Unix Timestamps Explained: Epoch Time, Time Zones, and the 2038 Problem
What Unix time actually counts, why seconds vs. milliseconds causes so many bugs, how time zones fit in, and what happens in January 2038.
Open any log file, API response, or JWT and you'll find numbers like 1784246400. That's Unix time — the quiet convention underpinning almost all timekeeping in software. Here's how it works, and the handful of pitfalls that cause real bugs.
What Unix time is
Unix time is simply the number of seconds elapsed since January 1, 1970, 00:00:00 UTC — a moment called the epoch. No months, no time zones, no daylight saving: one ever-increasing integer.
That simplicity is the point. Comparing two timestamps is integer comparison. Subtracting them gives a duration. Storing them takes a few bytes and sorts correctly. Every language and database understands them. Convert any timestamp to a human date (and back) with our Timestamp Converter.
Seconds vs. milliseconds: the #1 bug
Different systems disagree on the unit:
- Seconds (10 digits today): most APIs, databases, JWTs, and Unix tools
- Milliseconds (13 digits today): JavaScript's
Date.now(), Java, many logging systems
Mix them up and dates land in January 1970 (treated milliseconds as seconds) or the year 56,000+ (treated seconds as milliseconds). If you see either, you know instantly what happened: multiply or divide by 1,000. A quick digit-count is the fastest sanity check — 10 digits means seconds, 13 means milliseconds.
Where time zones fit (they don't)
A Unix timestamp has no time zone — it identifies an absolute instant, the same worldwide. Time zones only enter when you format the instant for humans. 1784246400 is 08:00 in London and 03:00 in New York, but it's one moment.
This gives the golden rule of handling time in software: store and compute in UTC/Unix time; convert to local time only at display. Almost every "the meeting shows the wrong hour" bug comes from breaking that rule — doing arithmetic on local wall-clock times, which jump around thanks to daylight saving. When you do need wall-clock conversions across cities, our Time Zone Converter handles the DST rules for you.
Related trap: a date like "2026-07-14" with no time zone attached is ambiguous. JavaScript, for instance, parses new Date("2026-07-14") as UTC midnight, which displays as July 13 in the Americas. Off-by-one-day bugs are almost always this.
Milestones worth recognizing
0— the epoch, Jan 1 19701000000000— Sep 2001 (timestamps have been 10 digits ever since)1500000000— Jul 20172000000000— May 20332147483647— Jan 19, 2038, and thereby hangs a tale:
The Year 2038 problem
Old systems store Unix time in a signed 32-bit integer, which maxes out at 2,147,483,647. One second later, the value overflows to a large negative number — which decodes to December 1901. Y2K, but for Unix.
Modern 64-bit systems are safe for ~292 billion years, and mainstream OSes and databases migrated years ago. The remaining risk lives in embedded devices, old file formats, and legacy binary protocols with hardcoded 32-bit fields — systems that tend to run for decades without updates. If you work anywhere near firmware or industrial systems, 2038 is closer than it sounds: mortgages and certificates with 12+ year horizons are already crossing it today.
Practical habits
- Store UTC / Unix time, format locally at the edge
- Name your units — a field called
created_at_msprevents the seconds/ms bug by design - Count digits when debugging: 10 = seconds, 13 = milliseconds
- Use the Timestamp Converter to sanity-check any value you're unsure about — it accepts both units and shows the date in UTC and your local zone