Module Name:    src
Committed By:   christos
Date:           Mon May 25 14:52:48 UTC 2020

Modified Files:
        src/lib/libc/time: Makefile NEWS localtime.c private.h strftime.c
            theory.html tz-art.html tz-link.html tzfile.5 version zdump.8
            zdump.c zic.8 zic.c

Log Message:
Bring in 2020a


To generate a diff of this commit:
cvs rdiff -u -r1.44 -r1.45 src/lib/libc/time/Makefile
cvs rdiff -u -r1.29 -r1.30 src/lib/libc/time/NEWS src/lib/libc/time/tzfile.5
cvs rdiff -u -r1.122 -r1.123 src/lib/libc/time/localtime.c
cvs rdiff -u -r1.55 -r1.56 src/lib/libc/time/private.h
cvs rdiff -u -r1.46 -r1.47 src/lib/libc/time/strftime.c
cvs rdiff -u -r1.8 -r1.9 src/lib/libc/time/theory.html
cvs rdiff -u -r1.5 -r1.6 src/lib/libc/time/tz-art.html
cvs rdiff -u -r1.6 -r1.7 src/lib/libc/time/tz-link.html
cvs rdiff -u -r1.12 -r1.13 src/lib/libc/time/version
cvs rdiff -u -r1.19 -r1.20 src/lib/libc/time/zdump.8
cvs rdiff -u -r1.52 -r1.53 src/lib/libc/time/zdump.c
cvs rdiff -u -r1.33 -r1.34 src/lib/libc/time/zic.8
cvs rdiff -u -r1.75 -r1.76 src/lib/libc/time/zic.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/time/Makefile
diff -u src/lib/libc/time/Makefile:1.44 src/lib/libc/time/Makefile:1.45
--- src/lib/libc/time/Makefile:1.44	Wed Jul  3 11:50:16 2019
+++ src/lib/libc/time/Makefile	Mon May 25 10:52:48 2020
@@ -150,6 +150,15 @@ TIME_T_ALTERNATIVES_TAIL = int32_t uint3
 
 REDO=		posix_right
 
+# Whether to put an "Expires" line in the leapseconds file.
+# Use EXPIRES_LINE=1 to put the line in, 0 to omit it.
+# The EXPIRES_LINE value matters only if REDO's value contains "right".
+# If you change EXPIRES_LINE, remove the leapseconds file before running "make".
+# zic's support for the Expires line was introduced in tzdb 2020a,
+# and EXPIRES_LINE defaults to 0 for now so that the leapseconds file
+# can be given to older zic implementations.
+EXPIRES_LINE=	0
+
 # To install data in text form that has all the information of the TZif data,
 # (optionally incorporating leap second information), use
 #	TZDATA_TEXT=	tzdata.zi leapseconds
@@ -295,8 +304,9 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fn
 # than TM_GMTOFF and TM_ZONE.  However, most of them are standardized.
 # #
 # # To omit or support the external variable "tzname", add one of:
-# #	-DHAVE_TZNAME=0
-# #	-DHAVE_TZNAME=1
+# #	-DHAVE_TZNAME=0 # do not support "tzname"
+# #	-DHAVE_TZNAME=1 # support "tzname", which is defined by system library
+# #	-DHAVE_TZNAME=2 # support and define "tzname"
 # # to the "CFLAGS=" line.  "tzname" is required by POSIX 1988 and later.
 # # If not defined, the code attempts to guess HAVE_TZNAME from other macros.
 # # Warning: unless time_tz is also defined, HAVE_TZNAME=1 can cause
@@ -304,16 +314,20 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fn
 # # presumably due to memory allocation issues.
 # #
 # # To omit or support the external variables "timezone" and "daylight", add
-# #	-DUSG_COMPAT=0
-# #	-DUSG_COMPAT=1
+# #	-DUSG_COMPAT=0 # do not support
+# #	-DUSG_COMPAT=1 # support, and variables are defined by system library
+# #	-DUSG_COMPAT=2 # support and define variables
 # # to the "CFLAGS=" line; "timezone" and "daylight" are inspired by
 # # Unix Systems Group code and are required by POSIX 2008 (with XSI) and later.
 # # If not defined, the code attempts to guess USG_COMPAT from other macros.
 # #
 # # To support the external variable "altzone", add
-# #	-DALTZONE
+# #	-DALTZONE=0 # do not support
+# #	-DALTZONE=1 # support "altzone", which is defined by system library
+# #	-DALTZONE=2 # support and define "altzone"
 # # to the end of the "CFLAGS=" line; although "altzone" appeared in
 # # System V Release 3.1 it has not been standardized.
+# # If not defined, the code attempts to guess ALTZONE from other macros.
 #
 # If you want functions that were inspired by early versions of X3J11's work,
 # add
@@ -321,9 +335,7 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fn
 # to the end of the "CFLAGS=" line.  This arranges for the functions
 # "tzsetwall", "offtime", "timelocal", "timegm", "timeoff",
 # "posix2time", and "time2posix" to be added to the time conversion library.
-# "tzsetwall" is like "tzset" except that it arranges for local wall clock
-# time (rather than the timezone specified in the TZ environment variable)
-# to be used.
+# "tzsetwall" is deprecated and is intended to be removed soon; see NEWS.
 # "offtime" is like "gmtime" except that it accepts a second (long) argument
 # that gives an offset to add to the time_t when converting it.
 # "timelocal" is equivalent to "mktime".
@@ -333,7 +345,6 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fn
 # that gives an offset to use when converting to a time_t.
 # "posix2time" and "time2posix" are described in an included manual page.
 # X3J11's work does not describe any of these functions.
-# Sun has provided "tzsetwall", "timelocal", and "timegm" in SunOS 4.0.
 # These functions may well disappear in future releases of the time
 # conversion package.
 #
@@ -505,11 +516,11 @@ RANLIB=		:
 TZCOBJS=	zic.o
 TZDOBJS=	zdump.o localtime.o asctime.o strftime.o
 DATEOBJS=	date.o localtime.o strftime.o asctime.o
-LIBSRCS=	localtime.c asctime.c difftime.c
-LIBOBJS=	localtime.o asctime.o difftime.o
+LIBSRCS=	localtime.c asctime.c difftime.c strftime.c
+LIBOBJS=	localtime.o asctime.o difftime.o strftime.o
 HEADERS=	tzfile.h private.h
 NONLIBSRCS=	zic.c zdump.c
-NEWUCBSRCS=	date.c strftime.c
+NEWUCBSRCS=	date.c
 SOURCES=	$(HEADERS) $(LIBSRCS) $(NONLIBSRCS) $(NEWUCBSRCS) \
 			tzselect.ksh workman.sh
 MANS=		newctime.3 newstrftime.3 newtzset.3 time2posix.3 \
@@ -651,7 +662,8 @@ yearistype:	yearistype.sh
 		chmod +x yearistype
 
 leapseconds:	$(LEAP_DEPS)
-		$(AWK) -f leapseconds.awk leap-seconds.list >$@.out
+		$(AWK) -v EXPIRES_LINE=$(EXPIRES_LINE) \
+		  -f leapseconds.awk leap-seconds.list >$@.out
 		mv $@.out $@
 
 # Arguments to pass to submakes of install_data.

Index: src/lib/libc/time/NEWS
diff -u src/lib/libc/time/NEWS:1.29 src/lib/libc/time/NEWS:1.30
--- src/lib/libc/time/NEWS:1.29	Wed Jul  3 11:50:16 2019
+++ src/lib/libc/time/NEWS	Mon May 25 10:52:48 2020
@@ -1,5 +1,162 @@
 News for the tz database
 
