[tz] Proposal regarding tz DB and leap second updates

Paul Eggert eggert at cs.ucla.edu
Tue Aug 13 07:07:59 UTC 2013


Bradley White privately sent a Perl script to generate
'leapseconds' from the NIST leap-seconds.list file.
Since we use POSIX Awk for the other processing
it's probably better to use Awk here, too, so here's a proposed
patch with all the Makefile bells and whistles, which I pushed
to the experimental github repository.  The patch removes the
file 'leapseconds' from the repository because it's now generated
automatically.  I took the liberty of removing the copy of the
IERS announcement from the generated 'leapseconds' since its copyright
status was unclear.  The NIST leap-seconds.list file is public domain,
so it's OK for us to redistribute it.

>From 459b72d3edec98488e5132d4473c4678b4ed5a73 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert at cs.ucla.edu>
Date: Mon, 12 Aug 2013 23:58:29 -0700
Subject: [PATCH] Generate the 'leapseconds' file automatically from
 leap-seconds.list.

* leap-seconds.list: New file, copied from the NIST.
* leapseconds: Remove from git; it's now generated.
* leapseconds.awk: New file.
* Makefile (DATA): Add leap-seconds.list.  Remove leapseconds.
(MISC): Add leapseconds.awk.
(leapseconds): New rule.
(right_posix, posix_right): Depend on leapseconds.
(clean_misc): Remove leapseconds.
---
 Makefile          |  14 ++--
 leap-seconds.list | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 leapseconds       | 100 -----------------------
 leapseconds.awk   |  68 ++++++++++++++++
 4 files changed, 308 insertions(+), 105 deletions(-)
 create mode 100644 leap-seconds.list
 delete mode 100644 leapseconds
 create mode 100644 leapseconds.awk

diff --git a/Makefile b/Makefile
index db7f56e..68d7132 100644
--- a/Makefile
+++ b/Makefile
@@ -318,10 +318,11 @@ NDATA=		systemv factory
 SDATA=		solar87 solar88 solar89
 TDATA=		$(YDATA) $(NDATA) $(SDATA)
 TABDATA=	iso3166.tab zone.tab
-DATA=		$(YDATA) $(NDATA) $(SDATA) $(TABDATA) leapseconds yearistype.sh
+DATA=		$(YDATA) $(NDATA) $(SDATA) $(TABDATA) \
+			leap-seconds.list yearistype.sh
 WEB_PAGES=	tz-art.htm tz-link.htm
 MISC=		usno1988 usno1989 usno1989a usno1995 usno1997 usno1998 \
-			$(WEB_PAGES) checktab.awk workman.sh \
+			$(WEB_PAGES) checktab.awk leapseconds.awk workman.sh \
 			zoneinfo2tdf.pl
 ENCHILADA=	$(COMMON) $(DOCS) $(SOURCES) $(DATA) $(MISC)
 
@@ -375,6 +376,9 @@ yearistype:	yearistype.sh
 		cp yearistype.sh yearistype
 		chmod +x yearistype
 
+leapseconds:	leapseconds.awk leap-seconds.list
+		$(AWK) -f leapseconds.awk leap-seconds.list >$@
+
 posix_only:	zic $(TDATA)
 		$(ZIC) -y $(YEARISTYPE) -d $(TZDIR) -L /dev/null $(TDATA)
 
@@ -390,14 +394,14 @@ right_only:	zic leapseconds $(TDATA)
 # Therefore, the other two directories are now siblings of $(TZDIR).
 # You must replace all of $(TZDIR) to switch from not using leap seconds
 # to using them, or vice versa.
-right_posix:	right_only
+right_posix:	right_only leapseconds
 		rm -fr $(TZDIR)-leaps
 		ln -s $(TZDIR_BASENAME) $(TZDIR)-leaps || \
 		  $(ZIC) -y $(YEARISTYPE) \
 			-d $(TZDIR)-leaps -L leapseconds $(TDATA)
 		$(ZIC) -y $(YEARISTYPE) -d $(TZDIR)-posix -L /dev/null $(TDATA)
 
-posix_right:	posix_only
+posix_right:	posix_only leapseconds
 		rm -fr $(TZDIR)-posix
 		ln -s $(TZDIR_BASENAME) $(TZDIR)-posix || \
 		  $(ZIC) -y $(YEARISTYPE) \
@@ -440,7 +444,7 @@ check_web:	$(WEB_PAGES)
 
 clean_misc:
 		rm -f core *.o *.out \
