Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

POSIX time will jump discontinuously backwards after the leap second, counting:

59.50 59.75 60.00 60.25 60.50 60.75 60.00

Or, if your clock implementation is not POSIX-compliant but follows Mills' paper instead:

59.50 59.75 60.00 59.25 59.50 59.75 60.00

It gets weird, though: since this information was only made available recently, your computer may not know the leap second exists. In that case, its upstream NTP servers will jump and the local ntpd will slew the clock smoothly over the discontinuity, IIRC.

OTOH, if your system is aware of the leap second and if you're using the system clock to calculate intervals (i.e. t2 - t1), expect possibly negative or zero intervals over this timeframe. If you're calculating rates over a roughly 1-second interval, divide-by-zero bugs are definitely possible.

On a related note, does anyone know what the Oracle and OpenJDK JVMs do with respect to System.currentTimeMillis? They claim it's number of seconds since the epoch, which would imply this timer will not encounter discontinuities. The only ways I can think of to achieve that are by reading the system clock state to look for the leap insert/del/doublecount flag, or read a copy of the leap second table.

[edit] You may be asking, "Why would anyone use a system of time in which two numbers could refer to the same instant, or one in which a given number could refer to no time at all? Why not use a time system in which you could subtract two times from each other to get the interval between them? Or hell, even a time system where time always increases, you know, so we could order events.

The closest thing we have to such a time scale is TAI (http://en.wikipedia.org/wiki/International_Atomic_Time), which is what most computer systems like to pretend their clocks are: "the number of seconds since an epoch".

UTC and POSIX time are adjusted, relative to TAI, to keep the number of seconds in a given day at a nice "easy" 86400, which is why we're in this mess. Given that it takes plenty of math to translate a number like 1339696998.435347 into a human-readable date, I think our computers should just be keeping TAI to begin with and make the whole process easier on ourselves; but so many systems assume UTC or POSIX time that we're stuck with it.



I think you're glossing over the fact that POSIX time was designed to correspond to UTC without needing additional information. Since leap seconds vary in response to solar and geological phenomena, converting from TAI to UTC requires an up-to-date lookup table, while the possibility of out-of-order times can be accounted for in code. I think that's the reasoning behind it moreso than "math is hard".


You're right; it was designed to make interoperating with UTC easier.

Converting from TAI to UTC requires a lookup table; but consider that this is already a problem: your local clocks almost always keep time in seconds, not UTC. In order to keep UTC/POSIX time, it needs regular updates from the network (NTP) or shipping around a lookup table. This probably made more sense before large-scale use of NTP, but nowadays I don't know anyone who syncs their clock to a UTC source.

UTC is in general fucked because two different systems, depending on the state of their lookup tables, may not agree on what time a given number represents. This is an especially big problem for embedded systems which can't receive regular updates; consider that a UTC device manufactured in the 70s may disagree by up to 30 seconds with a modern UTC clock.

The easiest resolution to the problem is likely to drop leap seconds from UTC altogether; at which point POSIX, TAI, and UTC can proceed in lockstep corrected by a fixed offset. [1] Then we can use fixed lookup tables to compute relationships for the period where we were using leap seconds.

[1] I think. Need to check SI/NIST on this.


I don't see that leap seconds are the problem here (?) -- it seems like the problem is that we're planning to roll clocks backward instead of having 23:59:60 happen as planned. In contrast, we don't just repeat February 28th once every four years; we call it the 29th. Why are leap seconds different than leap days?


Calendars are different than time. It's a little hard to think about; maybe this will help:

The earth is sort of an inertial reference frame with a single proper time. It isn't exactly, because it's orbiting, in varying gravity, and spinning, and has local gravitational changes, etc, but to a decent approximation you can write down an average time for the whole earth, which is the number of seconds since the epoch. That time is TAI.

Calendars and dates are things like "June", "Monday, "12:40:70.534 PM", etc. These are human-friendly names for times, and don't have to be precisely comparable. It's OK to have "12:00 AM" twice. It's not OK to have "143563534 seconds since Jan 1st 1970 00:00:00" twice.

Calendars are supposed to line up with things like seasons and days. Those don't last a fixed number of seconds; the earth is always changing. So we need to have a translation between earth-average-time like TAI, and human calendars/dates/times. There are a whole bunch of layers of translation between various time schemes; most of them derive from TAI and add some offset. UTC is basically TAI plus leap seconds, which keep UTC as "86400 times the number of days since the epoch, plus the number of seconds since midnight." POSIX time is derived from UTC. Local time is typically derived from UTC plus a timezone offset, which can also be modified by daylight savings time.

Those translations need to change and be updated over time, so we insert and remove leap seconds, leap days, etc. It doesn't change TAI, but it does change the mapping from TAI to human times.

Back when POSIX was being codified, we made the decision to base most computer clocks on UTC, which is a human time, subject to changes in that mapping. That introduces disagreement over what a given time means, discontinuities, reversals, etc. All of those make it difficult to do calculations around time correctly.


> UTC is basically TAI plus leap seconds

This part seems a little muddy. UTC isn't a number of seconds since an epoch, it's a number of hours since midnight, a number of minutes since the beginning of that hour, and a number of seconds since the beginning of that minute.

Accordingly, UTC can bend the rules by saying, for example, that just this once the second 23:59:60 exists before midnight. It refers to a different second from 00:00:00; only when converting into POSIX does that become ambiguous.

So UTC and TAI agree on the number of seconds since the epoch, it's just UTC doesn't encode that number in the current time. Going the other way, TAI doesn't encode the current solar time. You need a lookup table either way.


The core of this is not a problem of fixing some naming convention (like leap years), but to actually disturb the measuring of time for a sake of making idealistic views of solar system dynamics the canonical time source. If you measure c during this "correction", you are expected to believe that it is smaller (in fact arbitrarily) for this one replication of the experiment!


> UTC and POSIX time are adjusted, relative to TAI, to keep the number of seconds in a given day at a nice "easy" 86400

yes, technically POSIX time is defined not as a number of seconds since epoch, but as 86400 * (number of days since epoch) + (number of seconds since last midnight)


Java hedges its bets. System.currentTimeMillis refers you to the docs for java.util time which states

"Although the Date class is intended to reflect coordinated universal time (UTC), it may not do so exactly, depending on the host environment of the Java Virtual Machine."

and further down in notes on possible ranges of return values

"A second is represented by an integer from 0 to 61; the values 60 and 61 occur only for leap seconds and even then only in Java implementations that actually track leap seconds correctly. Because of the manner in which leap seconds are currently introduced, it is extremely unlikely that two leap seconds will occur in the same minute, but this specification follows the date and time conventions for ISO C."


Yeah, I was reading the same docs with confusion. My coworker cscotta dug down into the source. Oracle's JVM on Linux just calls gettimeofday(), which means System.currentTimeMillis will go all wonky during leap seconds. Ah, documentation. :D


[deleted]


Er, actually the posix times will be big numbers like

1339696578.75 1339696578.00

and so forth. I just called them 60 so you'd know which "second" was which.


NTP can adjust clock by minutes. User can adjust clock by minutes, days, months, or even years.

EDIT: Simple time torture script is added:

  for((I=0; I<100; I++)); do date --utc --set=@$(( `date --utc +%s`+1 )) ; date --utc --set=@$(( `date --utc +%s`-1 )) ; done




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: