[tz] An outline of a possible solution for sensible leap-second support.

random832 at fastmail.us random832 at fastmail.us
Sun Feb 15 14:12:58 UTC 2015

Right now, very few people use the leap second support in tzcode. This
may represent a lack of demand, or it may be due to the fact that you
cannot have both leap second support and POSIX compliance at the same
time. Even when people do use it, it's often done in an incomplete and
incorrect way (e.g. by specifying the "right" folder directly in the TZ
variable). If the tz project intends to provide leap second support, I
would argue that it should be in a form that people can actually use.

Also, general question: is there any standard on how leap seconds are to
be handled in timezones that have an offset that is not a multiple of
one whole minute? What does tzcode do now?


Abandon entirely the time2posix/posix2time functions, the "right"
directory, and the notion of a time_t representation where e.g.
2000-01-01T00:00:00Z is represented by a value of 946684822 rather than
946684800. Very few people use them, and many of those who do use them
do so incorrectly even disregarding the issue of programs they may run
that do not call the conversion functions when they should. Remove
support for generating tzdata files with leap second data, and report an
error if one is loaded. 

Create a non-ambiguous representation for leap-aware timestamps. My
suggestion is a pair of {time_t time; int leap;}, with time being (for
leap seconds) the POSIX timestamp for the preceding normal second, and
leap=1 for s=60, leap=2 for s=61, etc.

Define a function interface which leap-aware systems may use to return
the correct time, with leap seconds and without any skew to attempt to
compensate for them. Tzcode to contain a dummy version that returns
{time, 0}. The value of the existing time() function around leap seconds
(e.g. whether it reports 23:59:59 twice, 00:00:00 twice, or implements
some form of skew over the course of the minute/hour/day) is
implementation-defined. (Arguably this new interface should also return
the best known correct time immediately rather than implementing skew in
the case of NTP adjustments as well, since unlike time() it is not
expected to be used by legacy programs as a pseudo-monotonic counter)

Define a file format and location (e.g. zoneinfo/leapdb) to store a
single copy of leap second information for use by the following

Define leap-aware interval-measurement (difftime) and interval-addition
(+ and - operator) functions. For example, since there was a leap second
in June 2012, difftime_l({1341100802, 0}, {1341100798, 0})
[2012-07-01T00:00:02Z minus 2012-06-30T23:59:58Z] is 5 rather than the
conventional 4. This is in contrast to the current implementation which
represents these times with different values that differ by 5, and
implements difftime by simple subtraction.

Define leap-aware versions of mktime_r, localtime_r, mktime_rz,
localtime_rz, gmtime_r, timegm_r, which use the new representation where
the normal ones use time_t.

Expanded scope (not part of tzcode/tzdata itself) - provide
recommendations of how to represent leap second times in filesystem
structures, archive structures, struct stat, struct timespec, and to
maintain backwards compatibility with existing ABIs which do not provide
this information (extending the range of an existing sub-second field is
worth considering in some cases, though 32-bit signed nanoseconds only
have room for one additional second in this way.)

More information about the tz mailing list