-		  date tzselect version.h zdump zic yearistype
+		  date leapseconds tzselect version.h zdump zic yearistype
 clean:		clean_misc
 		rm -f -r tzpublic
 
diff --git a/leap-seconds.list b/leap-seconds.list
new file mode 100644
index 0000000..7df3de6
--- /dev/null
+++ b/leap-seconds.list
@@ -0,0 +1,231 @@
+#
+#	In the following text, the symbol '#' introduces
+#	a comment, which continues from that symbol until 
+#	the end of the line. A plain comment line has a
+#	whitespace character following the comment indicator.
+#	There are also special comment lines defined below. 
+#	A special comment will always have a non-whitespace 
+#	character in column 2.
+#
+#	A blank line should be ignored.
+#
+#	The following table shows the corrections that must
+#	be applied to compute International Atomic Time (TAI)
+#	from the Coordinated Universal Time (UTC) values that
+#	are transmitted by almost all time services.
+#
+#	The first column shows an epoch as a number of seconds
+#	since 1900.0 and the second column shows the number of
+#	seconds that must be added to UTC to compute TAI for
+#	any timestamp at or after that epoch. The value on 
+#	each line is valid from the indicated initial instant
+#	until the epoch given on the next one or indefinitely 
+#	into the future if there is no next line.
+#	(The comment on each line shows the representation of
+#	the corresponding initial epoch in the usual 
+#	day-month-year format. The epoch always begins at
+#	00:00:00 UTC on the indicated day. See Note 5 below.)
+#	
+#	Important notes:
+#
+#	1. Coordinated Universal Time (UTC) is often referred to
+#	as Greenwich Mean Time (GMT). The GMT time scale is no
+#	longer used, and the use of GMT to designate UTC is
+#	discouraged.
+#
+#	2. The UTC time scale is realized by many national 
+#	laboratories and timing centers. Each laboratory
+#	identifies its realization with its name: Thus
+#	UTC(NIST), UTC(USNO), etc. The differences among
+#	these different realizations are typically on the
+#	order of a few nanoseconds (i.e., 0.000 000 00x s)
+#	and can be ignored for many purposes. These differences
+#	are tabulated in Circular T, which is published monthly
+#	by the International Bureau of Weights and Measures
+#	(BIPM). See www.bipm.fr for more information.
+#
+#	3. The current defintion of the relationship between UTC 
+#	and TAI dates from 1 January 1972. A number of different 
+#	time scales were in use before than epoch, and it can be 
+#	quite difficult to compute precise timestamps and time 
+#	intervals in those "prehistoric" days. For more information,
+#	consult:
+#
+#		The Explanatory Supplement to the Astronomical
+#		Ephemeris.
+#	or
+#		Terry Quinn, "The BIPM and the Accurate Measurement
+#		of Time," Proc. of the IEEE, Vol. 79, pp. 894-905,
+#		July, 1991.
+#
+#	4.  The insertion of leap seconds into UTC is currently the
+#	responsibility of the International Earth Rotation Service,
+#	which is located at the Paris Observatory: 
+#
+#	Central Bureau of IERS
+#	61, Avenue de l'Observatoire
+#	75014 Paris, France.
+#
+#	Leap seconds are announced by the IERS in its Bulletin C
+#
+#	See hpiers.obspm.fr or www.iers.org for more details.
+#
+#	All national laboratories and timing centers use the
+#	data from the BIPM and the IERS to construct their
+#	local realizations of UTC.
+#
+#	Although the definition also includes the possibility
+#	of dropping seconds ("negative" leap seconds), this has 
+#	never been done and is unlikely to be necessary in the 
+#	foreseeable future.
+#
+#	5. If your system keeps time as the number of seconds since
+#	some epoch (e.g., NTP timestamps), then the algorithm for
+#	assigning a UTC time stamp to an event that happens during a positive
+#	leap second is not well defined. The official name of that leap 
+#	second is 23:59:60, but there is no way of representing that time 
+#	in these systems. 
+#	Many systems of this type effectively stop the system clock for 
+#	one second during the leap second and use a time that is equivalent 
+#	to 23:59:59 UTC twice. For these systems, the corresponding TAI 
+#	timestamp would be obtained by advancing to the next entry in the
+#	following table when the time equivalent to 23:59:59 UTC
+#	is used for the second time. Thus the leap second which
+#	occurred on 30 June 1972 at 23:59:59 UTC would have TAI
+#	timestamps computed as follows:
+#
+#	...
+#	30 June 1972 23:59:59 (2287785599, first time):	TAI= UTC + 10 seconds
+#	30 June 1972 23:59:60 (2287785599,second time):	TAI= UTC + 11 seconds
+#	1  July 1972 00:00:00 (2287785600)		TAI= UTC + 11 seconds
+#	...
+#
+#	If your system realizes the leap second by repeating 00:00:00 UTC twice
+#	(this is possible but not usual), then the advance to the next entry
+#	in the table must occur the second time that a time equivlent to 
+#	00:00:00 UTC is used. Thus, using the same example as above:
+#
+#	...
+#       30 June 1972 23:59:59 (2287785599):		TAI= UTC + 10 seconds
+#       30 June 1972 23:59:60 (2287785600, first time):	TAI= UTC + 10 seconds
+#       1  July 1972 00:00:00 (2287785600,second time):	TAI= UTC + 11 seconds
+#	...
+#
+#	in both cases the use of timestamps based on TAI produces a smooth
+#	time scale with no discontinuity in the time interval.
+#
+#	This complexity would not be needed for negative leap seconds (if they 
+#	are ever used). The UTC time would skip 23:59:59 and advance from 
+#	23:59:58 to 00:00:00 in that case.  The TAI offset would decrease by 
+#	1 second at the same instant.  This is a much easier situation to deal 
+#	with, since the difficulty of unambiguously representing the epoch 
+#	during the leap second does not arise.
+#
+#	Questions or comments to:
+#		Judah Levine
+#		Time and Frequency Division
+#		NIST
+#		Boulder, Colorado
+#		jlevine at boulder.nist.gov
+#
+#	Last Update of leap second values:   11 January 2012
+#
+#	The following line shows this last update date in NTP timestamp 
+#	format. This is the date on which the most recent change to
+#	the leap second data was added to the file. This line can
+#	be identified by the unique pair of characters in the first two 
+#	columns as shown below.
+#
+#$	 3535228800
+#
+#	The NTP timestamps are in units of seconds since the NTP epoch,
+#	which is 1900.0. The Modified Julian Day number corresponding
+#	to the NTP time stamp, X, can be computed as 
+#
+#	X/86400 + 15020
+#
+#	where the first term converts seconds to days and the second 
+#	term adds the MJD corresponding to 1900.0. The integer portion
+#	of the result is the integer MJD for that day, and any remainder
+#	is the time of day, expressed as the fraction of the day since 0 
+#	hours UTC. The conversion from day fraction to seconds or to
+#	hours, minutes, and seconds may involve rounding or truncation,
+#	depending on the method used in the computation.
+#
+#	The data in this file will be updated periodically as new leap 
+#	seconds are announced. In addition to being entered on the line
+#	above, the update time (in NTP format) will be added to the basic 
+#	file name leap-seconds to form the name leap-seconds.<NTP TIME>.
+#	In addition, the generic name leap-seconds.list will always point to 
+#	the most recent version of the file.
+#
+#	This update procedure will be performed only when a new leap second
+#	is announced. 
+#
+#	The following entry specifies the expiration date of the data
+#	in this file in units of seconds since 1900.0.  This expiration date 
+#	will be changed at least twice per year whether or not a new leap 
+#	second is announced. These semi-annual changes will be made no
+#	later than 1 June and 1 December of each year to indicate what
+#	action (if any) is to be taken on 30 June and 31 December, 
+#	respectively. (These are the customary effective dates for new
+#	leap seconds.) This expiration date will be identified by a
+#	unique pair of characters in columns 1 and 2 as shown below.
+#	In the unlikely event that a leap second is announced with an 
+#	effective date other than 30 June or 31 December, then this
+#	file will be edited to include that leap second as soon as it is
+#	announced or at least one month before the effective date
+#	(whichever is later). 
+#	If an announcement by the IERS specifies that no leap second is 
+#	scheduled, then only the expiration date of the file will 
+#	be advanced to show that the information in the file is still
+#	current -- the update time stamp, the data and the name of the file 
+#	will not change.
+#
+#	Updated through IERS Bulletin C46
+#	File expires on:  28 June 2014
+#
+#@	3612902400
+#
+2272060800	10	# 1 Jan 1972
+2287785600	11	# 1 Jul 1972
+2303683200	12	# 1 Jan 1973
+2335219200	13	# 1 Jan 1974
+2366755200	14	# 1 Jan 1975
+2398291200	15	# 1 Jan 1976
+2429913600	16	# 1 Jan 1977
+2461449600	17	# 1 Jan 1978
+2492985600	18	# 1 Jan 1979
+2524521600	19	# 1 Jan 1980
+2571782400	20	# 1 Jul 1981
+2603318400	21	# 1 Jul 1982
+2634854400	22	# 1 Jul 1983
+2698012800	23	# 1 Jul 1985
+2776982400	24	# 1 Jan 1988
+2840140800	25	# 1 Jan 1990
+2871676800	26	# 1 Jan 1991
+2918937600	27	# 1 Jul 1992
+2950473600	28	# 1 Jul 1993
+2982009600	29	# 1 Jul 1994
+3029443200	30	# 1 Jan 1996
+3076704000	31	# 1 Jul 1997
+3124137600	32	# 1 Jan 1999
+3345062400	33	# 1 Jan 2006
+3439756800	34	# 1 Jan 2009
+3550089600	35	# 1 Jul 2012
+#
+#	the following special comment contains the
+#	hash value of the data in this file computed
+#	use the secure hash algorithm as specified
+#	by FIPS 180-1. See the files in ~/pub/sha for
+#	the details of how this hash value is
+#	computed. Note that the hash computation
+#	ignores comments and whitespace characters
+#	in data lines. It includes the NTP values
+#	of both the last modification time and the 
+#	expiration time of the file, but not the
+#	white space on those lines.
+#	the hash line is also ignored in the
+#	computation.
+#
+#h	1151a8f e85a5069 9000fcdb 3d5e5365 1d505b37
diff --git a/leapseconds b/leapseconds
deleted file mode 100644
index 5b5c70e..0000000
--- a/leapseconds
+++ /dev/null
@@ -1,100 +0,0 @@
-# <pre>
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# Allowance for leapseconds added to each timezone file.
-
-# The International Earth Rotation Service periodically uses leap seconds
-# to keep UTC to within 0.9 s of UT1
-# (which measures the true angular orientation of the earth in space); see
-# Terry J Quinn, The BIPM and the accurate measure of time,
-# Proc IEEE 79, 7 (July 1991), 894-905.
-# There were no leap seconds before 1972, because the official mechanism
-# accounting for the discrepancy between atomic time and the earth's rotation
-# did not exist until the early 1970s.
-
-# The correction (+ or -) is made at the given time, so lines
-# will typically look like:
-#	Leap	YEAR	MON	DAY	23:59:60	+	R/S
-# or
-#	Leap	YEAR	MON	DAY	23:59:59	-	R/S
-
-# If the leapsecond is Rolling (R) the given time is local time
-# If the leapsecond is Stationary (S) the given time is UTC
-
-# Leap	YEAR	MONTH	DAY	HH:MM:SS	CORR	R/S
-Leap	1972	Jun	30	23:59:60	+	S
-Leap	1972	Dec	31	23:59:60	+	S
-Leap	1973	Dec	31	23:59:60	+	S
-Leap	1974	Dec	31	23:59:60	+	S
-Leap	1975	Dec	31	23:59:60	+	S
-Leap	1976	Dec	31	23:59:60	+	S
-Leap	1977	Dec	31	23:59:60	+	S
-Leap	1978	Dec	31	23:59:60	+	S
-Leap	1979	Dec	31	23:59:60	+	S
-Leap	1981	Jun	30	23:59:60	+	S
-Leap	1982	Jun	30	23:59:60	+	S
-Leap	1983	Jun	30	23:59:60	+	S
-Leap	1985	Jun	30	23:59:60	+	S
-Leap	1987	Dec	31	23:59:60	+	S
-Leap	1989	Dec	31	23:59:60	+	S
-Leap	1990	Dec	31	23:59:60	+	S
-Leap	1992	Jun	30	23:59:60	+	S
-Leap	1993	Jun	30	23:59:60	+	S
-Leap	1994	Jun	30	23:59:60	+	S
-Leap	1995	Dec	31	23:59:60	+	S
-Leap	1997	Jun	30	23:59:60	+	S
-Leap	1998	Dec	31	23:59:60	+	S
-Leap	2005	Dec	31	23:59:60	+	S
-Leap	2008	Dec	31	23:59:60	+	S
-Leap	2012	Jun	30	23:59:60	+	S
-
-# INTERNATIONAL EARTH ROTATION AND REFERENCE SYSTEMS SERVICE (IERS)
-#
-# SERVICE INTERNATIONAL DE LA ROTATION TERRESTRE ET DES SYSTEMES DE REFERENCE
-#
-#
-# SERVICE DE LA ROTATION TERRESTRE
-# OBSERVATOIRE DE PARIS
-# 61, Av. de l'Observatoire 75014 PARIS (France)
-# Tel.      : 33 (0) 1 40 51 22 26
-# FAX       : 33 (0) 1 40 51 22 91
-# e-mail    : (E-Mail Removed)
-# http://hpiers.obspm.fr/eop-pc
-#
-# Paris, 5 January 2012
-#
-#
-# Bulletin C 43
-#
-# To authorities responsible
-# for the measurement and
-# distribution of time
-#
-#
-# UTC TIME STEP
-# on the 1st of July 2012
-#
-#
-# A positive leap second will be introduced at the end of June 2012.
-# The sequence of dates of the UTC second markers will be:
-#
-#                          2012 June 30,     23h 59m 59s
-#                          2012 June 30,     23h 59m 60s
-#                          2012 July  1,      0h  0m  0s
-#
-# The difference between UTC and the International Atomic Time TAI is:
-#
-# from 2009 January 1, 0h UTC, to 2012 July 1  0h UTC  : UTC-TAI = - 34s
-# from 2012 July 1,    0h UTC, until further notice    : UTC-TAI = - 35s
-#
-# Leap seconds can be introduced in UTC at the end of the months of December
-# or June, depending on the evolution of UT1-TAI. Bulletin C is mailed every
-# six months, either to announce a time step in UTC or to confirm that there
-# will be no time step at the next possible date.
-#
-#
-# Daniel GAMBIS
-# Head
-# Earth Orientation Center of IERS
-# Observatoire de Paris, France
diff --git a/leapseconds.awk b/leapseconds.awk
new file mode 100644
index 0000000..732db99
--- /dev/null
+++ b/leapseconds.awk
@@ -0,0 +1,68 @@
+# Generate the 'leapseconds' file from 'leap-seconds.list'.
+
+# This file is in the public domain.
+
+BEGIN {
+    printf "%s", "\
+# Allowance for leapseconds added to each timezone file.\n\
+\n\
+# This file is in the public domain.\n\
+\n\
+# This file is generated automatically from the data in the public-domain\n\
+# leap-seconds.list file available from most NIST time servers.\n\
+# If the URL <ftp://time.nist.gov/pub/leap-seconds.list> does not work,\n\
+# you should be able to pick up leap-seconds.list from a secondary NIST server.\n\
+# For more about leap-seconds.list, please see\n\
+# The NTP Timescale and Leap Seconds\n\
+# <http://www.eecis.udel.edu/~mills/leap.html>.\n\
+\n\
+# The International Earth Rotation Service periodically uses leap seconds\n\
+# to keep UTC to within 0.9 s of UT1\n\
+# (which measures the true angular orientation of the earth in space); see\n\
+# Terry J Quinn, The BIPM and the accurate measure of time,\n\
+# Proc IEEE 79, 7 (July 1991), 894-905 <http://dx.doi.org/10.1109/5.84965>.\n\
+# There were no leap seconds before 1972, because the official mechanism\n\
+# accounting for the discrepancy between atomic time and the earth's rotation\n\
+# did not exist until the early 1970s.\n\
+\n\
+# The correction (+ or -) is made at the given time, so lines\n\
+# will typically look like:\n\
+#	Leap	YEAR	MON	DAY	23:59:60	+	R/S\n\
+# or\n\
+#	Leap	YEAR	MON	DAY	23:59:59	-	R/S\n\
+\n\
+# If the leapsecond is Rolling (R) the given time is local time.\n\
+# If the leapsecond is Stationary (S) the given time is UTC.\n\
+\n\
+# Leap	YEAR	MONTH	DAY	HH:MM:SS	CORR	R/S\n\
+"
+}
+
+/^ *$/ { next }
+/^#/ { next }
+
+{
+    NTP_timestamp = $1
+    TAI_minus_UTC = $2
+    hash_mark = $3
+    one = $4
+    month = $5
+    year = $6
+    if (old_TAI_minus_UTC) {
+	if (old_TAI_minus_UTC < TAI_minus_UTC) {
+	    sign = "23:59:60\t+"
+	} else {
+	    sign = "23:59:59\t-"
+	}
+	if (month == "Jan") {
+	    year--;
+	    month = "Dec";
+	    day = 31
+	} else if (month == "Jul") {
+	    month = "Jun";
+	    day = 30
+	}
+	printf "Leap\t%s\t%s\t%s\t%s\tS\n", year, month, day, sign
+    }
+    old_TAI_minus_UTC = TAI_minus_UTC
+}
-- 
1.8.1.2





More information about the tz mailing list