[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ntp-hackers
Subject:    Re: [ntp:hackers] Thailand and the religions of the East
From:       Terje Mathisen <terje.mathisen () hda ! hydro ! com>
Date:       2004-03-11 8:22:17
Message-ID: 405021B9.1040203 () hda ! hydro ! com
[Download RAW message or body]

Poul-Henning Kamp wrote:

> In message <404F8BBD.8020800@hda.hydro.com>, Terje Mathisen writes:
> 
>>>Well, the point is that TAI started at 1/1/1958 and UTC is defined
>>>as TAI+n(t), representing the leapseconds by their day on the TAI
>>>scale (plus their sign) is not subject to any third standards or
>>>convetions getting involved.
>>
>>So that just makes it even simpler then, right?
>>
>>1999-12-31 +
>>2005-06-30 -
> 
> No, because your textual formatting ties things into the calender
> used in the western world and the formatting specified by ISO for
> timestamps and a lot of other crap.

Yes?

Quoting what you wrote above:
" UTC is defined as TAI+n(t) "

and combining this with

a) the ISO standard for specifying (UTC) dates & times
and
b) the fact that leap seconds are defined to happen at midnight on the 
UTC scale

seems like an eminently useful thing to do. I.e. when UTC is thrown 
away, ntpd has more serious problems than trying to handle the UTC to 
TAI offset!

>>What I'm trying to say is that you don't need to store the table as a 
>>set of TAI second numbers when dates are much easier to enter and verify.
> 
> 
> I realize that, but what I'm saying is that by doing so you make
> the protocol more sensitive to random acts of legislation and
> standardization misfires.

Poul-Henning, now you're sounding like a grumpy old man! :-)

The definition if TAI is pretty dependable, right? (There are some 
potential problems with going backwards to times before 1972 (?) when 
the current length of the UTC/TAI second was fixed, but let's disregard 
this now, OK?)

The date/time format I suggested happens to be according to the current 
UTC standard, I cannot really see how legislation/standardization could 
mess up that in a manner incompatible with my suggested format. Any 
ideas/examples?

Anyway, it seems like NIST agrees with me, here's their specification:

  http://www.boulder.nist.gov/timefreq/pubs/bulletin/leapsecond.htm

However, if you _really_ don't like that, what about a tiny perl script 
to take a list of ISO (UTC) date/times and convert it into a list of TAI 
seconds?

Here's the NIST list (I've added a negative leap at the end for testing)
# List of all UTC leap seconds so far (Use '-' for a negative leap!)
       1972-06-30 	+
       1972-12-31 	+
       1973-12-31 	+
       1974-12-31 	+
       1975-12-31 	+
       1976-12-31 	+
       1977-12-31 	+
       1978-12-31 	+
       1979-12-31 	+
       1981-06-30 	+
       1982-06-30 	+
       1983-06-30 	+
       1985-06-30 	+
       1987-12-31 	+
       1989-12-31 	+
       1990-12-31 	+
       1992-06-30 	+
       1993-06-30 	+
       1994-06-30 	+
       1995-12-31 	+
       1997-06-30 	+
       1998-12-31 	+
       2023-09-30	-

A small perl script results in this output:

C:\DATA\ntp>perl tailist.pl leapsecond.txt
# Last TAI second (starting from 1958-01-01) before
# leap second insertion ('+') or deletion ('-'),
# Accumulated_leap_seconds,
# Corresponding UTC date/time
   457487999 +   1 Fri Jun 30 23:59:59 1972
   473385600 +   2 Sun Dec 31 23:59:59 1972
   504921601 +   3 Mon Dec 31 23:59:59 1973
   536457602 +   4 Tue Dec 31 23:59:59 1974
   567993603 +   5 Wed Dec 31 23:59:59 1975
   599616004 +   6 Fri Dec 31 23:59:59 1976
   631152005 +   7 Sat Dec 31 23:59:59 1977
   662688006 +   8 Sun Dec 31 23:59:59 1978
   694224007 +   9 Mon Dec 31 23:59:59 1979
   741484808 +  10 Tue Jun 30 23:59:59 1981
   773020809 +  11 Wed Jun 30 23:59:59 1982
   804556810 +  12 Thu Jun 30 23:59:59 1983
   867715211 +  13 Sun Jun 30 23:59:59 1985
   946684812 +  14 Thu Dec 31 23:59:59 1987
  1009843213 +  15 Sun Dec 31 23:59:59 1989
  1041379214 +  16 Mon Dec 31 23:59:59 1990
  1088640015 +  17 Tue Jun 30 23:59:59 1992
  1120176016 +  18 Wed Jun 30 23:59:59 1993
  1151712017 +  19 Thu Jun 30 23:59:59 1994
  1199145618 +  20 Sun Dec 31 23:59:59 1995
  1246406419 +  21 Mon Jun 30 23:59:59 1997
  1293840020 +  22 Thu Dec 31 23:59:59 1998
  2074809620 -  21 Sat Sep 30 23:59:58 2023

