English

Unix timestamp: seconds or milliseconds

Why timestamps can have 10 or 13 digits, how to tell seconds from milliseconds, and where date bugs usually start.

The UI suddenly shows 1970. Or the date jumps into a far future year. Before debugging timezones, check the unit: seconds vs milliseconds. The code can be "correct" on both sides; the contract between systems is what broke.

Use the timestamp converter to compare both interpretations. It does not prove the bug by itself, but it checks the main hypothesis quickly.

ValueIf read as secondsIf read as milliseconds
1719326400date around 2024January 1970
1719326400000far future datedate around 2024

A quick length check

For dates around the current years, a timestamp in seconds usually has 10 digits. It is the Unix-style count of seconds since January 1, 1970 UTC. You see it in logs, backend APIs and commands like date +%s.

Milliseconds usually show up as 13 digits. JavaScript is the common source: Date.now() returns milliseconds. Client analytics and browser events often use the same unit.

This is not a law of nature. Old dates are shorter, future dates get longer. But if a "current" timestamp has 13 digits, it is almost certainly milliseconds.

What the wrong unit looks like

If seconds go into code that expects milliseconds, the date falls back toward January 1970. You pass 1719326400, new Date() reads it as milliseconds, and you get the first weeks after the Unix epoch instead of summer 2024.

The opposite error is louder. Milliseconds are read as seconds, and the date jumps into a far future year. When a UI suddenly shows an impossible date, check the timestamp unit before looking for a timezone bug.

Where the bug usually starts

A common boundary is frontend to backend. The server returns seconds, the frontend passes the number to new Date(value), and JavaScript expects milliseconds. Or the browser sends Date.now(), while the backend stores it in a field everyone assumed was seconds.

Analytics data has the same problem. One source writes seconds, another writes milliseconds, a third one sends ISO strings. Normalize before sorting or comparing events, not after the chart looks wrong.

The cheapest prevention is naming the unit: created_at_ms, created_at_seconds, expiresAtMs. createdAt looks clean, but it makes people guess six months later.

If the API is already public, lock the unit in documentation and tests. Changing seconds to milliseconds without a contract version is how some clients end up in 1970.

Questions

Why does one timestamp have 10 digits and another have 13?

A 10-digit value usually means seconds since January 1, 1970 UTC. A 13-digit value usually means milliseconds. Still, check the API or database context.

Why does JavaScript show 1970?

A common cause is passing seconds into `new Date()`, while JavaScript expects milliseconds.

Does a Unix timestamp include a timezone?

No. It represents a moment relative to UTC. Timezone appears when that moment is displayed as a local date.

Related tools