I've read a lot about UNIX Time lately, most of it incoherent, much of it contradictory. I am trying to reconcile conversions between UNIX Time (hereafter, for simplicity, UXT), TAI, and UTC, and to do this, I need to understand UXT properly. The trouble is, I can't seem to find anyone else who does.

The following represents my best-attempt explanation, reconstructed from innumerable sources by tedious research. It is also wrong somewhere. I am looking for a holistic analysis and point-by-point verification/refutation of the following. Essentially, fix the following so that it works.

  1. TAI is a monotonically increasing time standard. It ticks SI seconds, and ignores DST and leap seconds.

  2. UTC is the same as TAI, but corrected by an integer number of leap SI seconds (conversions to time strings reflect this as a 60th second) so as to be within 0.9 SI seconds of UT1, an astronomical time standard.

  3. UXT is a count of UNIX seconds since 1970-01-01 00:00:00 UTC. There are always exactly 86400 seconds per day. Nevertheless, UXT is related to UTC.

  4. How is this possible? Well, the UNIX second needs to be different from the SI second, and because leap seconds are not perfectly regular, UNIX seconds can't be a well-defined length of time.

  5. The conversion from UTC to UXT in §4.15 of the UNIX spec aliases different UTC times to the same UXT timestamp, effectively making UNIX seconds the same as SI seconds (except for UNIX leap seconds, which are two SI seconds).

    In practice, what actually happens varies. Most computers synchronize based on a remote server, and so they handle leap second updates implicitly during the synchronization.

  6. All of this means that, while each individual UXT timestamp can be converted to/from UTC easily (use gmtime or §4.15, respectively), you can't really do arithmetic to find out anything using them. In particular, difftime returns UNIX seconds, and so you can't do anything with it, including adding it to a different timestamp, unless you know where all the relevant leap seconds are.

I think I understand so far.

  1. But now we look at actual code, which doesn't do any of this at all. I can understand people measuring durations using difftime and just sortof hoping that it's good enough (or not knowing there's a problem), but timekeeping libraries are wrong too.

    As one example, libtai provides a conversion (tai_now.c:7) to TAI from UXT as: TAI := 4,611,686,018,427,387,914 + UXT. Since TAI ticks SI seconds while UXT ticks UNIX seconds, you just can't do this. Yet, since libtai explicitly handles leapseconds, it doesn't seem reasonable that this is a careless mistake.

    It's not specific to libtai. You see this sort of thing all over.

So: points 1-6 are in disagreement with point 7. That is, tons of existing code is in contradiction with the time standards it supposedly represents. What went wrong?


A problem is that most documents do not use a vocabulary which can distinguish time scales without sentences of ambiguity. I suggest http://www.ucolick.org/~sla/leapsecs/picktwo.html as introduction to the problem that in historic use there are two unrelated kinds of seconds -- one which is a subdivision of a calendar day for residents of Earth, and one which is a constant duration as measured in a particular reference frame. Any time library which spans dates before and after 1970 is trying to make use of both kinds of second, and that ends up providing answers which are akin to a function that claims to provide arcsin(-2) -- which is to say that there are complexities involved that need careful explanations and definitions of exactly what is being considered important.


You are right, and this mess is terrible. My conclusion:

UXT and UTC are the same, except during the leap second. There, UTC counts to 60 and UTX just 'hangs' for a second.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.