A Unix timestamp counts seconds since midnight UTC on 1 January 1970. It is a plain integer with no time zone, no calendar and no ambiguity, which is why it underlies almost every system that has to compare two moments. Stored in a signed 32-bit integer it overflows on 19 January 2038 — and stored in the wrong unit it breaks today, which is the more common problem by a wide margin.
Thirteen digits are milliseconds and ten are seconds. Getting that wrong puts a date in 1970 or in the year 56000, and both are immediately obvious once you know to look.
Why does the unit confusion happen so often?
Because two ecosystems chose differently. JavaScript works in milliseconds; most Unix tooling, databases and APIs work in seconds. Any system that touches both will eventually multiply or divide by a thousand in the wrong place.
| Digits | Unit | 1 January 2026 |
|---|---|---|
| 10 | Seconds | 1767225600 |
| 13 | Milliseconds | 1767225600000 |
| 16 | Microseconds | 1767225600000000 |
The magnitude test is reliable for anything in the current era: a ten-digit value is seconds, a thirteen-digit value is milliseconds. It stops working for dates far from now, which is exactly when you most want it to.
What is the 2038 problem?
A signed 32-bit integer holds up to 2,147,483,647, and that many seconds after the epoch is 03:14:07 UTC on 19 January 2038. One second later it wraps to the most negative value, which reads as December 1901.
It is the same shape as the year 2000 problem and it has been fixed in most places by moving to 64-bit time. The remaining exposure is in embedded systems, in file formats with 32-bit timestamp fields, and in code that casts a 64-bit time to a 32-bit integer somewhere in the middle.
A 64-bit signed timestamp runs out about 292 billion years from now, which is comfortably longer than the problem needs to be solved for.
Do negative timestamps work?
They are perfectly valid and represent dates before 1970 — epoch −86400 is 31 December 1969. A surprising amount of software mishandles them, either rejecting the value outright or treating it as unsigned and producing a date in 2106.
That is worth testing for deliberately in anything storing historical dates. A birth date in 1955 is a negative timestamp, and a system that cannot represent it will fail on a fifth of its users rather than on an edge case.
What is a Julian day for?
A continuous day count with no months or years in it at all. The Julian Day Number counts days from noon UTC on 1 January 4713 BC, so 1 January 2026 is JD 2461041.5 — and subtracting two Julian days gives an interval directly, with no calendar arithmetic.
The noon start is the detail that catches people. Julian days begin at noon UTC so that a single night of astronomical observation falls within one Julian day rather than straddling two, which is why the fractional part of a date at midnight is always .5.
It is still the standard in astronomy and in some scientific data formats, for the same reason Unix time is standard elsewhere: a single monotonic number is easier to reason about than a calendar.
What other epochs are in use?
Several, and they are why a timestamp from an unfamiliar system can land decades away. Windows FILETIME counts 100-nanosecond intervals from 1601. GPS time counts seconds from January 1980 and does not skip leap seconds, so it now runs 18 seconds ahead of UTC. Spreadsheet serial dates count days from either 1900 or 1904 depending on the application and its age.
A date that is out by a known constant is almost always an epoch mismatch rather than a bug in the arithmetic, and the size of the offset usually identifies which epoch was assumed.
Why store a timestamp rather than a date string?
Because a timestamp is a moment and a date string is a moment plus an interpretation. "2026-03-29 02:30" is a real string and, in most of Europe, not a real time — that hour did not exist that year.
Timestamps have no such gaps. They are unaffected by daylight saving, by time zone changes and by the calendar reforms buried in any date library, and they compare with a single integer comparison. The conversion to a human-readable local time happens at the edge, once, on display.
The daylight saving article covers what happens when that conversion is done in the wrong place.
Questions people ask
Does Unix time count leap seconds? No, and that is deliberate. It assumes every day is exactly 86,400 seconds, so a leap second is absorbed rather than counted — which makes the arithmetic clean and the count technically not a true elapsed-seconds figure.
What was epoch 1000000000? 9 September 2001, widely noted at the time as a round-number milestone. Epoch 2000000000 falls in May 2033.
Why 1970? It was a convenient recent round date when Unix was being built, chosen after an earlier epoch proved too close to overflow at the resolution then in use.
Should a database store epoch or a timestamp type? Either, consistently. What causes trouble is mixing them, or storing a local time without its offset — which is a moment you cannot reconstruct.
One integer, no time zone, and two units that look alike. The Unix timestamp converter and epoch converter detect the unit by magnitude, and the Julian date converter handles the astronomical count that works the same way from a much older zero.