tz leap second bug encountered by sendmail 8.8.8 in Australia

Paul Eggert eggert at
Sun May 24 07:52:31 UTC 1998

   Date: Sat, 23 May 1998 00:25:34 -0400 (EDT)
   From: Bradley White <bww at>

   If "the user wants leap seconds and the system file doesn't (or vice
   versa)," the user is just kidding themselves.  Either the system clock
   ticks leap seconds (a stationary epoch), or it doesn't.  All tz files
   used on the system should reflect that reality.

That's good advice, but unfortunately the current tz package does not
follow it, and this apparently causes problems in practice.

By default the current tz distribution generates both "posix" and
"right" subdirectories, with the default being "posix".  It's natural
to assume that if all processes set the TZ environment variable to
"right/Australia/Adelaide", then the system will have leap second
support with Adelaide localtime.  Unfortunately this doesn't work as
expected, as it botches the localtime-gmtime offset.

One way to fix the problem is to remove the `posix' and `right'
subdirectories; this will make the configuration error less likely.

Also, the "GMT" link should be moved out of the "backward" file and
into the "etcetera" file, as the "GMT" link is currently essential for
proper leap second support.  (I didn't know this when I originally
moved it to the "backward" file -- sorry about that.)

I enclose a proposed patch below.  The Makefile change might be a bit
controversial, as it makes it harder to enable leap second support,
but the other two changes should be noncontroversial given the current
state of the code.

If these changes are acceptable, then it should be a win for gmtime to
look at the local time file's leap second info instead of looking at
the "GMT" file's leap second info, since the leap second info of the
two files ought to agree, and looking at just one file means one less
file to read.  But this is only a performance issue; it shouldn't
affect correctness.

RCS file: RCS/etcetera,v
retrieving revision 1997.11
retrieving revision 1997.11.1.1
diff -u -r1997.11 -r1997.11.1.1
--- etcetera	1997/12/29 14:31:50	1997.11
+++ etcetera	1998/05/24 07:28:25	1997.11.1.1
@@ -10,6 +10,10 @@
 Zone	Etc/UTC		0	-	UTC
 Zone	Etc/UCT		0	-	UCT
+# The following link is an important special case,
+# as functions like gmtime load the "GMT" file to handle leap seconds properly.
+Link	Etc/GMT			GMT
 Link	Etc/UTC				Etc/Universal
 Link	Etc/UTC				Etc/Zulu
RCS file: RCS/backward,v
retrieving revision 1997.10
retrieving revision 1997.10.1.1
diff -u -r1997.10 -r1997.10.1.1
--- backward	1997/12/11 17:44:35	1997.10
+++ backward	1998/05/24 07:28:25	1997.10.1.1
@@ -38,7 +38,6 @@
 Link	Africa/Cairo		Egypt
 Link	Europe/Dublin		Eire
 Link	Europe/London		GB
-Link	Etc/GMT			GMT
 Link	Etc/GMT+0		GMT+0
 Link	Etc/GMT-0		GMT-0
 Link	Etc/GMT0		GMT0
RCS file: RCS/Makefile,v
retrieving revision 1998.3
retrieving revision 1998.3.1.1
diff -u -r1998.3 -r1998.3.1.1
--- Makefile	1998/02/28 17:12:55	1998.3
+++ Makefile	1998/05/24 07:28:25	1998.3.1.1
@@ -58,21 +58,16 @@
 # If you always want time values interpreted as "seconds since the epoch
 # (not counting leap seconds)", use
-#	REDO=		posix_only
+#	REDO=		posix
 # below.  If you always want right time values interpreted as "seconds since
 # the epoch" (counting leap seconds)", use
-#	REDO=		right_only
-# below.  If you want both sets of data available, with leap seconds not
-# counted normally, use
-#	REDO=		posix_right
-# below.  If you want both sets of data available, with leap seconds counted
-# normally, use
-#	REDO=		right_posix
+#	REDO=		right
 # below.
 # POSIX mandates that leap seconds not be counted; for compatibility with it,
-# use either "posix_only" or "posix_right".
+# use "posix".  Do not use both "posix" and "right" files simultaneously,
+# as this causes either localtime or gmtime to yield incorrect results.
-REDO=		posix_right
+REDO=		posix
 # Since "." may not be in PATH...
@@ -287,21 +282,12 @@
 		cp yearistype
 		chmod +x yearistype
-posix_only:	zic $(TDATA)
+posix:		zic $(TDATA)
 		$(ZIC) -y $(YEARISTYPE) -d $(TZDIR) -L /dev/null $(TDATA)
-right_only:	zic leapseconds $(TDATA)
+right:		zic leapseconds $(TDATA)
 		$(ZIC) -y $(YEARISTYPE) -d $(TZDIR) -L leapseconds $(TDATA)
-other_two:	zic leapseconds $(TDATA)
-		$(ZIC) -y $(YEARISTYPE) -d $(TZDIR)/posix -L /dev/null $(TDATA)
-		$(ZIC) -y $(YEARISTYPE) \
-			-d $(TZDIR)/right -L leapseconds $(TDATA)
-posix_right:	posix_only other_two
-right_posix:	right_only other_two
 zones:		$(REDO)

More information about the tz mailing list