The 27-Second Gap
Ask any developer what POSIX time is, and you’ll get the same answer: the number of seconds since the Unix epoch, 1970-01-01T00:00:00Z. It’s a neat mental model, and it’s also wrong. Consider a concrete moment: 2024-12-25 at 18:51:26 UTC. The POSIX timestamp for that instant is 1735152686. But the actual number of seconds that have elapsed since the epoch is 1735152713. The POSIX clock reads 27 seconds less than reality.
That discrepancy is not a rounding error. It comes straight from the definition in IEEE 1003.1, which derives POSIX time from an idealized view of Coordinated Universal Time. The standard’s formula for converting a UTC calendar breakdown into “seconds since the Epoch” assumes every day is exactly 86,400 seconds long:
tm_sec + tm_min * 60 + tm_hour * 3600 + tm_yday * 86400 + (tm_year-70) * 31536000 + ((tm_year - 69) / 4) * 86400
Actual UTC days are not all 86,400 seconds. Because Earth’s rotation drifts, astronomers occasionally insert a leap second to keep civil time aligned with solar time. Every such insertion adds one true second to the day, but the POSIX formula never sees it. So every leap second since 1970 becomes a permanent, silent debt in the clock’s reading—currently 27 seconds owed.
The Standard Admits It
What’s striking is that the POSIX authors knew exactly what they were doing. Appendix B of IEEE 1003 contains a candid discussion of the trade-off. At publication time, 14 leap seconds had already been added since 1970. The standard’s response was to state that “these 14 seconds are ignored to provide an easy and compatible method of computing time differences.”
The appendix goes further, acknowledging the conceptual impossibility:
Most systems’ notion of “time” is that of a continuously-increasing value, so this value should increase even during leap seconds. However, not only do most systems not keep track of leap seconds, but most systems are probably not synchronized to any standard time reference. Therefore, it is inappropriate to require that a time represented as seconds since the Epoch precisely represent the number of seconds between the referenced time and the Epoch.
Instead, the standard punts the problem to vendors and system administrators, requiring only that they make the clock read “as closely as necessary” for whatever application runs on the machine. That is arguably an impossible mandate: the specification structurally guarantees the value will drift from real elapsed seconds, yet demands that vendors reconcile the two. They can’t. At least 27 seconds of slippage is baked into the definition itself.
The appendix also worries about distributed applications that rely on timestamps for event synchronization. But in practice, the opposite failure mode dominates: systems are always somewhat out of sync, so small clock drifts rarely surface. Leap seconds are rare, discrete events, so the mismatch only compounds linearly until one of those occasional seconds causes a widely publicized outage—as it has done at Qantas, Cloudflare, and others.
Choosing a Clock
There are practical alternatives for anyone whose code actually needs accurate elapsed time:
- Within a single machine: Use
CLOCK_MONOTONICor, preferably,CLOCK_BOOTTIME. These clocks count actual seconds without regard to wall-clock adjustments. - For astronomically precise absolute time: Use TAI or GPS time, which don’t insert leap seconds and therefore track true SI seconds continuously.
- For interoperability with POSIX systems: Smear leap seconds across a long interval instead of handling them as single discontinuities. Libraries such as qntm’s
t-a-iprovide POSIX-to-TAI and back conversions when absolute precision matters.
The industry is inching toward eliminating leap seconds, with a target of dropping them entirely by 2035. That will demand conversion tables baked into everything that currently assumes the 86,400-second day. But it should also finally allow a simple, truthful answer to “how many seconds between these two times?”—at least for any time after the change takes effect.



