
On 2005-02-11, Marcin 'Qrczak' Kowalczyk
Daan Leijen
writes: - gettimeofday() returns the number of seconds since epoch (a UTC date)
What kind of seconds does it return? Well, (A) sometimes these are just SI-seconds (which means we can derive TAI from that), but sometimes (B) it returns UTC-seconds -- ie. the absolute SI-second count, plus/minus any leap seconds that have occurred.
Is there anyone on this list who can give a solid overview of what "gettimeofday" returns, and if we can distinguish (A) from (B)?
POSIX says it returns an UTC date, converted to the number of seconds by a given formula. The formula assumes that each day has 86400 seconds.
POSIX says that it returns what I'll call "POSIX UTC", because of that brokenness. But POSIX is not the only standard, and people will be running on machines that are run differently.
With a strict reading of the definition, after a leap second one second is repeated (since 23:59:60 gives the same counter value as 0:00:00 of the next day) and converting the time to hh:mm:ss never yields 60 as the number of seconds.
NTP client is supposed to slow down the system clock at a leap second. If programs ask for the system time during a leap second, the clock progresses minimally, just enough to make time monotonic, and continues normally when it catches up with the UTC time. I don't know how well this is actually implemented.
If a Linux time zone is set to something beginning with "right", then the system clock is assumed to count SI seconds since the UTC epoch (i.e. since 1970-01-01 00:00:10 TAI, even though TAI has been established in 1972) and leap seconds are adjusted together with the time zone. That is, gmtime() returns TAI, and localtime() returns localtime which is relative to UTC. If a standard NTP client is used, I guess it will set the time wrong, too early by 22 seconds (today).
Correct, for now. Newer NTP standards distribute TAI as well as UTC, and some clients will start using that real soon now. I think ideally we would have two interfaces, one of which does its best guess at POSIX UTC and one which does its best guess at TAI, because a best guess at UTC converted to TAI (or vice-versa) has more paths for this inaccuracy to creep in.
I think the only way to distinguish these cases is to call gmtime() and localtime() on the current time, and check whether the difference is a nice round number of minutes which is reasonable for a time zone difference, or it ends with a strange number of seconds which suggests that it includes leap seconds.
Referenced above, okay, we "know" the clock is in TAI, but since our standard interface is UTC, converting it now requires that leapsecond table. If we're right at the edge of an update, we can be two seconds off!
This will work until the UTC-TAI offset reaches the smallest number which is a reasonable "fractional" part of a time zone offset.
15 minutes, likely. Practically forever. Even one minute buys us a really long time. I do think this is clever, though I'd really like for our guess at TAI or POSIX UTC to be exported. -- Aaron Denney -><-