Here's the perl script, including a replacement for the missing timegm() 
in my version:
The timegm() algorithm is _really_ simple, and it's the only thing 
needed to be able to specify ISO dates instead of TAI seconds as input!

#/bin/perl -w

# use Time::Local; # You can use this function instead if you have it!

# tailist.pl: Take a list of UTC date/times and convert it into a
# corresponding list of TAI seconds, starting at 1958-01-01 00:00:00
# The times are for the last regular second, before the leap second
# is either inserted or deleted!

$leap_acc = 0;

# 12 years (3 leap) from 1958-01-01 to 1970-01-01
$UNIX_2_TAI_OFFSET = (12*365 + 3) * 86400;

printf("# Last TAI second (starting from 1958-01-01) before\n".
        "# leap second insertion ('+') or deletion ('-'),\n".
        "# Accumulated_leap_seconds,\n".
        "# Corresponding UTC date/time\n");
while (<>) {
   chomp;
   next if (/^\s*\#/);
   next if (/^\s*$/);

   if (/^\s*(\d{4})\-(\d\d)-(\d\d)\s+([\+\-])\s*$/) {
     # Just date, assume midnight!
     ($year, $month, $day, $sign) = ($1, $2, $3, $4);
     ($hour, $minute, $second) = (23, 59, ($sign eq "+" ? 59 : 58));
   }
   elsif 
(/^\s*(\d{4})\-(\d\d)-(\d\d)\s(\d\d):(\d\d):(\d\d)\s([\+\-])\s*$/) {
     # Full date/time specified!
     ($year, $month, $day, $hour, $minute, $second, $sign) =
         ($1, $2, $3, $4, $5, $6, $7);
   }
   else {
     return syntax("Bad format:\n\"$_\"\n");
   }

   $unix_seconds = timegm($second, $minute, $hour, $day, $month, $year);
   $tai_seconds = $unix_seconds + $leap_acc + $UNIX_2_TAI_OFFSET;
   $leap_acc += ($sign eq "+") ? 1 : -1;
   printf("%11.0f %s %3d %s\n",
     $tai_seconds, $sign, $leap_acc, scalar gmtime($unix_seconds));
}

sub syntax
{
   local($msg) = @_;
   printf(stderr "%s\n", $msg);
   return 1;
}

sub timegm
{
   local ($s, $m, $h, $day, $mon, $year) = @_;
   local($daynr, $century, $utc_seconds, $UNIX_DAYNR, @MonthStart);

   $UNIX_DAYNR = 370 * 365 + (370 >> 2) - 3 - 59;
   @MonthStart = (0,31,61,92,122,153,184,214,245,275,306,337);
   $year -= 1600;

   if (($mon -= 3) < 0) {
     $year--;
     $mon += 12;
   }

   $century = int($year / 100);
   $daynr = $year * 365 + ($year >> 2) - $century + ($century >> 2) - 
$UNIX_DAYNR;
   $daynr += $MonthStart[$mon] + $day - 1;
   $utc_seconds = $daynr * 86400 + $h * 3600 + $m * 60 + $s;
   return $utc_seconds;
}


Terje
-- 
- <Terje.Mathisen@hda.hydro.com>
"almost all programming can be viewed as an exercise in caching"
_______________________________________________
hackers mailing list
hackers@ntp.org
http://mailman.ntp.org/mailman/listinfo/hackers
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic