Dev · 3 min read ·

Unix timestamps: seconds or milliseconds?

The 13-digit bug that ships to production every week, and a dead-simple heuristic to tell the two units apart.

JavaScript speaks milliseconds. Most backends speak seconds. Mix them up and your dates land in January 1970 — or tens of thousands of years in the future.

Count the digits

A present-day timestamp in seconds has 10 digits (1790000000 is 21 September 2026). The same moment in milliseconds has 13 digits; in microseconds 16 and in nanoseconds 19.

The heuristic

If the absolute value is above 10¹², it is milliseconds; otherwise treat it as seconds. That holds for any millisecond timestamp after September 2001 and any second timestamp before the year 33658.

const ms = Math.abs(n) > 1e12 ? n : n * 1000;

A timestamp has no time zone

A Unix timestamp counts seconds since 1 January 1970 at 00:00 UTC. The same number is the same instant everywhere in the world; only the way it is displayed changes. Bugs appear when local time is converted to a timestamp as if it were UTC, which shifts every date by your offset, often by an hour or two, and again around daylight saving changes. Store and send timestamps in UTC, and convert to local time only when you show them to a person.

Getting the current time in common languages

JavaScript  Date.now()                        milliseconds
JavaScript  Math.floor(Date.now() / 1000)     seconds
Python      time.time()                       seconds (with fraction)
Java        System.currentTimeMillis()        milliseconds
Go          time.Now().Unix()                 seconds
PostgreSQL  EXTRACT(EPOCH FROM now())         seconds
MySQL       UNIX_TIMESTAMP()                  seconds

Dates before 1970 and the year 2038

Negative timestamps are valid: −86400 is 31 December 1969. Some older systems and spreadsheets can’t handle them, so birth dates and historical data are a common source of bugs. At the other end, a signed 32-bit integer runs out at 2147483647, which is 03:14:07 UTC on 19 January 2038. Systems that still store timestamps in 32 bits will wrap around to 1901; 64-bit storage avoids the problem for billions of years.

Leap seconds

Unix time ignores leap seconds: every day is exactly 86,400 seconds. That keeps the arithmetic simple, and for almost every application the difference doesn’t matter. Only systems that need precise intervals across a leap second, such as some scientific or financial ones, have to care.

A quick debugging checklist

  • The date is in January 1970: a seconds value was read as milliseconds.
  • The year is in the tens of thousands: a milliseconds value was read as seconds.
  • Every date is off by the same number of hours: local time was treated as UTC, or the other way round.
  • Dates are off by one hour for part of the year: a daylight saving change was ignored.
  • Dates jump to 1901: a 32-bit overflow.

Pick the unit explicitly

The 4Dev timestamp converter doesn't guess: "Unix Timestamp" means seconds and "Unix Timestamp (ms)" means milliseconds, next to microsecond and nanosecond variants — 33 formats in total, including ISO 8601, RFC 2822, SQL DATETIME and Excel serial dates.

ISO 8601 when people read the date

Timestamps are ideal for storage and arithmetic, but hard for people to read. In logs, APIs and files that humans open, ISO 8601 such as 2026-09-21T14:30:00Z is unambiguous, sorts correctly as text and states the time zone explicitly. Converting between the two is exactly what the timestamp converter is for.

Open the timestamp converter

LinkedInXFacebook