Skip to content

Seconds or milliseconds? How to recognize and convert a Unix timestamp

What a Unix timestamp is, how to tell seconds from milliseconds by the number of digits, and how to convert it in JavaScript, Python and SQL without fuzzy dates.

By Felipe YamaokaPublished November 5, 20265 min read

A number that is really a date

APIs, databases, logs and tokens love to store time as a single number:

json
{ "createdAt": 1793880000, "updatedAt": 1793880000000 }

Both values mean the same instant: 5 November 2026 at 12:00 UTC. The first is in seconds, the second in milliseconds. Mixing them up is one of the most common date bugs there is, and it produces results that look absurd at first sight: an order created in January 1970, or a session that expires in the year 58,815.

This guide explains what a Unix timestamp is, how to tell the units apart at a glance and how to convert safely in the languages you use every day.

What a Unix timestamp is

A Unix timestamp counts the time elapsed since the Unix epoch: 1 January 1970 at 00:00:00 UTC. Zero is that exact moment, 86400 is one day later and negative numbers are dates before 1970, so -86400 is 31 December 1969.

Two properties make it popular:

  • It has no time zone. The number means the same instant in São Paulo, London and Tokyo. Time zones only appear when you turn it into a date for a person to read.
  • It is easy to compare and sort. Later is bigger. The difference between two timestamps is a duration.

The original Unix definition counts seconds. Many platforms, starting with JavaScript, count milliseconds instead. Some systems go further: Python's time.time_ns() returns nanoseconds and many databases store microseconds internally. In practice, seconds and milliseconds are the two you will meet in JSON.

One detail: Unix time ignores leap seconds. Every day is treated as exactly 86,400 seconds. For almost all application code, this is exactly what you want.

Telling seconds from milliseconds

For dates near today, the number of digits gives it away:

  • 10 digits, such as 1793880000: seconds.
  • 13 digits, such as 1793880000000: milliseconds.

The rule breaks for dates far from today, so tools use a threshold instead. The Unix Timestamp Converter on this site treats any absolute value from 100,000,000,000 (1e11) up as milliseconds and anything below as seconds. The cut is safe in both directions: 1e11 seconds would be the year 5138, and 1e11 milliseconds is March 1973, so no realistic date in seconds is that big and almost no date in milliseconds is that small.

If you are not sure, convert both ways and see which one makes sense:

  • 1793880000 read as seconds: 5 November 2026, 12:00 UTC.
  • 1793880000 read as milliseconds: 21 January 1970.
  • 1793880000000 read as milliseconds: 5 November 2026, 12:00 UTC.
  • 1793880000000 read as seconds: the year 58,815.

A date in January 1970 almost always means seconds read as milliseconds. A date tens of thousands of years away means the opposite.

Converting in JavaScript

JavaScript's Date works in milliseconds, so seconds must be multiplied by 1000:

js
const seconds = 1793880000;
const date = new Date(seconds * 1000);

date.toISOString(); // "2026-11-05T12:00:00.000Z"

To go the other way, divide and round down:

js
const nowMs = Date.now();               // milliseconds
const nowSeconds = Math.floor(nowMs / 1000);

Prefer Math.floor over Math.round here. Rounding can move a timestamp half a second into the future, which is enough to make a token look "issued in the future" to a strict server.

To show the date to a person, format it in their time zone with Intl:

js
new Intl.DateTimeFormat("en-US", {
  dateStyle: "long",
  timeStyle: "short",
  timeZone: "America/New_York",
}).format(new Date(1793880000 * 1000));
// "November 5, 2026 at 7:00 AM"

Converting in Python

Python's datetime works in seconds, with fractions for anything smaller. Always pass a time zone, otherwise you get a "naive" date in the local time of the machine running the code:

python
from datetime import datetime, timezone

datetime.fromtimestamp(1793880000, tz=timezone.utc)
# datetime.datetime(2026, 11, 5, 12, 0, tzinfo=datetime.timezone.utc)

datetime.fromtimestamp(1793880000000 / 1000, tz=timezone.utc)  # from milliseconds

And back:

python
int(datetime(2026, 11, 5, 12, 0, tzinfo=timezone.utc).timestamp())
# 1793880000

Converting in SQL

Each database has its own function, and most of them expect seconds:

sql
-- PostgreSQL
SELECT to_timestamp(1793880000);
SELECT extract(epoch FROM now())::bigint;

-- MySQL
SELECT FROM_UNIXTIME(1793880000);
SELECT UNIX_TIMESTAMP();

-- SQLite
SELECT datetime(1793880000, 'unixepoch');

If a column stores milliseconds, divide by 1000 before calling these functions. In MySQL, also remember that FROM_UNIXTIME returns the time in the session time zone, not in UTC.

The year 2038

Old systems store timestamps in seconds as a signed 32-bit integer. The largest value it can hold is 2,147,483,647, which is 19 January 2038 at 03:14:07 UTC. One second later the number overflows and wraps around to December 1901. Modern languages and databases use 64-bit numbers and are safe, but embedded devices, old file formats and INT columns in databases can still break. If you design a table today, store timestamps in a 64-bit column or use the database's own date type.

Common mistakes

  • Passing seconds to new Date() in JavaScript. The result lands in January 1970.
  • Using Date.now() where an API expects seconds, such as the exp claim of a JWT. The guide to reading a JWT shows how this makes tokens look broken.
  • Creating naive dates in Python. datetime.fromtimestamp(ts) without tz depends on the server's local time zone.
  • Storing local time as if it were a timestamp. A timestamp is always UTC. Convert to local time only when showing it.
  • Rounding up. Truncate milliseconds to seconds with floor, not round.
  • Using 32-bit columns for dates that may go past 2038.

Summary

A Unix timestamp is the number of seconds, or milliseconds, since 1 January 1970 UTC. Ten digits usually mean seconds and thirteen mean milliseconds; when in doubt, convert both ways and pick the one that gives a plausible date. Multiply or divide by 1000 at the boundary between systems, keep everything in UTC until you show it to a person, and store timestamps in 64-bit columns.

Keep reading