Unix time / epoch
Seconds since 1970 UTC — simple, ubiquitous, and full of sharp edges.
Unix time is a count of seconds elapsed since the Unix epoch:
1970-01-01T00:00:00Z. It is always relative to UTC, carries no time-zone
information, and is represented as a single integer or floating-point number —
making it trivial to store, compare, and transmit.
One critical design choice: Unix time ignores leap seconds. A Unix day is defined as exactly 86,400 seconds. When a leap second is inserted by IERS, Unix clocks either pause for a second, smear the adjustment across a window (as most cloud providers do), or repeat a second — but the Unix time value never reflects the extra second. This means Unix time is not a true count of elapsed SI seconds since the epoch; for scientific or precision timing work, be aware of this gap (currently 27 seconds as of 2026).
Because it is a single dimensionless number, Unix time is also used with finer
granularity: milliseconds (JavaScript’s Date.now()), microseconds
(PostgreSQL’s extract(epoch)), and nanoseconds (Go’s time.UnixNano())
variants all exist in the wild. Confusing the unit — e.g. treating a millisecond
timestamp as seconds — is one of the most common Unix-time bugs.
Storage size and the Y2038 problem
A signed 32-bit integer can hold Unix timestamps only up to
2038-01-19T03:14:07Z. After that it overflows to a large negative number,
interpreting the time as a date in 1901. This is the Y2038 problem.
Any system still using 32-bit time_t for timestamps — embedded firmware, legacy
databases, old 32-bit binaries — is affected.
Pitfall: Storing a millisecond-epoch timestamp in a field typed or sized for a second-epoch value silently truncates or misinterprets the time by a factor of 1,000 — putting an event in the year 49,000+ or, in the other direction, producing a date in early 1970.
Go deeper: 64-bit, smeared leap seconds, and negative values
A signed 64-bit integer in seconds can represent times roughly ±292 billion
years from the epoch, so Y2038 is not a concern for any system using 64-bit
storage. Most modern languages and operating systems have migrated time_t to
64 bits on 64-bit platforms, but cross-platform serialization formats (e.g.
certain binary protocols, old database schemas) may still impose 32-bit
constraints.
Negative Unix timestamps are valid and represent instants before 1970-01-01T00:00:00Z. Not all date libraries handle them correctly — worth testing if your application deals with historical dates.
Leap-second smearing: Google, AWS, and others distribute leap seconds by slightly slowing or speeding the clock over a window (e.g. 24 hours), keeping Unix time monotonically advancing and avoiding the “repeated second” problem for most applications. Because a full second is spread across the window, the smeared clock can deviate from true UTC by up to ~0.5 second at the window’s midpoint — fine for most applications, but significant for anything that must agree closely with TAI or precise UTC (e.g. cross-system time comparison).
For more on sub-second precision and the implications of different epoch units, see Precision and resolution. For the relationship between leap seconds and calendar systems, see Calendars.