From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Mark H Weaver Newsgroups: gmane.lisp.guile.bugs Subject: bug#22034: time-utc->date shows bogus zone-dependent leap second Date: Sun, 28 Oct 2018 16:39:19 -0400 Message-ID: <871s89ajql.fsf@netris.org> References: <20151127195146.GB28472@fysh.org> <87a7n847o5.fsf@netris.org> <87va5u8q7o.fsf@netris.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1540759148 30238 195.159.176.226 (28 Oct 2018 20:39:08 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sun, 28 Oct 2018 20:39:08 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) Cc: zefram@fysh.org, 22034@debbugs.gnu.org, 22034-done@debbugs.gnu.org To: John Cowan Original-X-From: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Sun Oct 28 21:39:03 2018 Return-path: Envelope-to: guile-bugs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gGrpu-0007il-KY for guile-bugs@m.gmane.org; Sun, 28 Oct 2018 21:39:02 +0100 Original-Received: from localhost ([::1]:41885 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gGrs0-0001nF-FA for guile-bugs@m.gmane.org; Sun, 28 Oct 2018 16:41:12 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:53045) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gGrrt-0001gV-Cs for bug-guile@gnu.org; Sun, 28 Oct 2018 16:41:06 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gGrrq-00058P-Em for bug-guile@gnu.org; Sun, 28 Oct 2018 16:41:05 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:45121) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gGrrq-00058E-9o for bug-guile@gnu.org; Sun, 28 Oct 2018 16:41:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1gGrrq-0006ST-80 for bug-guile@gnu.org; Sun, 28 Oct 2018 16:41:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Mark H Weaver Original-Sender: "Debbugs-submit" Resent-CC: bug-guile@gnu.org Resent-Date: Sun, 28 Oct 2018 20:41:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 22034 X-GNU-PR-Package: guile X-GNU-PR-Keywords: Original-Received: via spool by 22034-done@debbugs.gnu.org id=D22034.154075922524762 (code D ref 22034); Sun, 28 Oct 2018 20:41:02 +0000 Original-Received: (at 22034-done) by debbugs.gnu.org; 28 Oct 2018 20:40:25 +0000 Original-Received: from localhost ([127.0.0.1]:49376 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gGrrE-0006RH-Q3 for submit@debbugs.gnu.org; Sun, 28 Oct 2018 16:40:25 -0400 Original-Received: from world.peace.net ([64.112.178.59]:42256) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gGrrC-0006R0-6y; Sun, 28 Oct 2018 16:40:22 -0400 Original-Received: from mhw by world.peace.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1gGrr5-0002ed-8d; Sun, 28 Oct 2018 16:40:16 -0400 In-Reply-To: (John Cowan's message of "Thu, 25 Oct 2018 18:21:35 -0400") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-guile@gnu.org List-Id: "Bug reports for GUILE, GNU's Ubiquitous Extension Language" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Original-Sender: "bug-guile" Xref: news.gmane.org gmane.lisp.guile.bugs:9247 Archived-At: Hi John, John Cowan writes: > On Mon, Oct 22, 2018 at 2:12 AM Mark H Weaver wrote: > > Universal Time (UT) is not a measure of physical time, but rather is a > measure of the rotation angle of the Earth with respect to distant > quasars. A UT second is identified with a fixed amount of rotation of > the Earth, which equals 1/86400 of a mean solar day. That's why every > day has 86400 UT seconds. > > Quite right. Buit the whole point of UTC is that its seconds are not angles, > but SI = TAI seconds. I believe you're making a subtle error in your identification of UTC seconds with TAI seconds. It might be helpful to consider an analogy to spatial measurement. A TAI clock aims to measure the current TAI time, i.e. to measure the time interval between the epoch and _you_ in units of TAI seconds, i.e. SI seconds as observed on the geoid. In spatial terms, a TAI clock is analogous to a very precise measuring tape which aims to measure the distance between you and an fixed conventional point in space, analogous to the TAI epoch. In this analogy, a UTC clock is analogous to an equally precise measuring tape that is _almost_ identical to the TAI analogue measuring tape, but subtly different. If we place the two measuring tapes side by side and ignore pre-1972, we see that the markings are in _precisely_ the same positions along the entire length of the tape, without the slightest deviation, even over long distances. The difference between the two measuring tapes is that they assign different numbers to the markings, and moreover that the UTC analogue has a small handful of places where two adjacent markings have the same number assigned, and all subsequent numbers are shifted by 1. Such a place might look something like this: 126230388 |-- 126230389 |-- 126230390 |------------ 126230391 |-- 126230392 |-- 126230393 |-- 126230394 |-- 126230395 |------ 126230396 |-- 126230397 |-- 126230398 |-- 126230399 |-- 126230400 |------------ 126230400 |------------ 126230401 |-- 126230402 |-- 126230403 |-- 126230404 |-- 126230405 |------ 126230406 |-- 126230407 |-- 126230408 |-- 126230409 |-- 126230410 |------------ 126230411 |-- 126230412 |-- By asserting that UTC seconds are the same as TAI seconds, you're emphasizing that the distance between any two adjacent markings are precisely the same on the two measuring tapes. What I'm trying to say is that when you use these two measuring tapes to measure the interval between two arbitrary points, they will give different answers, unless the entire interval happens to be between two adjacent leap seconds (and post-1971). I think it's highly questionable to claim that these two measuring tapes measure the same units, given that when they are actually used to measure intervals, they give different answers, and moreover that the discrepancy grows without bound as larger intervals are measured, even in an idealized thought experiment. > There are a variable number of these in a day, and a UTC clock will > indeed report 23:59:60 at the end of a day with a leap second in it That's something that can be done when you convert TIME-TAI into a UTC date, and indeed 'time-tai->date' from SRFI-19 will do this: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> ,pp (map (lambda (n) (let* ((tai (make-time time-tai 0 n))) (list (time-second tai) (date->string (time-tai->date tai 0) "~4")))) (iota 5 126230410)) $1 = ((126230410 "1973-12-31T23:59:58Z") (126230411 "1973-12-31T23:59:59Z") (126230412 "1973-12-31T23:59:60Z") (126230413 "1974-01-01T00:00:00Z") (126230414 "1974-01-01T00:00:01Z")) --8<---------------cut here---------------end--------------->8--- However, let's return to our disagreement which started this digression: > On Sat, Oct 20, 2018 at 5:43 PM Mark H Weaver wrote: > > If I understand correctly, 'time-utc->date' should never return a date > object with 60 in the seconds field, because those extra seconds have no > representation in time-utc. They only have representations in time-tai > and time-monotonic. > > As I understand it, this is incorrect. UTC days can contain either > 86400 or 86401 seconds (or in principle a different number), depending > on whether the day has a leap second. You seem to be asserting above that TIME-UTC _does_ have representations of the extra leap seconds. That is simply not true. It's true that *date objects* for UTC, broken down into separate fields, are able to represent the leap seconds by putting 60 in the seconds field. However, TIME-UTC, represented as a single number of seconds since the epoch, is _not_ able to represent them. Let's look at a small interval near a leap second, in TIME-TAI, TIME-UTC, and the corresponding date objects expressed in UTC: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> ,pp (map (lambda (n) (let* ((tai (make-time time-tai 0 n)) (utc (time-tai->time-utc tai))) (list (time-second tai) (time-second utc) (date->string (time-tai->date tai 0) "~4")))) (iota 5 126230410)) $2 = ((126230410 126230398 "1973-12-31T23:59:58Z") (126230411 126230399 "1973-12-31T23:59:59Z") (126230412 126230400 "1973-12-31T23:59:60Z") (126230413 126230400 "1974-01-01T00:00:00Z") (126230414 126230401 "1974-01-01T00:00:01Z")) --8<---------------cut here---------------end--------------->8--- As you can see, 1973-12-31T23:59:60Z and 1974-01-01T00:00:00Z have the same representation in TIME-UTC. This is an unavoidable consequence of the fact that TAI-UTC=12 shortly before midnight 1974-01-01 UTC, and TAI-UTC=13 shortly after. This is the basis for my claim that TIME-UTC is unable to represent leap seconds, and that 'time-utc->date' should never return 60 in the seconds field. In theory, we could have it return 60 in the seconds field when the input is 126230400 UTC seconds, but if we did that, then we'd be skipping 1974-01-01T00:00:00Z. So, what about my claim that every UTC day has 86400 UTC seconds, although UTC days can have between 86399 and 86401 TAI seconds? Let's look at a similar table as above, but for the previous day: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> ,pp (map (lambda (n) (let* ((tai (make-time time-tai 0 n)) (utc (time-tai->time-utc tai))) (list (time-second tai) (time-second utc) (date->string (time-tai->date tai 0) "~4")))) (iota 5 (- 126230410 86400))) $3 = ((126144010 126143998 "1973-12-30T23:59:58Z") (126144011 126143999 "1973-12-30T23:59:59Z") (126144012 126144000 "1973-12-31T00:00:00Z") (126144013 126144001 "1973-12-31T00:00:01Z") (126144014 126144002 "1973-12-31T00:00:02Z")) --8<---------------cut here---------------end--------------->8--- The difference between the TIME-TAI values for 1973-12-31T00:00:00Z and 1974-01-01T00:00:00Z is 126230413-126144012 = 86401, but the difference between the corresponding TIME-UTC values is 126230400-126144000 = 86400. Does that make sense? Regards, Mark