# TAI zone?

Guy Harris guy at alum.mit.edu
Fri Jul 1 10:35:08 UTC 2011

```On Jun 30, 2011, at 6:15 AM, Kevin Kenny wrote:

> I'm going to tak a contrarian view -- at least from the perspective
> of the group here -- and assert that the Posix committee got it nearly
> right. (Or at least that the damage was done before the standardisation
> effort got under way.)
>
> Posix time, unfortunately, has served a dual purpose. It is used for
> measuring intervals - but it is also civil time: "what time is it on
> the clock on the wall?"

Most clocks on the wall, even if they're in the UK and are not adjusted for Summer Time, probably don't ever, for example, say {12,23}:59:60, so presumably by "civil time" you don't mean "something that exactly mirrors UTC".  Whether they "drift" from UTC due to leap seconds, so that the minute and second counters don't match, or are adjusted manually to match UTC to handle both clock drift and leap seconds (but still don't match it during a leap second), and whether they're additionally off from UTC because they weren't set precisely in the first place is another matter.

> And it has been used - from the very earliest
> days - as a calculation device for the civil clock. I would venture
> the guess that virtually all programs that depend on "seconds from
> 1 January 1970" actually are doing things like computing days between
> two times:"

If you phrase that as "time intervals between two times", I might agree.  If you restrict it to "days", I wouldn't; many of them calculate seconds.

> (time1/86400 - time2/86400).

...a calculation that could report 0 days between two events happening on different days, if fewer than 86400 seconds elapse between them, and you're doing it as an integer division.

2011-06-29 22:00:00 (US Pacific time) is 1309410000; 2011-06-30 11:00:00 (US Pacific time) is 1309456800.  1309410000/86400 is 15155, as is 1309456800/86400.

If you meant (time1 - time2)/86400, that does show how many days worth of time elapsed between the two events, although that could also be 0 between two events on different days.

If you do it in floating point, replace 0 with "a value less than 1".

So what do you mean by "days between two times"?  If you want to know whether two events happen on different days, use localtime() or gmtime(), and compare the resulting struct tm's.

> And having an integer representation of civil time,

So what does civil time do during a positive leap second?  Tick the seconds counter from 59 to 60, to match UTC's seconds counter?  Tick the seconds counter from 59 to 00, so it's off from UTC's seconds counter, and then maybe get fixed up later?  Freeze during the leap second, and tick from 59 to 00, so that, except during the leap second, it matches UTC?

> that well-defined calendar algorithms can handle without auxiliary tables that need to
> be updated, is too great a convenience to pass up lightly.

Without the auxiliary tables, you can't handle some UTC labels (as you don't know when to, for example, produce a UTC label that has XX:XX:60), so the calendar algorithms aren't going to be able to deal with UTC labels.  Which particular type(s) of "not matching UTC all the time" civil time are you talking about here?

> So: Make the TAI clock separate from the UTC clock.

There *is* no "UTC clock" in POSIX.  You cannot use only the POSIX APIs to convert a time_t, as returned by the POSIX time(), to the corresponding UTC time label, where the time label has HH:MM:SS; gmtime() will not do that for you, because gmtime() thinks that every minute ("minute" in the sense of period of time in which the minute counter of a clock ticks over) has exactly 60 seconds, which, for UTC time's minute counter, is not true.

What you have is a clock that is specified in a way that it attempts to display "typical clock" time, i.e. time from a clock that doesn't have the occasional more-than-60-second or less-than-60-second minute, which I suspect most clocks-on-the-wall don't have (whether that was the intent of the specification or not).  If you sync it up with NTP, it will probably somewhat similarly to a "typical clock" that people manually adjust for leap seconds; if you don't, it'll act similarly to most people's clock radios, as they don't know a leap second from a hole in the ground.

A "UTC clock", in the sense of a clock that displays UTC, could be implemented with

1) a TAI clock with the epoch shifted to 1970-01-01;

2) the Olson code, and the Olson database *with* the leap second information;

by just using gmtime() and displaying the tm_hour/tm_min/tm_sec values, as it will properly show 23:59:60, for example.

```