unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
From: Zefram <zefram@fysh.org>
To: 26632@debbugs.gnu.org
Subject: bug#26632: TAI<->UTC conversion botches 1961 to 1971
Date: Mon, 24 Apr 2017 02:02:18 +0100	[thread overview]
Message-ID: <20170424010218.GL6765@fysh.org> (raw)

The SRFI-19 library gets TAI<->UTC conversions badly wrong in the years
1961 to 1971 (inclusive).

This has to be examined somewhat indirectly, because SRFI-19 doesn't offer
any way to display a TAI time in its conventional form as a date-like
structure, nor to input a TAI time from such a structure.  SRFI-19's
date structure, as implemented, is always interpreted according to UTC.
The only operations supported on TAI time structures are conversions to
and from the various forms of UTC, conversions to and from the less-useful
`monotonic' time, and arithmetic operations.  Thus the erroneous TAI<->UTC
conversions only come out through arithmetic operations in TAI space.
One must also be careful to avoid unrelated bugs such as bug#21911.

First I'll consider an ordinary day in 1967:

scheme@(guile-user)> (use-modules (srfi srfi-19))
scheme@(guile-user)> (time-difference
... (time-utc->time-tai (date->time-utc (make-date 0 0 0 0 15 3 1967 0)))
... (time-utc->time-tai (date->time-utc (make-date 0 0 0 0 14 3 1967 0))))
$1 = #<time type: time-duration nanosecond: 0 second: 86400>

This takes the start and end of 1967-03-14, as judged by UTC, converts
both of these times to TAI, and asks for the duration of that TAI
interval.  It's asking how many TAI seconds long that UTC day was.
As described in <http://maia.usno.navy.mil/ser7/tai-utc.dat>, there
was no UTC leap on that day, but throughout 1967 UTC had a frequency
offset from TAI such that each UTC second lasted exactly 1.00000003 TAI
seconds.  The correct answer to the above question is therefore exactly
86400.002592 s.  The answer shown above, of 86400.000000 s, is incorrect.

If time-tai->time-utc is applied to the times in the above example,
it accurately inverts what time-utc->time-tai did.  It is good that the
conversions are mutually consistent, but in this case it means they are
both wrong.

Second, I'll consider a less ordinary day:

scheme@(guile-user)> (time-difference
... (time-utc->time-tai (date->time-utc (make-date 0 0 0 12 1 2 1968 0)))
... (time-utc->time-tai (date->time-utc (make-date 0 0 0 12 31 1 1968 0))))
$2 = #<time type: time-duration nanosecond: 0 second: 86400>

This time the period considered is from noon 1968-01-31 to noon
1968-02-01.  The same frequency offset described above applies throughout
this period.  The additional complication here is that at the end of
1968-01-31 there was a leap of -0.1 (TAI) seconds.  The true duration of
this day is therefore exactly 86399.902592 s.  The answer shown above,
of 86400.000000 s, is incorrect in two ways, accounting for neither the
frequency offset nor the leap.

Once again, time-tai->time-utc accurately inverts the incorrect
time-utc->time-tai.  The failure to handle UTC's leaps in this era is
not specific to the relatively unusual negative leaps: it's equally
clueless about the positive leaps.

The full extent of the conversion errors, integrated across the entire
"rubber seconds" era from 1961-01-01 to 1972-01-01, is a little over
8.5 seconds of TAI.

This bug influences bug#26164, regarding time arithmetic in UTC.  If one
were to ignore the rubber seconds era, an obvious way to correct UTC
time arithmetic would be to convert to TAI and the arithmetic there.
That handles UTC leaps correctly.  But with rubber seconds it would
still be wrong.  In the rubber seconds era the number of UTC seconds in
an interval differs from the number of TAI seconds.

-zefram





             reply	other threads:[~2017-04-24  1:02 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-24  1:02 Zefram [this message]
2018-10-24  5:57 ` bug#26632: TAI<->UTC conversion botches 1961 to 1971 Mark H Weaver
2018-10-24 18:11   ` John Cowan
2018-11-06  4:21   ` Zefram

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170424010218.GL6765@fysh.org \
    --to=zefram@fysh.org \
    --cc=26632@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).