[LEAPSECS] Time math libraries, UTC to TAI

Steve Summit scs+ls at eskimo.com
Sat Jan 7 07:18:03 EST 2017


zefram wrote:
> Steve Summit wrote:
>> I have implemented gmtime_ts_r() and mktime_ts() which operate
>> on struct timespec, and do the right thing with :60.
>
> Have you also extended struct tm to include tm_nsec?

Hoo, boy.  I would love to, but that's a project for another day,
and has nothing directly to do with leap seconds.  (But for the
time nurds on the list: It's interesting to ask, if struct tm
had tm_nsec, what should strftime do with it?  Even to ask the
question is to begin a slide down a slippery slope at the bottom
of which is: full printf-style width and precision handling for
strftime.  Which strftime has always needed anyway, so it's not
too bad.  But definitely a topic for another day.)

>> I'm not ready to think about the filesystem yet
>
> These days filesystem interfaces such as struct stat actually use
> a struct timespec for the inode timestamps.

*Interfaces*?  Really?  Struct stat64, maybe, but struct stat
can't, without breaking backwards compatibility.  (Unless it's
playing tricky games with unions or something.)

> It would be easy to use a CLOCK_UTC-style denormalised tv_nsec to
> represent leap seconds at the kernel interface.  Actually storing
> them in the filesystem is a different matter.  Most filesystems only
> store with second resolution anyway, so have no place and no need
> for the extra information.

Right.  Which is actually a good thing for our purposes, because
it means that file timestamps (in those filesystems, anyway) are
never accurate to better than a second, so we don't have to worry
whether they have Posix or smeared Posix or true-UTC timestamps.

> ext4 does store sub-second timestamps, down to nanosecond resolution,
> but it only allocates 30 bits for the nanoseconds.

I'd heard about the subsecond, but not about the bit-mongering.
Thanks.

> It uses the remaining 2 bits of that word to extend the
> representable range, postponing the Y2038 problem until 2242.

To extend the *range*?  What's wrong with just making tv_sec
(like time_t) 64 bits, which is happening everywhere else anyway?

> Still need to bum a bit somewhere else to represent leap seconds.

Well, I've concluded I really don't want to put leap seconds
in the filesystem anyway, for a different set of reasons.
On leap-second days, clock_gettime(CLOCK_UTC) and
clock_gettime(CLOCK_REALTIME) necessarily return slightly
different times.  The legacy calls gettimeofday() and time()
return whatever CLOCK_REALTIME returns.  And file timestamps
have to be touched with whatever CLOCK_REALTIME returns, too,
because Posix says that stat() yields time_t timestamps, and
legacy code is allowed to fetch the time and touch a file and
fetch the file's mtime and expect the two timestamps to be nearly
identical, not to differ by up to a second if smearing is in
progress.  If you put leap seconds in the filesystem, you have to
start smearing or unsmearing the timestamps on every stat() call,
plus you have to have some flag, or different call, by which the
caller can request whether he wants leapsecond-aware timestamps
back or not.  Another fine mess, and this one I have no interest
in tackling.


More information about the LEAPSECS mailing list