Same number, four meanings: unit conventions by platform
The most common timestamp bug is a unit mismatch, because ecosystems disagree on the default:
| Environment | Unit | Example for the same instant |
|---|---|---|
Unix / C / PHP / Python time.time() | seconds | 1781250000 |
JavaScript Date.now() / Java | milliseconds | 1781250000000 |
| Some APIs (Stripe events) | seconds | 1781250000 |
Go UnixNano(), databases | micro/nanoseconds | 1781250000000000000 |
A quick sanity check: 10 digits ≈ seconds (current era), 13 ≈ milliseconds, 16 ≈ microseconds, 19 ≈ nanoseconds. If a date renders as 1970 plus a few weeks, you parsed milliseconds as seconds; if it lands tens of thousands of years out, the reverse.
Timestamps are UTC — display is local
A Unix timestamp has no timezone: it counts seconds since 1970-01-01T00:00:00 UTC, everywhere on Earth. Timezone only enters when formatting for humans. This is why storing timestamps (or UTC datetimes) and converting at the display layer is the architecture that survives daylight-saving transitions, server migrations, and users in multiple regions. Bugs blamed on “timezone issues” are usually a local time stored without its offset — unrecoverable ambiguity twice a year when DST clocks repeat an hour.
Leap seconds and why your math still works
UTC has had leap seconds inserted to track Earth’s rotation, but Unix time pretends they don’t exist — every day is exactly 86,400 seconds, and systems typically smear or step the clock when a leap second occurs. The practical consequence: subtracting two Unix timestamps gives elapsed civil time, which is what almost every application wants. Only scientific and astronomical software needs true elapsed seconds (TAI), and it doesn’t use Unix time for that.
Debugging checklist for date bugs
- Print the raw value and count digits — confirm the unit before anything else.
- Confirm the parser’s expected unit (
new Date(seconds * 1000)in JS). - Render in UTC first; introduce the user’s timezone only once UTC is correct.
- Test the DST boundaries for your display timezone (late March, late October in Europe).
- For future dates beyond 2038 on legacy systems, verify the storage type is 64-bit.