+Release 2020a - 2020-04-23 16:03:47 -0700
+
+  Briefly:
+    Morocco springs forward on 2020-05-31, not 2020-05-24.
+    Canada's Yukon advanced to -07 year-round on 2020-03-08.
+    America/Nuuk renamed from America/Godthab.
+    zic now supports expiration dates for leap second lists.
+
+  Changes to future timestamps
+
+    Morocco's second spring-forward transition in 2020 will be May 31,
+    not May 24 as predicted earlier.  (Thanks to Semlali Naoufal.)
+    Adjust future-year predictions to use the first Sunday after the
+    day after Ramadan, not the first Sunday after Ramadan.
+
+    Canada's Yukon, represented by America/Whitehorse and
+    America/Dawson, advanced to -07 year-round, beginning with its
+    spring-forward transition on 2020-03-08, and will not fall back on
+    2020-11-01.  Although a government press release calls this
+    "permanent Pacific Daylight Saving Time", we prefer MST for
+    consistency with nearby Dawson Creek, Creston, and Fort Nelson.
+    (Thanks to Tim Parenti.)
+
+  Changes to past timestamps
+
+    Shanghai observed DST in 1919.  (Thanks to Phake Nick.)
+
+  Changes to timezone identifiers
+
+    To reflect current usage in English better, America/Godthab has
+    been renamed to America/Nuuk.  A backwards-compatibility link
+    remains for the old name.
+
+  Changes to code
+
+    localtime.c no longer mishandles timestamps after the last
+    transition in a TZif file with leap seconds and with daylight
+    saving time transitions projected into the indefinite future.
+    For example, with TZ='America/Los_Angeles' with leap seconds,
+    zdump formerly reported a DST transition on 2038-03-14
+    from 01:59:32.999... to 02:59:33 instead of the correct transition
+    from 01:59:59.999... to 03:00:00.
+
+    zic -L now supports an Expires line in the leapseconds file, and
+    truncates the TZif output accordingly.  This propagates leap
+    second expiration information into the TZif file, and avoids the
+    abovementioned localtime.c bug as well as similar bugs present in
+    many client implementations.  If no Expires line is present, zic
+    -L instead truncates the TZif output based on the #expires comment
+    present in leapseconds files distributed by tzdb 2018f and later;
+    however, this usage is obsolescent.  For now, the distributed
+    leapseconds file has an Expires line that is commented out, so
+    that the file can be fed to older versions of zic which ignore the
+    commented-out line.  Future tzdb distributions are planned to
+    contain a leapseconds file with an Expires line.
+
+    The configuration macros HAVE_TZNAME and USG_COMPAT should now be
+    set to 1 if the system library supports the feature, and 2 if not.
+    As before, these macros are nonzero if tzcode should support the
+    feature, zero otherwise.
+
+    The configuration macro ALTZONE now has the same values with the
+    same meaning as HAVE_TZNAME and USG_COMPAT.
+
+    The code's defense against CRLF in leap-seconds.list is now
+    portable to POSIX awk.  (Problem reported by Deborah Goldsmith.)
+
+    Although the undocumented tzsetwall function is not changed in
+    this release, it is now deprecated in preparation for removal in
+    future releases.  Due to POSIX requirements, tzsetwall has not
+    worked for some time.  Any code that uses it should instead use
+    tzalloc(NULL) or, if portability trumps thread-safety, should
+    unset the TZ environment variable.
+
+  Changes to commentary
+
+    The Îles-de-la-Madeleine and the Listuguj reserve are noted as
+    following America/Halifax, and comments about Yukon's "south" and
+    "north" have been corrected to say "east" and "west".  (Thanks to
+    Jeffery Nichols.)
+
+
+Release 2019c - 2019-09-11 08:59:48 -0700
+
+  Briefly:
+    Fiji observes DST from 2019-11-10 to 2020-01-12.
+    Norfolk Island starts observing Australian-style DST.
+
+  Changes to future timestamps
+
+    Fiji's next DST transitions will be 2019-11-10 and 2020-01-12
+    instead of 2019-11-03 and 2020-01-19.  (Thanks to Raymond Kumar.)
+    Adjust future guesses accordingly.
+
+    Norfolk Island will observe Australian-style DST starting in
+    spring 2019.  The first transition is on 2019-10-06.  (Thanks to
+    Kyle Czech and Michael Deckers.)
+
+  Changes to past timestamps
+
+    Many corrections to time in Turkey from 1940 through 1985.
+    (Thanks to Oya Vulaş via Alois Treindl, and to Kıvanç Yazan.)
+
+    The Norfolk Island 1975-03-02 transition was at 02:00 standard
+    time, not 02:00 DST.  (Thanks to Michael Deckers.)
+
+    South Korea observed DST from 1948 through 1951.  Although this
+    info was supposed to appear in release 2014j, a typo inadvertently
+    suppressed the change.  (Thanks to Alois Treindl.)
+
+    Detroit observed DST in 1967 and 1968 following the US DST rules,
+    except that its 1967 DST began on June 14 at 00:01.  (Thanks to
+    Alois Treindl for pointing out that the old data entries were
+    probably wrong.)
+
+    Fix several errors in pre-1970 transitions in Perry County, IN.
+    (Thanks to Alois Triendl for pointing out the 1967/9 errors.)
+
+    Edmonton did not observe DST in 1967 or 1969.  In 1946 Vancouver
+    ended DST on 09-29 not 10-13, and Vienna ended DST on 10-07 not
+    10-06.  In 1945 Königsberg (now Kaliningrad) switched from +01/+02
+    to +02/+03 on 04-10 not 01-01, and its +02/+03 is abbreviated
+    EET/EEST, not CET/CEST.  (Thanks to Alois Triendl.)  In 1946
+    Königsberg switched to +03 on 04-07 not 01-01.
+
+    In 1946 Louisville switched from CST to CDT on 04-28 at 00:01, not
+    01-01 at 00:00.  (Thanks to Alois Treindl and Michael Deckers.)
+    Also, it switched from CST to CDT on 1950-04-30, not 1947-04-27.
+
+    The 1892-05-01 transition in Brussels was at 00:17:30, not at noon.
+    (Thanks to Michael Deckers.)
+
+  Changes to past time zone abbreviations and DST flags
+
+    Hong Kong Winter Time, observed from 1941-10-01 to 1941-12-25,
+    is now flagged as DST and is abbreviated HKWT not HKT.
+
+  Changes to code
+
+    leapseconds.awk now relies only on its input data, rather than
+    also relying on its comments.  (Inspired by code from Dennis
+    Ferguson and Chris Woodbury.)
+
+    The code now defends against CRLFs in leap-seconds.list.
+    (Thanks to Brian Inglis and Chris Woodbury.)
+
+  Changes to documentation and commentary
+
+    theory.html discusses leap seconds.  (Thanks to Steve Summit.)
+
+    Nashville's newspapers dueled about the time of day in the 1950s.
+    (Thanks to John Seigenthaler.)
+
+    Liechtenstein observed Swiss DST in 1941/2.
+    (Thanks to Alois Treindl.)
+
+
 Release 2019b - 2019-07-01 00:09:53 -0700
 
   Briefly:
Index: src/lib/libc/time/tzfile.5
diff -u src/lib/libc/time/tzfile.5:1.29 src/lib/libc/time/tzfile.5:1.30
--- src/lib/libc/time/tzfile.5:1.29	Wed Jul  3 11:50:16 2019
+++ src/lib/libc/time/tzfile.5	Mon May 25 10:52:48 2020
@@ -1,8 +1,8 @@
-.\"	$NetBSD: tzfile.5,v 1.29 2019/07/03 15:50:16 christos Exp $
+.\"	$NetBSD: tzfile.5,v 1.30 2020/05/25 14:52:48 christos Exp $
 .\"
 .\" This file is in the public domain, so clarified as of
 .\" 1996-06-05 by Arthur David Olson (arthur_david_ol...@nih.gov).
-.Dd July 2, 2019
+.Dd May 25, 2020
 .Dt TZFILE 5
 .Os
 .Sh NAME
@@ -48,6 +48,7 @@ Six four-byte integer values, in the fol
 .Bl -inset
 .It Va tzh_ttisutcnt
 The number of UT/local indicators stored in the file.
+(UT is Universal Time.)
 .It Va tzh_ttisstdcnt
 The number of standard/wall indicators stored in the file.
 .It Va tzh_leapcnt

Index: src/lib/libc/time/localtime.c
diff -u src/lib/libc/time/localtime.c:1.122 src/lib/libc/time/localtime.c:1.123
--- src/lib/libc/time/localtime.c:1.122	Wed Jul  3 11:50:16 2019
+++ src/lib/libc/time/localtime.c	Mon May 25 10:52:48 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: localtime.c,v 1.122 2019/07/03 15:50:16 christos Exp $	*/
+/*	$NetBSD: localtime.c,v 1.123 2020/05/25 14:52:48 christos Exp $	*/
 
 /* Convert timestamp from time_t to struct tm.  */
 
@@ -12,7 +12,7 @@
 #if 0
 static char	elsieid[] = "@(#)localtime.c	8.17";
 #else
-__RCSID("$NetBSD: localtime.c,v 1.122 2019/07/03 15:50:16 christos Exp $");
+__RCSID("$NetBSD: localtime.c,v 1.123 2020/05/25 14:52:48 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -165,6 +165,7 @@ static struct tm *gmtsub(struct state co
 			 struct tm *);
 static bool increment_overflow(int *, int);
 static bool increment_overflow_time(time_t *, int_fast32_t);
+static int_fast64_t leapcorr(struct state const *, time_t);
 static bool normalize_overflow32(int_fast32_t *, int *, int);
 static struct tm *timesub(time_t const *, int_fast32_t, struct state const *,
 			  struct tm *);
