[LEAPSECS] [time-nuts] Leap Quirks
M. Warner Losh
imp at bsdimp.com
Sun Jan 4 21:15:36 EST 2009
[[ continuation of a discussion from time-nuts ]]
In message: <496157C4.2050300 at erols.com>
Chuck Harris <cfharris at erols.com> writes:
: Magnus Danielson wrote:
: > Chuck Harris skrev:
: >> One of us is confused about what time_t is... I think it is
: >> you.
: >
: > I know of three different ways to interpret it. They fit different purposes.
: >
: >> time_t is a 32 bit (depreciated), or 64 bit integer that contains
: >> the number of seconds since the epoch. It is not to be adjusted
: >> for leap seconds according to POSIX, and unix convention.
: >
: > This is one, no two, of the interpretations I know of.
:
: Good!
:
: >> Everything to do with UTC and leap seconds is a library function
: >> in most unixes that translates the leap second free time_t into
: >> the leap second adjusted broken-down-time UTC.
: >
: > Exactly where? Do please tell me what the unified way of getting UTC
: > time is. Oh, when there is a leap second it needs to give correct
: > counting as well.
:
: If the unix supports leap second, which usually requires ntp, gmtime()
: should report the UTC time correctly.
POSIX doesn't support leap seconds. At all. They do not exist in
POSIX's time_t.
: > Joe has in private conversations pointed out a POSIX interface which
: > could be used.
: >
: >> Again, are you telling me that time_t is getting adjusted for leap
: >> seconds? If so, when did this change?
: >
: > To the best of _my_ knowledge (which can be wrong) this is what is being
: > done in practice, which is outside of the POSIX standard, but has the
: > effect that 00:00:00 always midnight, which POSIX needs. This is a third
: > interpretation...
:
: Yes, but this is not UTC midnight, but unix time or POSIX time midnight.
: Unix time midnight, and POSIX time midnight drift from UTC midnight as the
: leap seconds get added or removed.
They are all the same thing. POSIX midnight, UTC midnight and Unix
midnight all necessarily translate to the same value on a POSIXly
correct system.
: Some of the libc functions that convert time_t to broken down time convert
: to UTC, and others convert to POSIX/Unix time... which is, I guess 24 seconds
: fast?
No. That's not POSIXly correct. There are some systems that
implement this, but they aren't POSIX compliant.
: Ntpd doesn't mess with time_t when it makes its leap second corrections,
: but rather messes with tables and counters used by gmtime(), etal.. The
: only time that ntpd messes with time_t is to slew it so that your system's
: time_t is the same as everyone elses... (The number of si seconds since
: the epoch without adjustments for leap seconds.)
Actually, you are right. ntpd doesn't mess with it, but the kernel
does. The kernel steps time backwards 1 second to accont for the leap
second. It has to, since the leap second has no unique value in a
time_t, in a POSIXly correct system. This is what is horribly broken
about POSIX: leap second exist, but are explicitly ignored in POSIX.
: > If somebody (say PHK) got out and slapped my face and say this is a
: > total misunderstanding, this is pretty good after all. If this practice
: > does exist, then we still have three interpretations and they are in
: > conflict with each other even after giving up on introducing leap
: > seconds. So we have two or three interpretation of the POSIX timescale,
: > one with pure SI seconds, one with rubber seconds up till
: > 1972-00-00T00:00:00Z and then SI seconds and a third which is like the
: > second but re-aligned on each leap second event so that midnights match.
: >
: > This is only an issue if the POSIX scale is under external control.
: >
: > And yes, do tell me how I get UTC on all platforms.
:
: On all platforms? Even my VCR? That's a tall order. On unix
: platforms, gmtime() will do the trick... assuming that leap seconds are
: supported.
Right. It can't do that in a POSIXly correct system, but system that
doesn't completely comply with POSIX can choose to implement things
this way.
The problem is that when a system is implemented this way, you
suddenly have a number of programs that report time wrong by 24
seconds because they make the POSIX assumption that time_t % 86400 is
necessarily midnight (or some other assumption that is equivalent).
There are many many programs that compute a time_t based on what I've
called 'naive math' (since it is based on the naive assumption that
leap seconds do not exist). It is not uncommon to see something akin
to:
// compute Dec 23, 1988 12:34:54
time_t t = (18 * 365 + 5) * 86400 + 12 * 3600 + 34 * 60 + 54;
(well, usually that's burried in the program's own implementation of
gmtime, but you get the idea). Also common is code that looks like:
time_t wakeup;
wakeup = time(NULL) + 86400; /* Same time tomorrow */
while (1) {
/* Do something */
while (time(NULL) < wakeup)
sleep (1);
wakeup += 86400; /* Same time tomorrow */
}
or variations on this theme where they can assume a time of day
computation and need no leap second tables. Such code is POSIXly
correct, but breaks with the 'right' timezones from Olson.
So time_t is effectively defined in POSIX to be:
d * 86400 + min(tod(x), 86399)
where d is the number of days since 01-01-1970, and tod is the second
since midnight within the day.
: > Regardless, this just shows how complex the issue is. There seems that
: > there is no "correct" interpretation that everyone can agree with as a
: > basis. If there is I'll be much happier and go away a bit wiser.
:
: The only interpretation that would make me happy is one where UTC no longer
: requires leap seconds... but that is a different subject.
Yea, there's much opinion on the wisdom of that, or the lack of wisdom
of that, to be had on this list...
Warner
More information about the LEAPSECS
mailing list