Subject: bug#21912: TAI<->UTC conversion botches the unknown

From: Zefram <[email-masked]>
Date: Fri, 13 Nov 2015 16:44:27 +0000

Probing the existence of leap seconds on particular days, via srfi-19's
TAI-to-UTC conversion.  The methodology here is to take noon UT on the
day of interest, convert to TAI, add 86400 seconds, then convert to UTC
and display.  The resulting time of day is 11:59:59 if there is a leap
second that day, and 12:00:00 if there is not.

scheme@(guile-user)> (use-modules (srfi srfi-19))
scheme@(guile-user)> (date->string (time-tai->date (add-duration (julian-day->time-tai 2455743) (make-time time-duration 0 86400)) 0) "~4")
$1 = "2011-07-01T12:00:00Z"
scheme@(guile-user)> (date->string (time-tai->date (add-duration (julian-day->time-tai 2456109) (make-time time-duration 0 86400)) 0) "~4")
$2 = "2012-07-01T11:59:59Z"
scheme@(guile-user)> (date->string (time-tai->date (add-duration (julian-day->time-tai 2457204) (make-time time-duration 0 86400)) 0) "~4")
$3 = "2015-07-01T12:00:00Z"
scheme@(guile-user)> (date->string (time-tai->date (add-duration (julian-day->time-tai 2457935) (make-time time-duration 0 86400)) 0) "~4")
$4 = "2017-07-01T12:00:00Z"

For 2011-06-30 it is correct that there was not a leap second, and for
2012-06-30 it is correct that there was.  But for 2015-06-30 it says
there was not a leap second, when in fact there was.  For 2017-06-30
it says there will not be a leap second, when in fact it is not yet
determined whether there will be.

Really both of these errors come from the same cause.  At the time
this Guile 2.0.11 was released, the leap status of 2015-06-30 had not
yet been determined.  Both 2015 and 2017 fall within the future period
beyond the scope of this Guile's static leap second knowledge.

The bug is not that Guile doesn't know that there was a leap second
in 2015.  As the 2017 case illustrates, it's impossible for it to
know all the leap second scheduling about which it can be asked.
The bug is that Guile *thinks* it knows about all future leap seconds.
It specifically thinks that there will be no leaps at all beyond the
historically-scheduled ones that it knows about.

Guile ought to be aware of how far its leap table extends, and signal
an error when asked to perform a TAI<->UTC conversion that falls outside
its scope.

-zefram