@@ -198,7 +199,7 @@ rwlock_t __lcl_lock = RWLOCK_INITIALIZER
 
 static struct tm	tm;
 
-#if !HAVE_POSIX_DECLS || TZ_TIME_T || defined(__NetBSD__)
+#if 2 <= HAVE_TZNAME + TZ_TIME_T || defined(__NetBSD__)
 # if !defined(__LIBC12_SOURCE__)
 
 __aconst char *		tzname[2] = {
@@ -211,21 +212,21 @@ __aconst char *		tzname[2] = {
 extern __aconst char *	tzname[2];
 
 # endif /* __LIBC12_SOURCE__ */
+#endif
 
-# if USG_COMPAT
-#  if !defined(__LIBC12_SOURCE__)
+#if 2 <= USG_COMPAT + TZ_TIME_T || defined(__NetBSD__)
+# if !defined(__LIBC12_SOURCE__)
 long 			timezone = 0;
 int			daylight = 0;
-#  else
+# else
 extern int		daylight;
 extern long		timezone __RENAME(__timezone13);
-#  endif /* __LIBC12_SOURCE__ */
-# endif /* defined USG_COMPAT */
+# endif /* __LIBC12_SOURCE__ */
+#endif /* 2<= USG_COMPAT + TZ_TIME_T */
 
-# ifdef ALTZONE
+#if 2 <= ALTZONE + TZ_TIME_T
 long			altzone = 0;
-# endif /* defined ALTZONE */
-#endif /* !HAVE_POSIX_DECLS */
+#endif /* 2 <= ALTZONE + TZ_TIME_T */
 
 /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX.  */
 static void
@@ -353,10 +354,10 @@ update_tzname_etc(const struct state *sp
 	if (!ttisp->tt_isdst)
 		timezone = - ttisp->tt_utoff;
 #endif
-#ifdef ALTZONE
+#if ALTZONE
 	if (ttisp->tt_isdst)
 	    altzone = - ttisp->tt_utoff;
-#endif /* defined ALTZONE */
+#endif /* ALTZONE */
 }
 
 static void
@@ -373,9 +374,9 @@ settzname(void)
 	daylight = 0;
 	timezone = 0;
 #endif
-#ifdef ALTZONE
+#if ALTZONE
 	altzone = 0;
-#endif /* defined ALTZONE */
+#endif
 	if (sp == NULL) {
 		return;
 	}
@@ -699,11 +700,13 @@ tzloadbody(char const *name, struct stat
 
 			    for (i = 0; i < ts->timecnt; i++)
 			      if (sp->timecnt == 0
-				  || sp->ats[sp->timecnt - 1] < ts->ats[i])
+				  || (sp->ats[sp->timecnt - 1]
+				      < ts->ats[i] + leapcorr(sp, ts->ats[i])))
 				break;
 			    while (i < ts->timecnt
 				   && sp->timecnt < TZ_MAX_TIMES) {
-			      sp->ats[sp->timecnt] = ts->ats[i];
+			      sp->ats[sp->timecnt] = (time_t)
+				(ts->ats[i] + leapcorr(sp, ts->ats[i]));
 			      sp->types[sp->timecnt] = (sp->typecnt
 							+ ts->types[i]);
 			      sp->timecnt++;
@@ -1703,7 +1706,7 @@ offtime_r(const time_t *timep, long offs
 #  define daylight 0
 #  define timezone 0
 # endif
-# ifndef ALTZONE
+# if !ALTZONE
 #  define altzone 0
 # endif
  
@@ -2401,22 +2404,8 @@ timeoff(struct tm *tmp, long offset)
 
 #endif /* defined STD_INSPIRED */
 
-/*
-** XXX--is the below the right way to conditionalize??
-*/
-
-#ifdef STD_INSPIRED
-
-/*
-** IEEE Std 1003.1 (POSIX) says that 536457599
-** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
-** is not the case if we are accounting for leap seconds.
-** So, we provide the following conversion routines for use
-** when exchanging timestamps with POSIX conforming systems.
-*/
-
 static int_fast64_t
-leapcorr(const timezone_t sp, time_t t)
+leapcorr(struct state const *sp, time_t t)
 {
 	struct lsinfo const * lp;
 	int		i;
@@ -2448,6 +2437,20 @@ time2posix(time_t t)
 	return t;
 }
 
+/*
+** XXX--is the below the right way to conditionalize??
+*/
+
+#ifdef STD_INSPIRED
+
+/*
+** IEEE Std 1003.1 (POSIX) says that 536457599
+** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
+** is not the case if we are accounting for leap seconds.
+** So, we provide the following conversion routines for use
+** when exchanging timestamps with POSIX conforming systems.
+*/
+
 NETBSD_INSPIRED_EXTERN time_t
 posix2time_z(timezone_t sp, time_t t)
 {

Index: src/lib/libc/time/private.h
diff -u src/lib/libc/time/private.h:1.55 src/lib/libc/time/private.h:1.56
--- src/lib/libc/time/private.h:1.55	Thu Apr  4 18:03:23 2019
+++ src/lib/libc/time/private.h	Mon May 25 10:52:48 2020
@@ -1,6 +1,6 @@
 /* Private header for tzdb code.  */
 
-/*	$NetBSD: private.h,v 1.55 2019/04/04 22:03:23 christos Exp $	*/
+/*	$NetBSD: private.h,v 1.56 2020/05/25 14:52:48 christos Exp $	*/
 
 #ifndef PRIVATE_H
 #define PRIVATE_H
@@ -145,11 +145,16 @@
 */
 
 #ifndef __NetBSD__
-/* Avoid clashes with NetBSD by renaming NetBSD's declarations.  */
+/* Avoid clashes with NetBSD by renaming NetBSD's declarations.
+   If defining the 'timezone' variable, avoid a clash with FreeBSD's
+   'timezone' function by renaming its declaration.  */
 #define localtime_rz sys_localtime_rz
 #define mktime_z sys_mktime_z
 #define posix2time_z sys_posix2time_z
 #define time2posix_z sys_time2posix_z
+#if defined USG_COMPAT && USG_COMPAT == 2
+# define timezone sys_timezone
+#endif
 #define timezone_t sys_timezone_t
 #define tzalloc sys_tzalloc
 #define tzfree sys_tzfree
@@ -158,6 +163,9 @@
 #undef mktime_z
 #undef posix2time_z
 #undef time2posix_z
+#if defined USG_COMPAT && USG_COMPAT == 2
+# undef timezone
+#endif
 #undef timezone_t
 #undef tzalloc
 #undef tzfree
@@ -214,6 +222,14 @@
 # endif
 #endif
 
+#ifndef ALTZONE
+# if defined __sun || defined _M_XENIX
+#  define ALTZONE 1
+# else
+#  define ALTZONE 0
+# endif
+#endif
+
 #ifndef R_OK
 #define R_OK	4
 #endif /* !defined R_OK */
@@ -425,6 +441,10 @@ static time_t sys_time(time_t *x) { retu
 
 typedef time_tz tz_time_t;
 
+# undef  asctime
+# define asctime tz_asctime
+# undef  asctime_r
+# define asctime_r tz_asctime_r
 # undef  ctime
 # define ctime tz_ctime
 # undef  ctime_r
@@ -489,11 +509,13 @@ typedef time_tz tz_time_t;
 #  undef  timezone
 #  define timezone tz_timezone
 # endif
-# ifdef ALTZONE
+# if ALTZONE
 #  undef  altzone
 #  define altzone tz_altzone
 # endif
 
+char *asctime(struct tm const *);
+char *asctime_r(struct tm const *restrict, char *restrict);
 char *ctime(time_t const *);
 char *ctime_r(time_t const *, char *);
 double difftime(time_t, time_t) ATTRIBUTE_CONST;
@@ -528,17 +550,14 @@ extern char *asctime_r(struct tm const *
 extern char **environ;
 #endif
 
-#if TZ_TIME_T || !HAVE_POSIX_DECLS
-# if HAVE_TZNAME
+#if 2 <= HAVE_TZNAME + (TZ_TIME_T || !HAVE_POSIX_DECLS)
 extern char *tzname[];
-# endif
-# if USG_COMPAT
+#endif
+#if 2 <= USG_COMPAT + (TZ_TIME_T || !HAVE_POSIX_DECLS)
 extern long timezone;
 extern int daylight;
-# endif
 #endif
-
-#ifdef ALTZONE
+#if 2 <= ALTZONE + (TZ_TIME_T || !HAVE_POSIX_DECLS)
 extern long altzone;
 #endif
 

Index: src/lib/libc/time/strftime.c
diff -u src/lib/libc/time/strftime.c:1.46 src/lib/libc/time/strftime.c:1.47
--- src/lib/libc/time/strftime.c:1.46	Sun Apr  7 18:31:54 2019
+++ src/lib/libc/time/strftime.c	Mon May 25 10:52:48 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: strftime.c,v 1.46 2019/04/07 22:31:54 christos Exp $	*/
+/*	$NetBSD: strftime.c,v 1.47 2020/05/25 14:52:48 christos Exp $	*/
 
 /* Convert a broken-down timestamp to a string.  */
 
@@ -35,7 +35,7 @@
 static char	elsieid[] = "@(#)strftime.c	7.64";
 static char	elsieid[] = "@(#)strftime.c	8.3";
 #else
-__RCSID("$NetBSD: strftime.c,v 1.46 2019/04/07 22:31:54 christos Exp $");
+__RCSID("$NetBSD: strftime.c,v 1.47 2020/05/25 14:52:48 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -563,7 +563,7 @@ label:
 				*/
 				continue;
 			case 'z':
-#if defined TM_GMTOFF || USG_COMPAT || defined ALTZONE
+#if defined TM_GMTOFF || USG_COMPAT || ALTZONE
 				{
 				long		diff;
 				char const *	sign;
@@ -601,7 +601,7 @@ label:
 					continue;
 #   endif
 				else
-#   ifdef ALTZONE
+#   if ALTZONE
 					diff = -altzone;
 #   else
 					continue;

Index: src/lib/libc/time/theory.html
diff -u src/lib/libc/time/theory.html:1.8 src/lib/libc/time/theory.html:1.9
--- src/lib/libc/time/theory.html:1.8	Wed Jul  3 11:50:16 2019
+++ src/lib/libc/time/theory.html	Mon May 25 10:52:48 2020
@@ -21,6 +21,7 @@
 	  database</a></li>
       <li><a href="#functions">Time and date functions</a></li>
       <li><a href="#stability">Interface stability</a></li>
+      <li><a href="#leapsec">Leap seconds</a></li>
       <li><a href="#calendar">Calendrical issues</a></li>
       <li><a href="#planets">Time and time zones on other planets</a></li>
     </ul>
@@ -98,8 +99,9 @@ A <code><abbr>tz</abbr></code> timezone 
 have more than two changes per year, these changes need not merely
 flip back and forth between two alternatives, and the rules themselves
 can change at times.
-Whether and when a timezone changes its
-clock, and even the timezone's notional base offset from UTC, are variable.
+Whether and when a timezone changes its clock,
+and even the timezone's notional base offset from <abbr>UTC</abbr>,
+are variable.
 It does not always make sense to talk about a timezone's
 "base offset", which is not necessarily a single number.
 </p>
@@ -296,6 +298,10 @@ in decreasing order of importance:
     If a name is changed, put its old spelling in the
     '<code>backward</code>' file.
     This means old spellings will continue to work.
+    Ordinarily a name change should occur only in the rare case when
+    a location's consensus English-language spelling changes; for example,
+    in 2008 <code>Asia/Calcutta</code> was renamed to <code>Asia/Kolkata</code>
+    due to long-time widespread use of the new city name instead of the old.
   </li>
 </ul>
 
@@ -428,7 +434,7 @@ in decreasing order of importance:
       EET/EEST Eastern European,
       GST/GDT Guam,
       HST/HDT/HWT/HPT Hawaii,
-      HKT/HKST Hong Kong,
+      HKT/HKST/HKWT Hong Kong,
       IST India,
       IST/GMT Irish,
       IST/IDT/IDDT Israel,
@@ -972,7 +978,8 @@ an older <code>zic</code>.
     that do not fit into the POSIX model.
   </li>
   <li>
-    POSIX requires that systems ignore leap seconds.
+    POSIX requires that <code>time_t</code> clock counts exclude leap
+    seconds.
   </li>
   <li>
     The <code><abbr>tz</abbr></code> code attempts to support all the
@@ -1051,28 +1058,12 @@ an older <code>zic</code>.
     The functions were inspired by <a href="https://netbsd.org/";>NetBSD</a>.
   </li>
   <li>
-    A function <code>tzsetwall</code> has been added to arrange for the
-    system's best approximation to local (wall clock) time to be delivered
-    by subsequent calls to <code>localtime</code>.
-    Source code for portable applications that "must" run on local
-    time should call <code>tzsetwall</code>;
-    if such code is moved to "old" systems that do not
-    provide <code>tzsetwall</code>, you will not be able to generate an
-    executable program.
-    (These functions also arrange for local time to
-    be used if <code>tzset</code> is called &ndash; directly or
-    indirectly &ndash; and there is no <code>TZ</code> environment
-    variable; portable applications should not, however, rely on this
-    behavior since it is not the way <a
-    href="https://en.wikipedia.org/wiki/UNIX_System_V#SVR2";><abbr>SVR2</abbr></a>
-    systems behave.)
-  </li>
-  <li>
     Negative <code>time_t</code> values are supported, on systems
     where <code>time_t</code> is signed.
   </li>
   <li>
-    These functions can account for leap seconds, thanks to Bradley White.
+    These functions can account for leap seconds;
+    see <a href="#leapsec">Leap seconds</a> below.
   </li>
 </ul>
 
@@ -1133,7 +1124,7 @@ The vestigial <abbr>API</abbr>s are:
     may now examine <code>localtime(&amp;clock)-&gt;tm_zone</code>
     (if <code>TM_ZONE</code> is defined) or
     <code>tzname[localtime(&amp;clock)-&gt;tm_isdst]</code>
-    (if <code>HAVE_TZNAME</code> is defined) to learn the correct time
+    (if <code>HAVE_TZNAME</code> is nonzero) to learn the correct time
     zone abbreviation to use.
   </li>
   <li>
@@ -1249,6 +1240,69 @@ between now and the future time.
 </section>
 
 <section>
+  <h2 id="leapsec">Leap seconds</h2>
+<p>
+The <code><abbr>tz</abbr></code> code and data can account for leap seconds,
+thanks to code contributed by Bradley White.
+However, the leap second support of this package is rarely used directly
+because POSIX requires leap seconds to be excluded and many
+software packages would mishandle leap seconds if they were present.
+Instead, leap seconds are more commonly handled by occasionally adjusting
+the operating system kernel clock as described in
+<a href="tz-link.html#precision">Precision timekeeping</a>,
+and this package by default installs a <samp>leapseconds</samp> file
+commonly used by
+<a href="http://www.ntp.org";><abbr title="Network Time Protocol">NTP</abbr></a>
+software that adjusts the kernel clock.
+However, kernel-clock twiddling approximates UTC only roughly,
+and systems needing more-precise UTC can use this package's leap
+second support directly.
+</p>
+
+<p>
+The directly-supported mechanism assumes that <code>time_t</code>
+counts of seconds since the POSIX epoch normally include leap seconds,
+as opposed to POSIX <code>time_t</code> counts which exclude leap seconds.
+This modified timescale is converted to <abbr>UTC</abbr>
+at the same point that time zone and DST adjustments are applied &ndash;
+namely, at calls to <code>localtime</code> and analogous functions &ndash;
+and the process is driven by leap second information
+stored in alternate versions of the <abbr>TZif</abbr> files.
+Because a leap second adjustment may be needed even
+if no time zone correction is desired,
+calls to <code>gmtime</code>-like functions
+also need to consult a <abbr>TZif</abbr> file,
+conventionally named <samp><abbr>GMT</abbr></samp>,
+to see whether leap second corrections are needed.
+To convert an application's <code>time_t</code> timestamps to or from
+POSIX <code>time_t</code> timestamps (for use when, say,
+embedding or interpreting timestamps in portable
+<a href="https://en.wikipedia.org/wiki/Tar_(computing)"><code>tar</code></a>
+files),
+the application can call the utility functions
+<code>time2posix</code> and <code>posix2time</code>
+included with this package.
+</p>
+
+<p>
+If the POSIX-compatible <abbr>TZif</abbr> file set is installed
+in a directory whose basename is <samp>zoneinfo</samp>, the
+leap-second-aware file set is by default installed in a separate
+directory <samp>zoneinfo-leaps</samp>.
+Although each process can have its own time zone by setting
+its <code>TZ</code> environment variable, there is no support for some
+processes being leap-second aware while other processes are
+POSIX-compatible; the leap-second choice is system-wide.
+So if you configure your kernel to count leap seconds, you should also
+discard <samp>zoneinfo</samp> and rename <samp>zoneinfo-leaps</samp>
+to <samp>zoneinfo</samp>.
+Alternatively, you can install just one set of <abbr>TZif</abbr> files
+in the first place; see the <code>REDO</code> variable in this package's
+<a href="https://en.wikipedia.org/wiki/Makefile";>makefile</a>.
+</p>
+</section>
+
+<section>
   <h2 id="calendar">Calendrical issues</h2>
 <p>
 Calendrical issues are a bit out of scope for a time zone database,

Index: src/lib/libc/time/tz-art.html
diff -u src/lib/libc/time/tz-art.html:1.5 src/lib/libc/time/tz-art.html:1.6
--- src/lib/libc/time/tz-art.html:1.5	Wed Jul  3 11:50:16 2019
+++ src/lib/libc/time/tz-art.html	Mon May 25 10:52:48 2020
@@ -458,6 +458,15 @@ Supernaw.</td></tr>
 <tr><td><a href="https://www.allmusic.com/album/youre-getting-better-the-word-jazz-dot-masters-mw0000736197";>AMG Rating</a></td><td>4.5 stars</td></tr>
 <tr><td>Notes</td><td>Includes the piece "What Time Is It"
 ("He knew what time it was everywhere...that counted").</td></tr>
+<tr><td>&nbsp;</td><td></td></tr>
+<tr><td>Artist</td><td>Chicago</td></tr>
+<tr><td>CD</td><td>Chicago Transit Authority</td></tr>
+<tr><td>Copyright Date</td><td>1969</td></tr>
+<tr><td>Label</td><td>Columbia</td></tr>
+<tr><td>ID</td><td>64409</td></tr>
+<tr><td>Total Time</td><td>1:16:20</td></tr>
+<tr><td><a href="https://www.allmusic.com/album/chicago-transit-authority-mw0000189364";>AMG Rating</a></td><td>4 stars</td></tr>
+<tr><td>Notes</td><td>Includes the song "Does Anybody Really Know What Time It Is?"</td></tr>
 </table>
 <h2>Comics</h2>
 <ul>
@@ -472,7 +481,8 @@ The webcomic <em>xkcd</em> has the strip
 "<a href='https://xkcd.com/1799/'>Bad Map Projection: Time Zones</a>"
 (2017-02-15),
 "<a href='https://xkcd.com/1883/'>Supervillain Plan</a>" (2017-08-30),
-and "<a href='https://xkcd.com/2050/'>6/6 Time</a>" (2018-09-24).
+"<a href='https://xkcd.com/2050/'>6/6 Time</a>" (2018-09-24),
+and "<a href='https://xkcd.com/2266/'>Leap Smearing</a>" (2020-02-10).
 The related book <em>What If?</em> has an entry
 "<a href='https://what-if.xkcd.com/26/'>Leap Seconds</a>" (2012-12-31).
 </li>

Index: src/lib/libc/time/tz-link.html
diff -u src/lib/libc/time/tz-link.html:1.6 src/lib/libc/time/tz-link.html:1.7
--- src/lib/libc/time/tz-link.html:1.6	Wed Jul  3 11:50:16 2019
+++ src/lib/libc/time/tz-link.html	Mon May 25 10:52:48 2020
@@ -49,6 +49,7 @@ area.
 	<ul>
 	  <li><a href="#civil">Civil time concepts and history</a></li>
 	  <li><a href="#national">National histories of legal time</a></li>
+	  <li><a href="#costs">Costs and benefits of time shifts</a></li>
 	  <li><a href="#precision">Precision timekeeping</a></li>
 	  <li><a href="#notation">Time notation</a></li>
 	  <li><a href="#see-also">See also</a></li>
@@ -81,11 +82,12 @@ title="Berkeley Software Distribution">B
 <a href="https://www.openbsd.org";>Open<abbr>BSD</abbr></a>,
 <a href="https://www.chromium.org/chromium-os";>Chromium OS</a>,
 <a href="https://cygwin.com";>Cygwin</a>,
+<a href="https://mariadb.org";>MariaDB</a>,
 <a href="https://en.wikipedia.org/wiki/MINIX";>MINIX</a>,
 <a href="https://www.mysql.com";>MySQL</a>,
 <a href="https://en.wikipedia.org/wiki/WebOS";><abbr
 title="Web Operating System">webOS</abbr></a>,
-<a href="https://ibm.com/aix";><abbr
+<a href="https://en.wikipedia.org/wiki/IBM_AIX";><abbr
 title="Advanced Interactive eXecutive">AIX</abbr></a>,
 <a href="https://en.wikipedia.org/wiki/BlackBerry_10";>BlackBerry 10</a>,
 <a href="https://www.apple.com/ios";><abbr
@@ -167,7 +169,8 @@ then <samp>za</samp> through <samp>zz</s
 through <samp>zzz</samp>, and so on).
 Since version 2016h, each release has contained a text file named
 "<samp>version</samp>" whose first (and currently only) line is the version.
-The releases are also available in an
+Older releases are <a href="https://ftp.iana.org/tz/releases/";>archived</a>,
+and are also available in an
 <a href="ftp://ftp.iana.org/tz/releases/";><abbr
 title="File Transfer Protocol">FTP</abbr> directory</a> via a
 less-secure protocol.</p>
@@ -268,7 +271,8 @@ For further information about updates, p
 <a href="https://tools.ietf.org/html/rfc6557";>Procedures for
 Maintaining the Time Zone Database</a> (Internet <abbr
 title="Request For Comments">RFC</abbr> 6557). More detail can be
-found in <a href="theory.html">Theory and pragmatics of the tz code and data</a>.
+found in <a href="theory.html">Theory and pragmatics of the
+<code><abbr>tz</abbr></code> code and data</a>.
 <a href="https://a0.github.io/a0-tzmigration/";>A0 TimeZone Migration</a>
 displays changes between recent <code><abbr>tzdb</abbr></code> versions.
 </p>
@@ -301,7 +305,7 @@ These are listed roughly in ascending or
 time and zones.</li>
 <li><a href="https://www.timejones.com";>TimeJones.com</a>,
 <a href="https://timezoneconverterapp.com";>Time Zone Converter</a> and
-<a href="https://worldclock.com";>The World Clock</a>
+<a href="https://www.worldclock.com";>The World Clock</a>
 are time zone converters.</li>
 <li><a
 href="https://twiki.org/cgi-bin/xtra/tzdatepick.html";>Date and Time Gateway</a>
@@ -311,7 +315,7 @@ href="http://www.convertit.com/Go/Conver
 Time in 1000 Places</a> uses descriptions of the values.</li>
 <li><a href="https://timezoneconverterapp.com/";>Time Zone Converter</a>
 uses a pulldown menu.</li>
-<li><a href="http://home.kpn.nl/vanadovv/time/TZworld.html";>Complete
+<li><a href="https://home.kpn.nl/vanadovv/time/TZworld.html";>Complete
 timezone information for all countries</a> displays tables of DST rules.
 <li><a href="https://www.timeanddate.com/worldclock/";>The World Clock &ndash;
 Worldwide</a> lets you sort zone names and convert times.</li>
@@ -361,6 +365,11 @@ title="JavaScript Object Notation">JSON<
 
 <section>
 <h2 id="compilers">Other <code><abbr>tz</abbr></code> compilers</h2>
+<p>Although some of these do not fully support
+<code><abbr>tz</abbr></code> data, in recent <code><abbr>tzdb</abbr></code>
+distributions you can generally work around compatibility problems by
+running the command <code>make rearguard_tarballs</code> and compiling
+from the resulting tarballs instead.</p>
 <ul>
 <li><a href="https://sourceforge.net/projects/vzic/";>Vzic</a> is a <a
 href="https://en.wikipedia.org/wiki/C_%28programming_language%29";>C</a>
@@ -389,9 +398,9 @@ transition in the <code><abbr>tz</abbr><
 <li>The <a href="https://howardhinnant.github.io/date/tz.html";>Time Zone
 Database Parser</a> is a
 <a href="https://en.wikipedia.org/wiki/C%2B%2B";>C++</a> parser and
-runtime library that is <a
-href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0355r4.html";>moving
-forward</a> for inclusion in
+runtime library with API <a
+href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0355r7.html";>adopted
+into the draft standard</a> for
 <a href="https://en.wikipedia.org/wiki/C++20";>C++20</a>,
 the next iteration of the C++ standard.
 It is freely available under the
@@ -408,7 +417,7 @@ into an <abbr>ICU</abbr>-specific format
 <abbr>BSD</abbr>-style license.</li>
 <li>The <a href="https://github.com/lau/tzdata";>Tzdata</a> package for
 the <a href="https://elixir-lang.org";>Elixir</a> language downloads
-and compiles tz source and exposes <abbr
+and compiles <code><abbr>tz</abbr></code> source and exposes <abbr
 title="Application Program Interface">API</abbr>s for use. It is
 freely available under the <abbr>MIT</abbr> license.</li>
 <li>Java-based compilers and libraries include:
@@ -429,6 +438,11 @@ and time <abbr>API</abbr></a> contains a
 Java 8 <code>java.time</code>, which its users should migrate to once
 they can assume Java 8 or later. It is available under the <a
 href="https://www.apache.org/licenses/LICENSE-2.0";>Apache License</a>.</li>
+<li><a href="https://bell-sw.com/pages/iana-updater/";>IANA Updater</a>,
+<a href="https://github.com/akashche/tzdbgen";>tzdbgen</a>, and <a
+href="https://www.azul.com/products/open-source-tools/ziupdater-time-zone-tool/";>ZIUpdater</a>
+are other alternatives to TZUpdater. IANA Updater's license is unclear;
+the others are licensed under the <abbr>GPL</abbr>.</li>
 <li><a href="https://github.com/MenoData/Time4A";>Time4A: Advanced date and
 time library for Android</a> and
 <a href="https://github.com/MenoData/Time4J/";>Time4J: Advanced date,
@@ -738,7 +752,7 @@ coordinates?</a>" discusses other geoloc
 <li><a href="http://statoids.com/statoids.html";>Administrative
 Divisions of Countries ("Statoids")</a> lists
 political subdivision data related to time zones.</li>
-<li><a href="http://home.kpn.nl/vanadovv/time/Multizones.html";>Time
+<li><a href="https://home.kpn.nl/vanadovv/time/Multizones.html";>Time
 zone boundaries for multizone countries</a> summarizes legal
 boundaries between time zones within countries.</li>
 <li><a href="http://manifold.net/info/freestuff.shtml";>Manifold Software
@@ -793,9 +807,12 @@ The Bureau of Meteorology publishes a li
 href="http://www.bom.gov.au/climate/averages/tables/dst_times.shtml";>Implementation
 Dates of Daylight Savings Time within Australia</a>.</dd>
 <dt>Belgium</dt>
-<dd>The Royal Observatory of Belgium maintains a table of <a
-href="https://www.astro.oma.be/GENERAL/INFO/nli001a.html";
-hreflang="nl">time in Belgium (in Dutch)</a>.</dd>
+<dd>The Royal Observatory of Belgium maintains a table of time in
+Belgium (in
+<a href="https://www.astro.oma.be/GENERAL/INFO/nli001a.html";
+hreflang="nl">Dutch</a> and <a
+href="https://www.astro.oma.be/GENERAL/INFO/fri001a.html";
+hreflang="fr">French</a>).</dd>
 <dt>Brazil</dt>
 <dd>The Time Service Department of the National Observatory
 records <a href="http://pcdsh01.on.br/DecHV.html";
@@ -812,10 +829,10 @@ zones and daylight saving time</a>.</dd>
 Chile's official time (in Spanish)</a>.</dd>
 <dt>China</dt>
 <dd>The Hong Kong Observatory maintains a
-<a href="https://www.hko.gov.hk/gts/time/Summertime.htm";>history of
+<a href="https://www.hko.gov.hk/en/gts/time/Summertime.htm";>history of
  summer time in Hong Kong</a>,
 and Macau's Meteorological and Geophysical Bureau maintains a <a
-href="http://www.smg.gov.mo/smg/geophysics/e_t_Summer%20Time.htm";>similar
+href="https://www.smg.gov.mo/en/subpage/224/page/174";>similar
 history for Macau</a>.
 Unfortunately the latter is incomplete and has errors.</dd>
 <dt>Czech Republic</dt>
@@ -851,7 +868,7 @@ href="https://www.dia.govt.nz/Daylight-S
 Daylight Saving</a>.</dd>
 <dt>Singapore</dt>
 <dd><a id="Singapore"
-href="http://www.math.nus.edu.sg/~mathelmr/teaching/timezone.html";>Why
+href="https://web.archive.org/web/20190822231045/http://www.math.nus.edu.sg/~mathelmr/teaching/timezone.html";>Why
 is Singapore in the "Wrong" Time Zone?</a> details the
 history of legal time in Singapore and Malaysia.</dd>
 <dt>United Kingdom</dt>
@@ -866,12 +883,46 @@ Time Zone Proceedings</a> lists changes 
 <dt>Uruguay</dt>
 <dd>The Oceanography, Hydrography, and Meteorology Service of the Uruguayan
 Navy (SOHMA) publishes an annual <a
-href="http://www.armada.gub.uy/sohma/index.php/servicios/datos-astronomicos"; hreflang="es">almanac
+href="http://sohma.armada.mil.uy/index.php/servicios/datos-astronomicos"; hreflang="es">almanac
 (in Spanish)</a>.</dd>
 </dl>
 </section>
 
 <section>
+<h2 id="costs">Costs and benefits of time shifts</h2>
+<p>Various sources argue for and against daylight saving time and time
+zone shifts, and many scientific studies have been conducted. This
+section summarizes reviews of scientific literature in the area.</p>
+<ul>
+<li>Carey RN, Sarma KM.
+<a href="https://bmjopen.bmj.com/content/7/6/e014319.long";>Impact of
+daylight saving time on road traffic collision risk: a systematic
+review</a>.
+<em>BMJ Open.</em> 2017;7(6):e014319. doi:<a href="https://doi.org/10.1136/bmjopen-2016-014319";>10.1136/bmjopen-2016-014319</a>.
+This reviews research literature and concludes that the evidence
+neither supports nor refutes road safety benefits from
+shifts in time zones.</li>
+<li>Havranek T, Herman D, Irsova D.
+<a href="https://www.econstor.eu/handle/10419/174191";>Does daylight
+saving save electricity? A meta-analysis</a>. <em>Energy J.</em>
+2018;39(2).
+doi:<a href="https://doi.org/10.5547/01956574.39.2.thav";>10.5547/01956574.39.2.thav</a>.
+This analyzes research literature and concludes, "Electricity savings
+are larger for countries farther away from the equator, while
+subtropical regions consume more electricity because of DST."</li>
+<li>Roenneberg T, Winnebeck EC, Klerman EB.
+<a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6692659/";>Daylight
+saving time and artificial time zones &ndash; a battle between
+biological and social times</a>. <em>Front Physiol.</em> 2019;10:944.
+doi:<a href="https://doi.org/10.3389/fphys.2019.00944";>10.3389/fphys.2019.00944</a>.
+This reviews evidence about the health effects of DST and concludes,
+"In summary, the scientific literature strongly argues against the
+switching between DST and Standard Time and even more so against
+adopting DST permanently."</li>
+</ul>
+</section>
+
+<section>
 <h2 id="precision">Precision timekeeping</h2>
 <ul>
 <li><a
@@ -929,6 +980,10 @@ scales used by each landed mission on Ma
 dedicated not only to leap seconds but to precise time and frequency
 in general. It covers the state of the art in amateur timekeeping, and
 how the art has progressed over the past few decades.</li>
+<li>The rules for leap seconds are specified in Annex 1 (Time scales) of <a
+href="https://www.itu.int/rec/R-REC-TF.460-6-200202-I/";>Standard-frequency
+and time-signal emissions</a>, International Telecommunication Union &ndash;
+Radiocommunication Sector (ITU-R) Recommendation TF.460-6 (02/2002).</li>
 <li><a
 href="https://www.iers.org/IERS/EN/Publications/Bulletins/bulletins.html";><abbr
 title="International Earth Rotation and Reference Systems Service">IERS</abbr>
@@ -945,7 +1000,12 @@ sixty seconds. This approach works with 
 "<code>posix</code>" configuration, is <a
 href="http://bk1.ntp.org/ntp-stable/README.leapsmear";>supported</a> by
 the <abbr>NTP</abbr> reference implementation, and is used by major
-cloud service providers.</li>
+cloud service providers. However, according to
+<a href="https://tools.ietf.org/html/rfc8633#section-3.7.1";>&sect;3.7.1 of
+Network Time Protocol Best Current Practices</a>
+(Internet <abbr>RFC</abbr> 8633), leap smearing is not suitable for
+applications requiring accurate UTC or civil time,
+and is intended for use only in single, well-controlled environments.</li>
 <li>The <a
 href="https://pairlist6.pair.net/mailman/listinfo/leapsecs";>Leap
 Second Discussion List</a> covers <a
@@ -999,7 +1059,7 @@ specifies an <abbr>ISO</abbr> 8601
 profile for use in new Internet
 protocols.</li>
 <li>
-<a href="https://www.hackcraft.net/web/datetime/";>Date &amp; Time
+<a href="https://web.archive.org/web/20190130042457/https://www.hackcraft.net/web/datetime/";>Date &amp; Time
 Formats on the Web</a> surveys web- and Internet-oriented date and time
 formats.</li>
 <li>Alphabetic time zone abbreviations should not be used as unique
@@ -1036,7 +1096,8 @@ is called "<abbr>GMT</abbr>".</li>
 <section>
 <h2 id="see-also">See also</h2>
 <ul>
-<li><a href="theory.html">Theory and pragmatics of the tz code and data</a></li>
+<li><a href="theory.html">Theory and pragmatics of the
+<code><abbr>tz</abbr></code> code and data</a></li>
 <li><a href="tz-art.html">Time and the Arts</a></li>
 </ul>
 </section>

Index: src/lib/libc/time/version
diff -u src/lib/libc/time/version:1.12 src/lib/libc/time/version:1.13
--- src/lib/libc/time/version:1.12	Wed Jul  3 11:50:16 2019
+++ src/lib/libc/time/version	Mon May 25 10:52:48 2020
@@ -1 +1 @@
-2019b
+2020a

Index: src/lib/libc/time/zdump.8
diff -u src/lib/libc/time/zdump.8:1.19 src/lib/libc/time/zdump.8:1.20
--- src/lib/libc/time/zdump.8:1.19	Sat Oct 27 18:29:24 2018
+++ src/lib/libc/time/zdump.8	Mon May 25 10:52:48 2020
@@ -1,5 +1,5 @@
-.\"	$NetBSD: zdump.8,v 1.19 2018/10/27 22:29:24 christos Exp $
-.Dd October 27, 2018
+.\"	$NetBSD: zdump.8,v 1.20 2020/05/25 14:52:48 christos Exp $
+.Dd May 25, 2020
 .Dt ZDUMP 8
 .Os
 .Sh NAME
@@ -64,11 +64,11 @@ seconds east of Greenwich.
 Cut off interval output at the given year(s).
 Cutoff times are computed using the proleptic Gregorian calendar with year 0
 and with Universal Time (UT) ignoring leap seconds.
-The lower bound is exclusive and the upper is inclusive; for example, a
-.Em loyear
-of 1970 excludes a transition occurring at 1970-01-01 00:00:00 UTC but a
-.Em hiyear
-of 1970 includes the transition.
+Cutoffs are at the start of each year, where the lower-bound
+timestamp is exclusive and the upper is inclusive; for example,
+.Em "\&-c 1970,2070"
+selects transitions after 1970-01-01 00:00:00 UTC
+and on or before 2070-01-01 00:00:00 UTC.
 The default cutoff is
 .Em \&-500,2500 .
 .It Fl t Ar [lotime,]hightime

Index: src/lib/libc/time/zdump.c
diff -u src/lib/libc/time/zdump.c:1.52 src/lib/libc/time/zdump.c:1.53
--- src/lib/libc/time/zdump.c:1.52	Sat Jan 26 21:08:35 2019
+++ src/lib/libc/time/zdump.c	Mon May 25 10:52:48 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: zdump.c,v 1.52 2019/01/27 02:08:35 pgoyette Exp $	*/
+/*	$NetBSD: zdump.c,v 1.53 2020/05/25 14:52:48 christos Exp $	*/
 /* Dump time zone data in a textual format.  */
 
 /*
@@ -8,7 +8,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: zdump.c,v 1.52 2019/01/27 02:08:35 pgoyette Exp $");
+__RCSID("$NetBSD: zdump.c,v 1.53 2020/05/25 14:52:48 christos Exp $");
 #endif /* !defined lint */
 
 #ifndef NETBSD_INSPIRED
@@ -330,12 +330,12 @@ abbrok(const char *const abbrp, const ch
 	cp = abbrp;
 	while (is_alpha(*cp) || is_digit(*cp) || *cp == '-' || *cp == '+')
 		++cp;
-	if (cp - abbrp < 3)
+	if (*cp)
+		wp = _("has characters other than ASCII alphanumerics, '-' or '+'");
+	else if (cp - abbrp < 3)
 		wp = _("has fewer than 3 characters");
 	else if (cp - abbrp > 6)
 		wp = _("has more than 6 characters");
-	else if (*cp)
-		wp = _("has characters other than ASCII alphanumerics, '-' or '+'");
 	else
 		return;
 	(void) fflush(stdout);

Index: src/lib/libc/time/zic.8
diff -u src/lib/libc/time/zic.8:1.33 src/lib/libc/time/zic.8:1.34
--- src/lib/libc/time/zic.8:1.33	Wed Jul  3 11:50:16 2019
+++ src/lib/libc/time/zic.8	Mon May 25 10:52:48 2020
@@ -1,5 +1,5 @@
-.\"	$NetBSD: zic.8,v 1.33 2019/07/03 15:50:16 christos Exp $
-.Dd July 2, 2019
+.\"	$NetBSD: zic.8,v 1.34 2020/05/25 14:52:48 christos Exp $
+.Dd May 25, 2020
 .Dt ZIC 8
 .Os
 .Sh NAME
@@ -92,7 +92,7 @@ and it should not be combined with
 .Fl b Ar slim
 if
 .Va timezone's
-transitions are at standard time or UT instead of local time.
+transitions are at standard time or Universal Time (UT) instead of local time.
 .It Fl r Op Ar @lo / Op Ar @hi
 Reduce the size of output files by limiting their applicability
 to timestamps in the range from
@@ -587,7 +587,9 @@ However, the behavior is unspecified if 
 define the same name, or if the source of one link line is the target
 of another.
 .Pp
-Lines in the file that describes leap seconds have the following form:
+The file that describes leap seconds can have leap lines and an
+expiration line.
+Leap lines have the following form:
 .Pp
 .Dl Leap	YEAR	MONTH	DAY	HH:MM:SS	CORR	R/S
 .Pp
@@ -622,6 +624,38 @@ or
 .Qq Rolling
 if the leap second time given by the other fields should be interpreted as
 local (wall clock) time.
+.Pp
+The expiration line, if present, has the form:
+.Pp
+.Dl Expires	YEAR	MONTH	DAY	HH:MM:SS
+.Pp
+For example:
+.Pp
+.Dl Expires	2020	Dec		28	00:00:00
+.Pp
+The
+.Em YEAR ,
+.Em MONTH ,
+.Em DAY ,
+and
+.Em HH:MM:SS
+fields give the expiration timestamp in UTC for the leap second table;
+.Nm
+outputs this expiration timestamp by truncating the end of the output
+file to the timestamp.
+If there is no expiration line,
+.Nm
+also accepts a comment
+.Qq "#expires \fIE\fP ...\&"
+where
+.Em E
+is the expiration timestamp as a decimal integer count of seconds
+since the Epoch, not counting leap seconds.
+However, the
+.Qq "#expires"
+comment is an obsolescent feature,
+and the leap second file should use an expiration line
+instead of relying on a comment.
 .Sh EXTENDED EXAMPLE
 Here is an extended example of
 .Ic zic

Index: src/lib/libc/time/zic.c
diff -u src/lib/libc/time/zic.c:1.75 src/lib/libc/time/zic.c:1.76
--- src/lib/libc/time/zic.c:1.75	Wed Jul  3 11:50:16 2019
+++ src/lib/libc/time/zic.c	Mon May 25 10:52:48 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: zic.c,v 1.75 2019/07/03 15:50:16 christos Exp $	*/
+/*	$NetBSD: zic.c,v 1.76 2020/05/25 14:52:48 christos Exp $	*/
 /*
 ** This file is in the public domain, so clarified as of
 ** 2006-07-17 by Arthur David Olson.
@@ -11,7 +11,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: zic.c,v 1.75 2019/07/03 15:50:16 christos Exp $");
+__RCSID("$NetBSD: zic.c,v 1.76 2020/05/25 14:52:48 christos Exp $");
 #endif /* !defined lint */
 
 #include "private.h"
@@ -163,13 +163,14 @@ extern int	optind;
 
 static void	addtt(zic_t starttime, int type);
 static int	addtype(zic_t, char const *, bool, bool, bool);
-static void	leapadd(zic_t, bool, int, int);
+static void	leapadd(zic_t, int, int);
 static void	adjleap(void);
 static void	associate(void);
 static void	dolink(const char *, const char *, bool);
 static char **	getfields(char * buf);
 static zic_t	gethms(const char * string, const char * errstring);
 static zic_t	getsave(char *, bool *);
+static void	inexpires(char **, int);
 static void	infile(const char * filename);
 static void	inleap(char ** fields, int nfields);
 static void	inlink(char ** fields, int nfields);
@@ -234,6 +235,7 @@ static int		typecnt;
 #define LC_ZONE		1
 #define LC_LINK		2
 #define LC_LEAP		3
+#define LC_EXPIRES	4
 
 /*
 ** Which fields are which on a Zone line.
@@ -299,6 +301,9 @@ static int		typecnt;
 #define LP_ROLL		6
 #define LEAP_FIELDS	7
 
+/* Expires lines are like Leap lines, except without CORR and ROLL fields.  */
+#define EXPIRES_FIELDS	5
+
 /*
 ** Year synonyms.
 */
@@ -342,6 +347,7 @@ static struct lookup const zi_line_codes
 };
 static struct lookup const leap_line_codes[] = {
 	{ "Leap",	LC_LEAP },
+	{ "Expires",	LC_EXPIRES },
 	{ NULL,		0}
 };
 
@@ -624,6 +630,12 @@ static zic_t const max_time = MAXVAL(zic
 static zic_t lo_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
 static zic_t hi_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
 
+/* The time specified by an Expires line, or negative if no such line.  */
+static zic_t leapexpires = -1;
+
+/* The time specified by an #expires comment, or negative if no such line.  */
+static zic_t comment_leapexpires = -1;
+
 /* Set the time range of the output to TIMERANGE.
    Return true if successful.  */
 static bool
@@ -1217,7 +1229,8 @@ infile(const char *name)
 			++nfields;
 		}
 		if (nfields == 0) {
-			/* nothing to do */
+		  if (name == leapsec && *buf == '#')
+		    sscanf(buf, "#expires %"SCNdZIC, &comment_leapexpires);
 		} else if (wantcont) {
 			wantcont = inzcont(fields, nfields);
 		} else {
@@ -1242,6 +1255,10 @@ infile(const char *name)
 					inleap(fields, nfields);
 					wantcont = false;
 					break;
+				case LC_EXPIRES:
+					inexpires(fields, nfields);
+					wantcont = false;
+					break;
 				default:	/* "cannot happen" */
 					fprintf(stderr,
 _("%s: panic: Invalid l_value %d\n"),
@@ -1499,8 +1516,8 @@ inzsub(char **fields, int nfields, bool 
 	return hasuntil;
 }
 
-static void
-inleap(char **fields, int nfields)
+static zic_t
+getleapdatetime(char **fields, int nfields, bool expire_line)
 {
 	const char *		cp;
 	const struct lookup *	lp;
@@ -1511,10 +1528,6 @@ inleap(char **fields, int nfields)
 	zic_t			t;
 	char			xs;
 
-	if (nfields != LEAP_FIELDS) {
-		error(_("wrong number of fields on Leap line"));
-		return;
-	}
 	dayoff = 0;
 	cp = fields[LP_YEAR];
 	if (sscanf(cp, "%"SCNdZIC"%c", &year, &xs) != 1) {
@@ -1522,13 +1535,15 @@ inleap(char **fields, int nfields)
 		** Leapin' Lizards!
 		*/
 		error(_("invalid leaping year"));
-		return;
+		return -1;
 	}
-	if (!leapseen || leapmaxyear < year)
+	if (!expire_line) {
+	    if (!leapseen || leapmaxyear < year)
 		leapmaxyear = year;
-	if (!leapseen || leapminyear > year)
+	    if (!leapseen || leapminyear > year)
 		leapminyear = year;
-	leapseen = true;
+	    leapseen = true;
+	}
 	j = EPOCH_YEAR;
 	while (j != year) {
 		if (year > j) {
@@ -1542,7 +1557,7 @@ inleap(char **fields, int nfields)
 	}
 	if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) {
 		error(_("invalid month name"));
-		return;
+		return -1;
 	}
 	month = lp->l_value;
 	j = TM_JANUARY;
@@ -1555,47 +1570,60 @@ inleap(char **fields, int nfields)
 	if (sscanf(cp, "%d%c", &day, &xs) != 1 ||
 		day <= 0 || day > len_months[isleap(year)][month]) {
 			error(_("invalid day of month"));
-			return;
+			return -1;
 	}
 	dayoff = oadd(dayoff, day - 1);
 	if (dayoff < min_time / SECSPERDAY) {
 		error(_("time too small"));
-		return;
+		return -1;
 	}
 	if (dayoff > max_time / SECSPERDAY) {
 		error(_("time too large"));
-		return;
+		return -1;
 	}
 	t = dayoff * SECSPERDAY;
 	tod = gethms(fields[LP_TIME], _("invalid time of day"));
-	cp = fields[LP_CORR];
-	{
-		bool	positive;
-		int	count;
+	t = tadd(t, tod);
+	if (t < 0)
+	  error(_("leap second precedes Epoch"));
+	return t;
+}
 
-		if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */
-			positive = false;
-			count = 1;
-		} else if (strcmp(cp, "+") == 0) {
-			positive = true;
-			count = 1;
-		} else {
-			error(_("illegal CORRECTION field on Leap line"));
-			return;
-		}
-		if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) {
-			error(_(
-				"illegal Rolling/Stationary field on Leap line"
-				));
-			return;
-		}
-		t = tadd(t, tod);
-		if (t < 0) {
-			error(_("leap second precedes Epoch"));
-			return;
-		}
-		leapadd(t, positive, lp->l_value, count);
-	}
+static void
+inleap(char **fields, int nfields)
+{
+  if (nfields != LEAP_FIELDS)
+    error(_("wrong number of fields on Leap line"));
+  else {
+    zic_t t = getleapdatetime(fields, nfields, false);
+    if (0 <= t) {
+      struct lookup const *lp = byword(fields[LP_ROLL], leap_types);
+      if (!lp)
+	error(_("invalid Rolling/Stationary field on Leap line"));
+      else {
+	int correction = 0;
+	if (!fields[LP_CORR][0]) /* infile() turns "-" into "".  */
+	  correction = -1;
+	else if (strcmp(fields[LP_CORR], "+") == 0)
+	  correction = 1;
+	else
+	  error(_("invalid CORRECTION field on Leap line"));
+	if (correction)
+	  leapadd(t, correction, lp->l_value);
+      }
+    }
+  }
+}
+
+static void
+inexpires(char **fields, int nfields)
+{
+  if (nfields != EXPIRES_FIELDS)
+    error(_("wrong number of fields on Expires line"));
+  else if (0 <= leapexpires)
+    error(_("multiple Expires lines"));
+  else
+    leapexpires = getleapdatetime(fields, nfields, true);
 }
 
 static void
@@ -2156,7 +2184,7 @@ writezone(const char *const name, const 
 		}
 		if (pass == 1 && !want_bloat()) {
 		  utcnt = stdcnt = thisleapcnt = 0;
-		  thistimecnt = - locut - hicut;
+		  thistimecnt = - (locut + hicut);
 		  thistypecnt = thischarcnt = 1;
 		  thistimelim = thistimei;
 		}
@@ -2987,28 +3015,24 @@ addtype(zic_t utoff, char const *abbr, b
 }
 
 static void
-leapadd(zic_t t, bool positive, int rolling, int count)
+leapadd(zic_t t, int correction, int rolling)
 {
-	int	i, j;
+	int	i;
 
-	if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) {
+	if (TZ_MAX_LEAPS <= leapcnt) {
 		error(_("too many leap seconds"));
 		exit(EXIT_FAILURE);
 	}
 	for (i = 0; i < leapcnt; ++i)
 		if (t <= trans[i])
 			break;
-	do {
-		for (j = leapcnt; j > i; --j) {
-			trans[j] = trans[j - 1];
-			corr[j] = corr[j - 1];
-			roll[j] = roll[j - 1];
-		}
-		trans[i] = t;
-		corr[i] = positive ? 1 : -count;
-		roll[i] = rolling;
-		++leapcnt;
-	} while (positive && --count != 0);
+	memmove(&trans[i + 1], &trans[i], (leapcnt - i) * sizeof *trans);
+	memmove(&corr[i + 1], &corr[i], (leapcnt - i) * sizeof *corr);
+	memmove(&roll[i + 1], &roll[i], (leapcnt - i) * sizeof *roll);
+	trans[i] = t;
+	corr[i] = correction;
+	roll[i] = rolling;
+	++leapcnt;
 }
 
 static void
@@ -3030,6 +3054,22 @@ adjleap(void)
 		trans[i] = tadd(trans[i], last);
 		last = corr[i] += last;
 	}
+
+	if (leapexpires < 0) {
+	  leapexpires = comment_leapexpires;
+	  if (0 <= leapexpires)
+	    warning(_("\"#expires\" is obsolescent; use \"Expires\""));
+	}
+
+	if (0 <= leapexpires) {
+	  leapexpires = oadd(leapexpires, last);
+	  if (! (leapcnt == 0 || (trans[leapcnt - 1] < leapexpires))) {
+	    error(_("last Leap time does not precede Expires time"));
+	    exit(EXIT_FAILURE);
+	  }
+	  if (leapexpires <= hi_time)
+	    hi_time = leapexpires - 1;
+	}
 }
 
 static char *

Reply via email to