Module Name: src
Committed By: christos
Date: Fri Oct 7 15:29:42 UTC 2016
Modified Files:
src/lib/libc/time: Makefile NEWS README Theory localtime.c private.h
strftime.c tz-art.htm tz-how-to.html tz-link.htm tzfile.5 tzset.3
zdump.8 zdump.c zic.c
Log Message:
merge tzcode2016g
To generate a diff of this commit:
cvs rdiff -u -r1.33 -r1.34 src/lib/libc/time/Makefile
cvs rdiff -u -r1.16 -r1.17 src/lib/libc/time/NEWS
cvs rdiff -u -r1.10 -r1.11 src/lib/libc/time/README
cvs rdiff -u -r1.20 -r1.21 src/lib/libc/time/Theory
cvs rdiff -u -r1.103 -r1.104 src/lib/libc/time/localtime.c
cvs rdiff -u -r1.45 -r1.46 src/lib/libc/time/private.h
cvs rdiff -u -r1.36 -r1.37 src/lib/libc/time/strftime.c
cvs rdiff -u -r1.13 -r1.14 src/lib/libc/time/tz-art.htm
cvs rdiff -u -r1.1 -r1.2 src/lib/libc/time/tz-how-to.html
cvs rdiff -u -r1.26 -r1.27 src/lib/libc/time/tz-link.htm
cvs rdiff -u -r1.23 -r1.24 src/lib/libc/time/tzfile.5
cvs rdiff -u -r1.34 -r1.35 src/lib/libc/time/tzset.3
cvs rdiff -u -r1.14 -r1.15 src/lib/libc/time/zdump.8
cvs rdiff -u -r1.43 -r1.44 src/lib/libc/time/zdump.c
cvs rdiff -u -r1.62 -r1.63 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.33 src/lib/libc/time/Makefile:1.34
--- src/lib/libc/time/Makefile:1.33 Fri Sep 16 13:12:06 2016
+++ src/lib/libc/time/Makefile Fri Oct 7 11:29:42 2016
@@ -4,8 +4,8 @@
# Package name for the code distribution.
PACKAGE= tzcode
-# Version numbers of the code and data distributions.
-VERSION= 2016f
+# Version number for the distribution, overridden in the 'tarballs' rule below.
+VERSION= 2016g
# Email address for bug reports.
BUGEMAIL= [email protected]
@@ -241,7 +241,7 @@ GCC_DEBUG_FLAGS = -Dlint -g3 -O3 -fno-co
CFLAGS=
# Linker flags. Default to $(LFLAGS) for backwards compatibility
-# to tzcode2012h and earlier.
+# to release 2012h and earlier.
LDFLAGS= $(LFLAGS)
@@ -257,7 +257,7 @@ ZIC= $(zic) $(ZFLAGS)
ZFLAGS=
-# How to use zic to install tzdata binary files.
+# How to use zic to install tz binary files.
ZIC_INSTALL= $(ZIC) -y $(YEARISTYPE) -d $(DESTDIR)$(TZDIR) $(LEAPSECONDS)
@@ -273,16 +273,16 @@ AWK= awk
KSHELL= /bin/bash
# The path where SGML DTDs are kept and the catalog file(s) to use when
-# validating. The default is appropriate for Ubuntu 13.10.
+# validating. The default should work on both Debian and Red Hat.
SGML_TOPDIR= /usr
SGML_DTDDIR= $(SGML_TOPDIR)/share/xml/w3c-sgml-lib/schema/dtd
SGML_SEARCH_PATH= $(SGML_DTDDIR)/REC-html401-19991224
SGML_CATALOG_FILES= \
- $(SGML_TOPDIR)/share/doc/w3-recs/html/www.w3.org/TR/1999/REC-html401-19991224/HTML4.cat
+ $(SGML_TOPDIR)/share/doc/w3-recs/html/www.w3.org/TR/1999/REC-html401-19991224/HTML4.cat:$(SGML_TOPDIR)/share/sgml/html/4.01/HTML4.cat
# The name, arguments and environment of a program to validate your web pages.
-# See <http://www.jclark.com/sp/> for a validator, and
-# <http://validator.w3.org/source/> for a validation library.
+# See <http://openjade.sourceforge.net/doc/> for a validator, and
+# <https://validator.w3.org/source/> for a validation library.
VALIDATE = nsgmls
VALIDATE_FLAGS = -s -B -wall -wno-unused-param
VALIDATE_ENV = \
@@ -327,7 +327,7 @@ OK_LINE= '^'$(OK_CHAR)'*$$'
# Flags to give 'tar' when making a distribution.
# Try to use flags appropriate for GNU tar.
-GNUTARFLAGS= --numeric-owner --owner=0 --group=0 --mode=go+u,go-w
+GNUTARFLAGS= --numeric-owner --owner=0 --group=0 --mode=go+u,go-w --sort=name
TARFLAGS= `if tar $(GNUTARFLAGS) --version >/dev/null 2>&1; \
then echo $(GNUTARFLAGS); \
else :; \
@@ -357,7 +357,7 @@ HEADERS= tzfile.h private.h
NONLIBSRCS= zic.c zdump.c
NEWUCBSRCS= date.c strftime.c
SOURCES= $(HEADERS) $(LIBSRCS) $(NONLIBSRCS) $(NEWUCBSRCS) \
- tzselect.ksh workman.sh
+ tzselect.ksh version workman.sh
MANS= newctime.3 newstrftime.3 newtzset.3 time2posix.3 \
tzfile.5 tzselect.8 zic.8 zdump.8
MANTXTS= newctime.3.txt newstrftime.3.txt newtzset.3.txt \
@@ -379,7 +379,32 @@ DATA= $(YDATA) $(NDATA) backzone $(TABD
leap-seconds.list yearistype.sh
AWK_SCRIPTS= checklinks.awk checktab.awk leapseconds.awk
MISC= $(AWK_SCRIPTS) zoneinfo2tdf.pl
-ENCHILADA= $(COMMON) $(DOCS) $(SOURCES) $(DATA) $(MISC)
+TZS_YEAR= 2050
+TZS= to$(TZS_YEAR).tzs
+TZS_NEW= to$(TZS_YEAR)new.tzs
+TZS_DEPS= $(PRIMARY_YDATA) asctime.c localtime.c \
+ private.h tzfile.h zdump.c zic.c
+ENCHILADA= $(COMMON) $(DOCS) $(SOURCES) $(DATA) $(MISC) $(TZS)
+
+# Consult these files when deciding whether to rebuild the 'version' file.
+# This list is not the same as the output of 'git ls-files', since
+# .gitignore is not distributed.
+VERSION_DEPS= \
+ CONTRIBUTING LICENSE Makefile NEWS README Theory \
+ africa antarctica asctime.c asia australasia \
+ backward backzone \
+ checklinks.awk checktab.awk \
+ date.1 date.c difftime.c \
+ etcetera europe factory iso3166.tab \
+ leap-seconds.list leapseconds.awk localtime.c \
+ newctime.3 newstrftime.3 newtzset.3 northamerica \
+ pacificnew private.h \
+ southamerica strftime.c systemv \
+ time2posix.3 tz-art.htm tz-how-to.html tz-link.htm \
+ tzfile.5 tzfile.h tzselect.8 tzselect.ksh \
+ workman.sh yearistype.sh \
+ zdump.8 zdump.c zic.8 zic.c \
+ zone.tab zone1970.tab zoneinfo2tdf.pl
# And for the benefit of csh users on systems that assume the user
# shell should be used to handle commands in Makefiles. . .
@@ -409,9 +434,16 @@ INSTALL: ALL install date.1
cp date $(DESTDIR)$(BINDIR)/.
cp -f date.1 $(DESTDIR)$(MANDIR)/man1/.
-version.h:
+version: $(VERSION_DEPS)
+ { V=$$(git describe --match '[0-9][0-9][0-9][0-9][a-z]*' \
+ --abbrev=7 --dirty) || \
+ V=$(VERSION); } && \
+ printf '%s\n' "$$V" >$@
+
+version.h: version
(echo 'static char const PKGVERSION[]="($(PACKAGE)) ";' && \
- echo 'static char const TZVERSION[]="$(VERSION)";' && \
+ printf 'static char const TZVERSION[]="%s";\n' \
+ "$$(cat version)" && \
echo 'static char const REPORT_BUGS_TO[]="$(BUGEMAIL)";') >$@
zdump: $(TZDOBJS)
@@ -478,6 +510,27 @@ posix_packrat:
zones: $(REDO)
+$(TZS_NEW): $(TDATA) zdump zic
+ mkdir -p tzs.dir
+ $(zic) -d tzs.dir $(TDATA)
+ $(AWK) '/^Link/{print $$1 "\t" $$2 "\t" $$3}' \
+ $(TDATA) | LC_ALL=C sort >[email protected]
+ zones=$$($(AWK) -v wd="$$(pwd)" \
+ '/^Zone/{print wd "/tzs.dir/" $$2}' $(TDATA) \
+ | LC_ALL=C sort) && \
+ ./zdump -i -c $(TZS_YEAR) $$zones >>[email protected]
+ sed 's,^TZ=".*tzs\.dir/,TZ=",' [email protected] >$@
+ rm -fr tzs.dir [email protected]
+
+# If $(TZS) does not already exist (e.g., old-format tarballs), create it.
+# If it exists but 'make check_tzs' fails, a maintainer should inspect the
+# failed output and fix the inconsistency, perhaps by running 'make force_tzs'.
+$(TZS):
+ $(MAKE) force_tzs
+
+force_tzs: $(TZS_NEW)
+ cp $(TZS_NEW) $(TZS)
+
libtz.a: $(LIBOBJS)
$(AR) ru $@ $(LIBOBJS)
$(RANLIB) $@
@@ -485,19 +538,19 @@ libtz.a: $(LIBOBJS)
date: $(DATEOBJS)
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(DATEOBJS) $(LDLIBS)
-tzselect: tzselect.ksh
+tzselect: tzselect.ksh version
sed \
-e 's|#!/bin/bash|#!$(KSHELL)|g' \
-e 's|AWK=[^}]*|AWK=$(AWK)|g' \
-e 's|\(PKGVERSION\)=.*|\1='\''($(PACKAGE)) '\''|' \
-e 's|\(REPORT_BUGS_TO\)=.*|\1=$(BUGEMAIL)|' \
-e 's|TZDIR=[^}]*|TZDIR=$(TZDIR)|' \
- -e 's|\(TZVERSION\)=.*|\1=$(VERSION)|' \
- <$? >$@
+ -e 's|\(TZVERSION\)=.*|\1='"$$(cat version)"'|' \
+ <[email protected] >$@
chmod +x $@
check: check_character_set check_white_space check_links check_sorted \
- check_tables check_web
+ check_tables check_tzs check_web
check_character_set: $(ENCHILADA)
LC_ALL=en_US.utf8 && export LC_ALL && \
@@ -533,6 +586,9 @@ check_tables: checktab.awk $(PRIMARY_YDA
|| exit; \
done
+check_tzs: $(TZS) $(TZS_NEW)
+ diff -u $(TZS) $(TZS_NEW)
+
check_web: $(WEB_PAGES)
$(VALIDATE_ENV) $(VALIDATE) $(VALIDATE_FLAGS) $(WEB_PAGES)
@@ -540,12 +596,12 @@ clean_misc:
rm -f core *.o *.out \
date tzselect version.h zdump zic yearistype libtz.a
clean: clean_misc
- rm -fr tzpublic
+ rm -fr *.dir tzdb-*/ $(TZS_NEW)
maintainer-clean: clean
@echo 'This command is intended for maintainers to use; it'
@echo 'deletes files that may need special tools to rebuild.'
- rm -f leapseconds $(MANTXTS) *.asc *.tar.gz
+ rm -f leapseconds version $(MANTXTS) $(TZS) *.asc *.tar.*
names:
@echo $(ENCHILADA)
@@ -592,6 +648,8 @@ set-timestamps.out: $(ENCHILADA)
touch -cmr `ls -t $$file workman.sh | sed 1q` $$file.txt || \
exit; \
done
+ touch -cmr $$(ls -t $(TZS_DEPS) | sed 1q) $(TZS)
+ touch -cmr $$(ls -t $(VERSION_DEPS) | sed 1q) version
touch $@
# The zics below ensure that each data file can stand on its own.
@@ -600,12 +658,12 @@ set-timestamps.out: $(ENCHILADA)
check_public:
$(MAKE) maintainer-clean
$(MAKE) "CFLAGS=$(GCC_DEBUG_FLAGS)" ALL
- mkdir tzpublic
+ mkdir -p public.dir
for i in $(TDATA) ; do \
- $(zic) -v -d tzpublic $$i 2>&1 || exit; \
+ $(zic) -v -d public.dir $$i 2>&1 || exit; \
done
- $(zic) -v -d tzpublic $(TDATA)
- rm -fr tzpublic
+ $(zic) -v -d public.dir $(TDATA)
+ rm -fr public.dir
# Check that the code works under various alternative
# implementations of time_t.
@@ -617,15 +675,15 @@ check_time_t_alternatives:
fi && \
zones=`$(AWK) '/^[^#]/ { print $$3 }' <zone1970.tab` && \
for type in $(TIME_T_ALTERNATIVES); do \
- mkdir -p tzpublic/$$type && \
+ mkdir -p time_t.dir/$$type && \
$(MAKE) clean_misc && \
- $(MAKE) TOPDIR=`pwd`/tzpublic/$$type \
+ $(MAKE) TOPDIR=$$(pwd)/time_t.dir/$$type \
CFLAGS='$(CFLAGS) -Dtime_tz='"'$$type'" \
REDO='$(REDO)' \
install && \
diff $$quiet_option -r \
- tzpublic/int64_t/etc/zoneinfo \
- tzpublic/$$type/etc/zoneinfo && \
+ time_t.dir/int64_t/etc/zoneinfo \
+ time_t.dir/$$type/etc/zoneinfo && \
case $$type in \
int32_t) range=-2147483648,2147483647;; \
uint32_t) range=0,4294967296;; \
@@ -634,16 +692,20 @@ check_time_t_alternatives:
*) range=-10000000000,10000000000;; \
esac && \
echo checking $$type zones ... && \
- tzpublic/int64_t/etc/zdump -V -t $$range $$zones \
- >tzpublic/int64_t.out && \
- tzpublic/$$type/etc/zdump -V -t $$range $$zones \
- >tzpublic/$$type.out && \
- diff -u tzpublic/int64_t.out tzpublic/$$type.out \
+ time_t.dir/int64_t/etc/zdump -V -t $$range $$zones \
+ >time_t.dir/int64_t.out && \
+ time_t.dir/$$type/etc/zdump -V -t $$range $$zones \
+ >time_t.dir/$$type.out && \
+ diff -u time_t.dir/int64_t.out time_t.dir/$$type.out \
|| exit; \
done
- rm -fr tzpublic
+ rm -fr time_t.dir
+
+tarballs signatures: version
+ $(MAKE) VERSION="$$(cat version)" $@_version
-tarballs: tzcode$(VERSION).tar.gz tzdata$(VERSION).tar.gz
+tarballs_version: tzcode$(VERSION).tar.gz tzdata$(VERSION).tar.gz \
+ tzdb-$(VERSION).tar.lz
tzcode$(VERSION).tar.gz: set-timestamps.out
LC_ALL=C && export LC_ALL && \
@@ -656,7 +718,16 @@ tzdata$(VERSION).tar.gz: set-timestamps.
tar $(TARFLAGS) -cf - $(COMMON) $(DATA) $(MISC) | \
${TOOL_GZIP} $(GZIPFLAGS) > $@
-signatures: tzcode$(VERSION).tar.gz.asc tzdata$(VERSION).tar.gz.asc
+tzdb-$(VERSION).tar.lz: set-timestamps.out
+ rm -fr tzdb-$(VERSION)
+ mkdir tzdb-$(VERSION)
+ ln $(ENCHILADA) tzdb-$(VERSION)
+ touch -cmr $$(ls -t tzdb-$(VERSION)/* | sed 1q) tzdb-$(VERSION)
+ LC_ALL=C && export LC_ALL && \
+ tar $(TARFLAGS) -cf - tzdb-$(VERSION) | lzip -9 > $@
+
+signatures_version: tzcode$(VERSION).tar.gz.asc tzdata$(VERSION).tar.gz.asc \
+ tzdb-$(VERSION).tar.lz.asc
tzcode$(VERSION).tar.gz.asc: tzcode$(VERSION).tar.gz
gpg --armor --detach-sign $?
@@ -664,6 +735,9 @@ tzcode$(VERSION).tar.gz.asc: tzcode$(VER
tzdata$(VERSION).tar.gz.asc: tzdata$(VERSION).tar.gz
gpg --armor --detach-sign $?
+tzdb-$(VERSION).tar.lz.asc: tzdb-$(VERSION).tar.lz
+ gpg --armor --detach-sign $?
+
typecheck:
$(MAKE) clean
for i in "long long" unsigned; \
@@ -689,8 +763,10 @@ zic.o: private.h tzfile.h version.h
.PHONY: ALL INSTALL all
.PHONY: check check_character_set check_links
.PHONY: check_public check_sorted check_tables
-.PHONY: check_time_t_alternatives check_web check_white_space clean clean_misc
+.PHONY: check_time_t_alternatives check_tzs check_web check_white_space
+.PHONY: clean clean_misc force_tzs
.PHONY: install install_data maintainer-clean names
.PHONY: posix_only posix_packrat posix_right
-.PHONY: public right_only right_posix signatures tarballs typecheck
+.PHONY: public right_only right_posix signatures signatures_version
+.PHONY: tarballs tarballs_version typecheck
.PHONY: zonenames zones
Index: src/lib/libc/time/NEWS
diff -u src/lib/libc/time/NEWS:1.16 src/lib/libc/time/NEWS:1.17
--- src/lib/libc/time/NEWS:1.16 Fri Sep 16 13:12:06 2016
+++ src/lib/libc/time/NEWS Fri Oct 7 11:29:42 2016
@@ -1,5 +1,128 @@
News for the tz database
+Release 2016g - 2016-09-13 08:56:38 -0700
+
+ Changes to future time stamps
+
+ Turkey switched from EET/EEST (+02/+03) to permanent +03,
+ effective 2016-09-07. (Thanks to Burak AYDIN.) Use "+03" rather
+ than an invented abbreviation for the new time.
+
+ New leap second 2016-12-31 23:59:60 UTC as per IERS Bulletin C 52.
+ (Thanks to Tim Parenti.)
+
+ Changes to past time stamps
+
+ For America/Los_Angeles, spring-forward transition times have been
+ corrected from 02:00 to 02:01 in 1948, and from 02:00 to 01:00 in
+ 1950-1966.
+
+ For zones using Soviet time on 1919-07-01, transitions to UT-based
+ time were at 00:00 UT, not at 02:00 local time. The affected
+ zones are Europe/Kirov, Europe/Moscow, Europe/Samara, and
+ Europe/Ulyanovsk. (Thanks to Alexander Belopolsky.)
+
+ Changes to past and future time zone abbreviations
+
+ The Factory zone now uses the time zone abbreviation -00 instead
+ of a long English-language string, as -00 is now the normal way to
+ represent an undefined time zone.
+
+ Several zones in Antarctica and the former Soviet Union, along
+ with zones intended for ships at sea that cannot use POSIX TZ
+ strings, now use numeric time zone abbreviations instead of
+ invented or obsolete alphanumeric abbreviations. The affected
+ zones are Antarctica/Casey, Antarctica/Davis,
+ Antarctica/DumontDUrville, Antarctica/Mawson, Antarctica/Rothera,
+ Antarctica/Syowa, Antarctica/Troll, Antarctica/Vostok,
+ Asia/Anadyr, Asia/Ashgabat, Asia/Baku, Asia/Bishkek, Asia/Chita,
+ Asia/Dushanbe, Asia/Irkutsk, Asia/Kamchatka, Asia/Khandyga,
+ Asia/Krasnoyarsk, Asia/Magadan, Asia/Omsk, Asia/Sakhalin,
+ Asia/Samarkand, Asia/Srednekolymsk, Asia/Tashkent, Asia/Tbilisi,
+ Asia/Ust-Nera, Asia/Vladivostok, Asia/Yakutsk, Asia/Yekaterinburg,
+ Asia/Yerevan, Etc/GMT-14, Etc/GMT-13, Etc/GMT-12, Etc/GMT-11,
+ Etc/GMT-10, Etc/GMT-9, Etc/GMT-8, Etc/GMT-7, Etc/GMT-6, Etc/GMT-5,
+ Etc/GMT-4, Etc/GMT-3, Etc/GMT-2, Etc/GMT-1, Etc/GMT+1, Etc/GMT+2,
+ Etc/GMT+3, Etc/GMT+4, Etc/GMT+5, Etc/GMT+6, Etc/GMT+7, Etc/GMT+8,
+ Etc/GMT+9, Etc/GMT+10, Etc/GMT+11, Etc/GMT+12, Europe/Kaliningrad,
+ Europe/Minsk, Europe/Samara, Europe/Volgograd, and
+ Indian/Kerguelen. For Europe/Moscow the invented abbreviation MSM
+ was replaced by +05, whereas MSK and MSD were kept as they are not
+ our invention and are widely used.
+
+ Changes to zone names
+
+ Rename Asia/Rangoon to Asia/Yangon, with a backward compatibility link.
+ (Thanks to David Massoud.)
+
+ Changes to code
+
+ zic no longer generates binary files containing POSIX TZ-like
+ strings that disagree with the local time type after the last
+ explicit transition in the data. This fixes a bug with
+ Africa/Casablanca and Africa/El_Aaiun in some year-2037 time
+ stamps on the reference platform. (Thanks to Alexander Belopolsky
+ for reporting the bug and suggesting a way forward.)
+
+ If the installed localtime and/or posixrules files are symbolic
+ links, zic now keeps them symbolic links when updating them, for
+ compatibility with platforms like OpenSUSE where other programs
+ configure these files as symlinks.
+
+ zic now avoids hard linking to symbolic links, avoids some
+ unnecessary mkdir and stat system calls, and uses shorter file
+ names internally.
+
+ zdump has a new -i option to generate transitions in a
+ more-compact but still human-readable format. This option is
+ experimental, and the output format may change in future versions.
+ (Thanks to Jon Skeet for suggesting that an option was needed,
+ and thanks to Tim Parenti and Chris Rovick for further comments.)
+
+ Changes to build procedure
+
+ An experimental distribution format is available, in addition
+ to the traditional format which will continue to be distributed.
+ The new format is a tarball tzdb-VERSION.tar.lz with signature
+ file tzdb-VERSION.tar.lz.asc. It unpacks to a top-level directory
+ tzdb-VERSION containing the code and data of the traditional
+ two-tarball format, along with extra data that may be useful.
+ (Thanks to Antonio Diaz Diaz, Oscar van Vlijmen, and many others
+ for comments about the experimental format.)
+
+ The release version number is now more accurate in the usual case
+ where releases are built from a Git repository. For example, if
+ 23 commits and some working-file changes have been made since
+ release 2016g, the version number is now something like
+ '2016g-23-g50556e3-dirty' instead of the misleading '2016g'.
+ Official releases uses the same version number format as before,
+ e.g., '2016g'. To support the more-accurate version number, its
+ specification has moved from a line in the Makefile to a new
+ source file 'version'.
+
+ The experimental distribution contains a file to2050.tzs that
+ contains what should be the output of 'zdump -i -c 2050' on
+ primary zones. If this file is available, 'make check' now checks
+ that zdump generates this output.
+
+ 'make check_web' now works on Fedora-like distributions.
+
+ Changes to documentation and commentary
+
+ tzfile.5 now documents the new restriction on POSIX TZ-like
+ strings that is now implemented by zic.
+
+ Comments now cite URLs for some 1917-1921 Russian DST decrees.
+ (Thanks to Alexander Belopolsky.)
+
+ tz-link.htm mentions JuliaTime (thanks to Curtis Vogt) and Time4J
+ (thanks to Meno Hochschild) and ThreeTen-Extra, and its
+ description of Java 8 has been brought up to date (thanks to
+ Stephen Colebourne). Its description of local time on Mars has
+ been updated to match current practice, and URLs have been updated
+ and some obsolete ones removed.
+
+
Release 2016f - 2016-07-05 16:26:51 +0200
Changes affecting future time stamps
@@ -393,7 +516,7 @@ Release 2015d - 2015-04-24 08:09:46 -070
Changes affecting past time stamps
- America/Whitehorse switched from UTC-9 to UTC-8 on 1967-05-28, not
+ America/Whitehorse switched from UT -09 to -08 on 1967-05-28, not
1966-07-01. Also, Yukon's time zone history is documented better.
(Thanks to Brian Inglis and Dennis Ferguson.)
@@ -427,12 +550,12 @@ Release 2015c - 2015-04-11 08:55:55 -070
The 1918 transition was September 10, not September 1.
- The UTC-4 time observed from 1932 to 1942 is now considered to be
- standard time, not year-round DST.
+ The UT -04 time observed from 1932 to 1942 is now considered to
+ be standard time, not year-round DST.
- Santiago observed DST (UTC-3) from 1946-07-15 through 1946-08-31,
- then reverted to standard time, then switched its time zone to
- UTC-5 on 1947-04-01.
+ Santiago observed DST (UT -03) from 1946-07-15 through
+ 1946-08-31, then reverted to standard time, then switched to -05
+ on 1947-04-01.
Assume transitions before 1968 were at 00:00, since we have no data
saying otherwise.
@@ -561,7 +684,7 @@ Release 2014j - 2014-11-10 17:37:11 -080
Changes affecting current and future time stamps
- Turks & Caicos' switch from US eastern time to UTC-4 year-round
+ Turks & Caicos' switch from US eastern time to UT -04 year-round
did not occur on 2014-11-02 at 02:00. It's currently scheduled
for 2015-11-01 at 02:00. (Thanks to Chris Walton.)
@@ -597,7 +720,7 @@ Release 2014i - 2014-10-21 22:04:57 -070
years will use a similar pattern.
A new Zone Pacific/Bougainville, for the part of Papua New Guinea
- that plans to switch from UTC+10 to UTC+11 on 2014-12-28 at 02:00.
+ that plans to switch from UT +10 to +11 on 2014-12-28 at 02:00.
(Thanks to Kiley Walbom for the heads-up.)
Changes affecting time zone abbreviations
@@ -607,8 +730,8 @@ Release 2014i - 2014-10-21 22:04:57 -070
to its more-traditional value MSK on 2014-10-26 at 01:00.
(Thanks to Alexander Bokovoy for the heads-up about Belarus.)
- The new abbreviation IDT stands for the pre-1976 use of UT+8 in
- Indochina, to distinguish it better from ICT (UT+7).
+ The new abbreviation IDT stands for the pre-1976 use of UT +08 in
+ Indochina, to distinguish it better from ICT (+07).
Changes affecting past time stamps
@@ -686,7 +809,7 @@ Release 2014h - 2014-09-25 18:59:03 -070
zdump -c no longer mishandles transitions near year boundaries.
(Thanks to Tim Parenti for reporting the problem.)
- An access to uninitalized data has been fixed.
+ An access to uninitialized data has been fixed.
(Thanks to Jörg Richter for reporting the problem.)
When THREAD_SAFE is defined, the code ports to the C11 memory model.
@@ -719,8 +842,8 @@ Release 2014g - 2014-08-28 12:31:23 -070
Changes affecting future time stamps
- Turks & Caicos is switching from US eastern time to UTC-4 year-round,
- modeled as a switch from EST/EDT to AST on 2014-11-02 at 02:00.
+ Turks & Caicos is switching from US eastern time to UT -04
+ year-round, modeled as a switch on 2014-11-02 at 02:00.
[As noted in 2014j, this switch was later delayed.]
Changes affecting past time stamps
@@ -903,7 +1026,7 @@ Release 2014f - 2014-08-05 17:42:36 -070
This change does not affect UTC offsets, only time zone abbreviations.
(Thanks to Rich Tibbett and many others.)
- Asia/Novokuznetsk shifts from NOVT to KRAT (remaining on UTC+7)
+ Asia/Novokuznetsk shifts from NOVT to KRAT (remaining on UT +07)
effective 2014-10-26 at 02:00 local time.
The time zone abbreviation for Xinjiang Time (observed in Ürümqi)
@@ -932,8 +1055,8 @@ Release 2014f - 2014-08-05 17:42:36 -070
zones Asia/Harbin, Asia/Chongqing, and Asia/Kashgar have been
removed; backwards-compatibility links still work, albeit with
different behaviors for time stamps before May 1980. Asia/Urumqi's
- 1980 transition to UTC+8 has been removed, so that it is now at
- UTC+6 and not UTC+8. (Thanks to Luther Ma and to Alois Treindl;
+ 1980 transition to UT +08 has been removed, so that it is now at
+ +06 and not +08. (Thanks to Luther Ma and to Alois Treindl;
Treindl sent helpful translations of two papers by Guo Qingsheng.)
Some zones have been turned into links, when they differed from existing
@@ -963,8 +1086,8 @@ Release 2014f - 2014-08-05 17:42:36 -070
Europe/Helsinki's 1942 fall-back transition was 10-04 at 01:00, not
10-03 at 00:00. (Thanks to Konstantin Hyppönen.)
- Pacific/Pago_Pago has been changed from UTC-11:30 to UTC-11 for the period
- from 1911 to 1950.
+ Pacific/Pago_Pago has been changed from UT -11:30 to -11 for the
+ period from 1911 to 1950.
Pacific/Chatham has been changed to New Zealand standard time plus
45 minutes for the period before 1957, reflecting a 1956 remark in
@@ -1291,15 +1414,15 @@ Release 2013h - 2013-10-25 15:32:32 -070
Changes affecting current and future time stamps:
- Libya has switched its time zone back to UTC+2 without DST,
- instead of UTC+1 with DST. (Thanks to Even Scharning.)
+ Libya has switched its UT offset back to +02 without DST, instead
+ of +01 with DST. (Thanks to Even Scharning.)
Western Sahara (Africa/El_Aaiun) uses Morocco's DST rules.
(Thanks to Gwillim Law.)
Changes affecting future time stamps:
- Acre and (we guess) western Amazonas will switch from UTC-4 to UTC-5
+ Acre and (we guess) western Amazonas will switch from UT -04 to -05
on 2013-11-10. This affects America/Rio_Branco and America/Eirunepe.
(Thanks to Steffen Thorsen.)
@@ -1386,7 +1509,7 @@ Release 2013f - 2013-09-24 23:37:36 -070
Tocantins will very likely not observe DST starting this spring.
(Thanks to Steffen Thorsen.)
- Jordan will likely stay at UTC+3 indefinitely, and will not fall
+ Jordan will likely stay at UT +03 indefinitely, and will not fall
back this fall.
Palestine will fall back at 00:00, not 01:00. (Thanks to Steffen Thorsen.)
@@ -1443,7 +1566,7 @@ Release 2013e - 2013-09-19 23:50:04 -070
Benny Lin.) This affects Asia/Dili, Asia/Jakarta, Asia/Jayapura,
Asia/Makassar, and Asia/Pontianak.
- Use ART (UTC-3, standard time), rather than WARST (also UTC-3, but
+ Use ART (UT -03, standard time), rather than WARST (also -03, but
daylight saving time) for San Luis, Argentina since 2009.
Changes affecting Godthåb time stamps after 2037 if version mismatch
@@ -1900,7 +2023,7 @@ Release 2012f - 2012-09-12 23:17:03 -070
Release 2012e - 2012-08-02 20:44:55 -0700
- * australasia (Pacific/Fakaofo): Tokelau is UTC+13, not UTC+14.
+ * australasia (Pacific/Fakaofo): Tokelau is UT +13, not +14.
(Thanks to Steffen Thorsen.)
* Use a single version number for both code and data.
@@ -3519,14 +3642,15 @@ This file contains copies of the part of
that talks about the changes in that release. The text has been
adapted and reformatted for the purposes of this file.
-Typically a release R consists of a pair of tarball files,
+Traditionally a release R consists of a pair of tarball files,
tzcodeR.tar.gz and tzdataR.tar.gz. However, some releases (e.g.,
code2010a, data2012c) consist of just one or the other tarball, and a
few (e.g., code2012c-data2012d) have tarballs with mixed version
-numbers.
+numbers. Recent releases also come in an experimental format
+consisting of a single tarball tzdb-R.tar.lz with extra data.
Release time stamps are taken from the release's commit (for newer,
-git releases), from the newest file in the tarball (for older
+Git-based releases), from the newest file in the tarball (for older
releases, where this info is available) or from the email announcing
the release (if all else fails; these are marked with a time zone of
-0000 and an "is missing!" comment).
Index: src/lib/libc/time/README
diff -u src/lib/libc/time/README:1.10 src/lib/libc/time/README:1.11
--- src/lib/libc/time/README:1.10 Tue Mar 15 11:16:01 2016
+++ src/lib/libc/time/README Fri Oct 7 11:29:42 2016
@@ -13,12 +13,20 @@ and daylight-saving rules.
Here is a recipe for acquiring, building, installing, and testing the
tz distribution on a GNU/Linux or similar host.
+To acquire the distribution, run the following shell commands:
+
mkdir tz
cd tz
wget --retr-symlinks 'ftp://ftp.iana.org/tz/tz*-latest.tar.gz'
gzip -dc tzcode-latest.tar.gz | tar -xf -
gzip -dc tzdata-latest.tar.gz | tar -xf -
+Alternatively, the following shell commands acquire the same
+distribution, with extra data useful for regression testing:
+
+ wget --retr-symlinks 'ftp://ftp.iana.org/tz/tzdb-latest.tar.lz'
+ lzip -dc tzdb-latest.tar.lz | tar -xf -
+
Be sure to read the comments in "Makefile" and make any changes needed
to make things right for your system, especially if you are using some
platform other than GNU/Linux. Then run the following commands,
Index: src/lib/libc/time/Theory
diff -u src/lib/libc/time/Theory:1.20 src/lib/libc/time/Theory:1.21
--- src/lib/libc/time/Theory:1.20 Fri Sep 16 13:12:06 2016
+++ src/lib/libc/time/Theory Fri Oct 7 11:29:42 2016
@@ -323,7 +323,7 @@ Errors in the tz database arise from man
* Sometimes historical timekeeping was specified more precisely
than what the tz database can handle. For example, from 1909 to
- 1937 Netherlands clocks were legally UT+00:19:32.13, but the tz
+ 1937 Netherlands clocks were legally UT +00:19:32.13, but the tz
database cannot represent the fractional second.
* Even when all the timestamp transitions recorded by the tz database
Index: src/lib/libc/time/localtime.c
diff -u src/lib/libc/time/localtime.c:1.103 src/lib/libc/time/localtime.c:1.104
--- src/lib/libc/time/localtime.c:1.103 Fri Mar 18 08:41:25 2016
+++ src/lib/libc/time/localtime.c Fri Oct 7 11:29:42 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: localtime.c,v 1.103 2016/03/18 12:41:25 ginsbach Exp $ */
+/* $NetBSD: localtime.c,v 1.104 2016/10/07 15:29:42 christos Exp $ */
/*
** This file is in the public domain, so clarified as of
@@ -10,7 +10,7 @@
#if 0
static char elsieid[] = "@(#)localtime.c 8.17";
#else
-__RCSID("$NetBSD: localtime.c,v 1.103 2016/03/18 12:41:25 ginsbach Exp $");
+__RCSID("$NetBSD: localtime.c,v 1.104 2016/10/07 15:29:42 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -1560,7 +1560,7 @@ gmtsub(struct state const *sp, const tim
#ifdef TM_ZONE
/*
** Could get fancy here and deliver something such as
- ** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
+ ** "+xx" or "-xx" if offset is non-zero,
** but this is no time for a treasure hunt.
*/
if (result)
Index: src/lib/libc/time/private.h
diff -u src/lib/libc/time/private.h:1.45 src/lib/libc/time/private.h:1.46
--- src/lib/libc/time/private.h:1.45 Tue Mar 15 11:16:01 2016
+++ src/lib/libc/time/private.h Fri Oct 7 11:29:42 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: private.h,v 1.45 2016/03/15 15:16:01 christos Exp $ */
+/* $NetBSD: private.h,v 1.46 2016/10/07 15:29:42 christos Exp $ */
#ifndef PRIVATE_H
#define PRIVATE_H
@@ -27,6 +27,7 @@
** Thank you!
*/
+/* This string was in the Factory zone through version 2016f. */
#define GRANDPARENTED "Local time zone must be set--see zic manual page"
/*
Index: src/lib/libc/time/strftime.c
diff -u src/lib/libc/time/strftime.c:1.36 src/lib/libc/time/strftime.c:1.37
--- src/lib/libc/time/strftime.c:1.36 Tue Mar 15 11:16:01 2016
+++ src/lib/libc/time/strftime.c Fri Oct 7 11:29:42 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: strftime.c,v 1.36 2016/03/15 15:16:01 christos Exp $ */
+/* $NetBSD: strftime.c,v 1.37 2016/10/07 15:29:42 christos Exp $ */
/* Convert a broken-down time stamp 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.36 2016/03/15 15:16:01 christos Exp $");
+__RCSID("$NetBSD: strftime.c,v 1.37 2016/10/07 15:29:42 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -124,15 +124,11 @@ strftime_lz(const timezone_t sp, char *c
int warn;
warn = IN_NONE;
- p = _fmt(sp, ((format == NULL) ? "%c" : format), t, s, s + maxsize,
- &warn, loc);
+ p = _fmt(sp, format, t, s, s + maxsize, &warn, loc);
#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
(void) fprintf(stderr, "\n");
- if (format == NULL)
- (void) fprintf(stderr, "NULL strftime format ");
- else (void) fprintf(stderr, "strftime format \"%s\" ",
- format);
+ (void) fprintf(stderr, "strftime format \"%s\" ", format);
(void) fprintf(stderr, "yields only two digits of years in ");
if (warn == IN_SOME)
(void) fprintf(stderr, "some locales");
Index: src/lib/libc/time/tz-art.htm
diff -u src/lib/libc/time/tz-art.htm:1.13 src/lib/libc/time/tz-art.htm:1.14
--- src/lib/libc/time/tz-art.htm:1.13 Fri Sep 16 13:12:06 2016
+++ src/lib/libc/time/tz-art.htm Fri Oct 7 11:29:42 2016
@@ -24,6 +24,184 @@ into problems that programmers have with
Bell Science extravaganza, with Frank Baxter, Richard Deacon, and Les Tremayne.
(<a href="http://www.imdb.com/title/tt0154110/">IMDb entry</a>.)</li>
</ul>
+<h2>Movies</h2>
+<ul>
+<li>
+In the 1946 movie <em>A Matter of Life and Death</em>
+(U.S. title <em>Stairway to Heaven</em>)
+there is a reference to British Double Summer Time.
+The time does not play a large part in the plot;
+it's just a passing reference to the time when one of the
+characters was supposed to have died (but didn't).
+The IMDb page is at
+<a href="http://us.imdb.com/title/tt0038733/">
+http://us.imdb.com/title/tt0038733/
+</a>. (Dave Cantor)
+<li>
+The 1953 railway comedy movie <em>The Titfield Thunderbolt</em> includes a
+play on words on British Double Summer Time. Valentine's wife wants
+him to leave the pub and asks him, "Do you know what time it is?"
+And he, happy where he is, replies: "Yes, my love. Summer double time."
+IMDb page:
+<a href="http://us.imdb.com/title/tt0046436/">
+http://us.imdb.com/title/tt0046436/
+</a>. (Mark Brader, 2009-10-02)
+</li>
+<li>
+The premise of the 1999 caper movie <em>Entrapment</em> involves computers
+in an international banking network being shut down briefly at
+midnight in each time zone to avoid any problems at the transition
+from the year 1999 to 2000 in that zone. (Hmmmm.) If this shutdown
+is extended by 10 seconds, it will create a one-time opportunity for
+a gigantic computerized theft. To achieve this, at one location the
+crooks interfere with the microwave system supplying time signals to
+the computer, advancing the time by 0.1 second each minute over the
+last hour of 1999. (So this movie teaches us that 0.1 × 60 = 10.)
+IMDb page:
+<a href="http://us.imdb.com/title/tt0137494/">
+http://us.imdb.com/title/tt0137494/
+</a>. (Mark Brader, 2009-10-02)
+</li>
+<li>
+One mustn't forget the
+<a href="https://www.youtube.com/watch?v=k4EUTMPuvHo">trailer</a>
+(2014; 2:23) for the movie <em>Daylight Saving</em>.
+</li>
+</ul>
+<h2>TV episodes</h2>
+<ul>
+<li>
+An episode of <em>The Adventures of Superman</em> entitled "The Mysterious
+Cube," first aired 1958-02-24, had Superman convincing the controllers
+of the Arlington Time Signal to broadcast ahead of actual time;
+doing so got a crook trying to be declared dead to
+emerge a bit too early from the titular enclosure.
+</li>
+<li>
+The 1960s ITC television series <em>The Prisoner</em> included an episode
+entitled "The Chimes of Big Ben" in which our protagonist tumbled to
+the fraudulent nature of a Poland-to-England escape upon hearing "Big
+Ben" chiming on Polish local time.
+</li>
+<li>
+The series <em>Seinfeld</em> included an episode entitled "The Susie," first
+broadcast 1997-02-13, in which Kramer decides that daylight saving time
+isn't coming fast enough, so he sets his watch ahead an hour.
+</li>
+<li>
+The "20 Hours in America" episode of <em>The West Wing</em>,
+first aired 2002-09-25, contained a <a
+href="https://www.youtube.com/watch?v=-J1NHzQ1sgc">scene</a> that
+saw White House staffers stranded in Indiana; they thought they had time to
+catch Air Force One but were done in by intra-Indiana local time changes.
+</li>
+<li>
+"In what time zone would you find New York City?" was a $200 question on
+the 1999-11-13 United States airing of <em>Who Wants to Be a Millionaire?</em>,
+and "In 1883, what industry led the movement to divide the U.S. into four time
+zones?" was a $32,000 question on the 2001-05-23 United States airing of
+the same show. At this rate, the million-dollar time-zone
+question should have been asked 2002-06-04.
+</li>
+<li>
+A private jet's mid-flight change of time zones distorts Alison Dubois'
+premonition in the "We Had a Dream" episode of <em>Medium</em>
+(originally aired 2007-02-28).
+</li>
+<li>
+In the <em>30 Rock</em> episode "Anna Howard Shaw Day"
+(first broadcast 2010-02-11),
+Jack Donaghy's date realizes that a Geneva-to-New-York business phone call
+received in the evening must be fake given the difference in local times.
+</li>
+<li>
+In the "Run by the Monkeys" episode of <em>Da Vinci's Inquest</em>
+(first broadcast 2002-11-17),
+a witness in a five-year-old fire case realizes they may not have set
+their clock back when daylight saving ended on the day of the fire,
+introducing the possibility of an hour when arson might have occurred.
+</li>
+<li>
+In "The Todd Couple" episode of <em>Outsourced</em> (first aired 2011-02-10),
+Manmeet sets up Valentine's Day teledates for 6:00 and 9:00pm;
+since one is with a New Yorker and the other with a San Franciscan,
+hilarity ensues.
+(Never mind that this should be 7:30am in Mumbai, yet for some reason the show
+proceeds as though it's also mid-evening there.)
+</li>
+<li>
+In the "14 Days to Go"/"T Minus..." episode of
+<em>You, Me and the Apocalypse</em>
+(first aired 2015-11-11 in the UK, 2016-03-10 in the US),
+the success of a mission to deal with a comet
+hinges on whether or not Russia observes daylight saving time.
+(In the US, the episode first aired in the week before the switch to DST.)
+</li>
+<li>
+"The Lost Hour", <em>Eerie, Indiana</em>, episode 10, NBC, 1991-12-01.
+Despite Indiana's then-lack of DST, Marshall changes his clock with
+unusual consequences.
+</li>
+<li>
+"Time Tunnel", <em>The Adventures of Pete & Pete</em>, season 2, episode 5,
+Nickelodeon, 1994-10-23.
+The two Petes travel back in time an hour on the day that DST ends.
+</li>
+<li>
+"King-Size Homer", <em>The Simpsons</em>, episode 135, Fox, 1995-11-05.
+Homer, working from home, remarks "8:58, first
+time I've ever been early for work. Except for all those daylight
+savings days. Lousy farmers."
+</li>
+<li>
+"Tracks", <em>The Good Wife</em>, season 7, episode 12,
+CBS, 2016-01-17.
+The applicability of a contract hinges on the
+time zone associated with a video time stamp.
+</li>
+</ul>
+<h2>Books, plays, and magazines</h2>
+<ul>
+<li>
+Jules Verne, <em>Around the World in Eighty Days</em>
+(<em>Le tour du monde en quatre-vingts jours</em>).
+Wall-clock time plays a central role in the plot.
+European readers of the 1870s clearly held the U.S. press in
+deep contempt; the protagonists cross the U.S. without once
+reading a paper.
+Available versions include
+<a href="http://www.literature.org/Works/Jules-Verne/eighty">an English
+translation</a>, and
+<a href="http://fourmilab.ch/etexts/www/tdm80j">the original French</a>
+"with illustrations from the original 1873 French-language edition".
+</li>
+<li>
+Nick Enright, <em>Daylight Saving</em>, 1989.
+A fast-paced comedy about love and loneliness as the clocks turn back.
+</li>
+<li>
+Umberto Eco, <em>The Island of the Day Before</em>
+(<em>L'isola del giorno prima</em>), 1994.
+"...the story of a 17th century Italian nobleman trapped near an island
+on the International Date Line. Time and time zones play an integral
+part in the novel." (Paul Eggert, 2006-04-22)
+</li>
+<li>
+John Dunning, <a
+href="http://books.simonandschuster.com/Two-OClock-Eastern-Wartime/John-Dunning/9781439171530"><em>Two
+O'Clock, Eastern Wartime</em></a>, 2001.
+Mystery, history, daylight saving time, and old-time radio.
+</li>
+<li>
+Surrealist artist Guy Billout's work "Date Line" appeared on page 103
+of the 1999-11 <em>Atlantic Monthly</em>.
+</li>
+<li>
+"Gloom, Gloom, Go Away" by Walter Kirn appeared on page 106 of <em>Time</em>
+magazine's 2002-11-11 issue; among other things, it proposed
+year-round DST as a way of lessening wintertime despair.
+</li>
+</ul>
<h2>Music</h2>
<p>
Data on recordings of "Save That Time," Russ Long, Serrob Publishing, BMI:</p>
@@ -254,215 +432,6 @@ Supernaw.</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>
</table>
-
-<h2>TV episodes</h2>
-
-<ul>
-<li>
-An episode of <em>The Adventures of Superman</em> entitled "The Mysterious
-Cube," first aired 1958-02-24, had Superman convincing the controllers
-of the Arlington Time Signal to broadcast ahead of actual time;
-doing so got a crook trying to be declared dead to
-emerge a bit too early from the titular enclosure.
-</li>
-<li>
-The 1960s ITC television series <em>The Prisoner</em> included an episode
-entitled "The Chimes of Big Ben" in which our protagonist tumbled to
-the fraudulent nature of a Poland-to-England escape upon hearing "Big
-Ben" chiming on Polish local time.
-</li>
-<li>
-The series <em>Seinfeld</em> included an episode entitled "The Susie," first
-broadcast 1997-02-13, in which Kramer decides that daylight saving time
-isn't coming fast enough, so he sets his watch ahead an hour.
-</li>
-<li>
-The "20 Hours in America" episode of <em>The West Wing</em>,
-first aired 2002-09-25,
-saw White House staffers stranded in Indiana; they thought they had time to
-catch Air Force One but were done in by intra-Indiana local time changes.
-</li>
-<li>
-"In what time zone would you find New York City?" was a $200 question on
-the 1999-11-13 United States airing of <em>Who Wants to Be a Millionaire?</em>,
-and "In 1883, what industry led the movement to divide the U.S. into four time
-zones?" was a $32,000 question on the 2001-05-23 United States airing of
-the same show. At this rate, the million-dollar time-zone
-question should have been asked 2002-06-04.
-</li>
-<li>
-A private jet's mid-flight change of time zones distorts Alison Dubois'
-premonition in the "We Had a Dream" episode of <em>Medium</em>
-(originally aired 2007-02-28).
-</li>
-<li>
-In the <em>30 Rock</em> episode "Anna Howard Shaw Day"
-(first broadcast 2010-02-11),
-Jack Donaghy's date realizes that a Geneva-to-New-York business phone call
-received in the evening must be fake given the difference in local times.
-</li>
-<li>
-In the "Run by the Monkeys" episode of <em>Da Vinci's Inquest</em>
-(first broadcast 2002-11-17),
-a witness in a five-year-old fire case realizes they may not have set
-their clock back when daylight saving ended on the day of the fire,
-introducing the possibility of an hour when arson might have occurred.
-</li>
-<li>
-In "The Todd Couple" episode of <em>Outsourced</em> (first aired 2011-02-10),
-Manmeet sets up Valentine's Day teledates for 6:00 and 9:00pm;
-since one is with a New Yorker and the other with a San Franciscan,
-hilarity ensues.
-(Never mind that this should be 7:30am in Mumbai, yet for some reason the show
-proceeds as though it's also mid-evening there.)
-</li>
-<li>
-In the "14 Days to Go"/"T Minus..." episode of
-<em>You, Me and the Apocalypse</em>
-(first aired 2015-11-11 in the UK, 2016-03-10 in the US),
-the success of a mission to deal with a comet
-hinges on whether or not Russia observes daylight saving time.
-(In the US, the episode first aired in the week before the switch to DST.)
-</li>
-</ul>
-
-<table>
-<tr><td>TV episode title</td><td>The Lost Hour</td>
-<tr><td>TV series</td><td><em>Eerie, Indiana</em></td>
-<tr><td>TV episode number</td><td>10</td>
-<tr><td>Network</td><td>NBC</td>
-<tr><td>Air date</td><td>1991-12-01</td>
-<tr><td>Notes</td><td>Despite Indiana's then-lack of DST, Marshall changes his clock with unusual consequences.</td></tr>
-<tr><td> </td></tr>
-
-<tr><td>TV episode title</td><td>Time Tunnel</td>
-<tr><td>TV series</td><td><em>The Adventures of Pete & Pete</em></td>
-<tr><td>TV episode number</td><td>5, season 2</td>
-<tr><td>Network</td><td>Nickelodeon</td>
-<tr><td>Air date</td><td>1994-10-23</td>
-<tr><td>Notes</td><td>The two Petes travel back in time an hour on the day that DST ends.</td></tr>
-<tr><td> </td></tr>
-
-<tr><td>TV episode title</td><td>King-Size Homer</td>
-<tr><td>TV series</td><td><em>The Simpsons</em></td>
-<tr><td>TV episode number</td><td>135</td>
-<tr><td>Network</td><td>Fox</td>
-<tr><td>Air date</td><td>1995-11-05</td>
-<tr><td>Notes</td><td>Homer, working from home, remarks "8:58, first
-time I've ever been early for work. Except for all those daylight
-savings days. Lousy farmers."</td></tr>
-<tr><td> </td></tr>
-
-<tr><td>TV episode title</td><td>Tracks</td></tr>
-<tr><td>TV series</td><td><em>The Good Wife</em></td></tr>
-<tr><td>TV episode number</td><td>12, season 7</td></tr>
-<tr><td>Network</td><td>CBS</td></tr>
-<tr><td>Air date</td><td>2016-01-17</td></tr>
-<tr><td>Notes</td><td>The applicability of a contract hinges on the
-time zone associated with a video time stamp.</td></tr>
-</table>
-
-<h2>Books, plays, and magazines</h2>
-
-<table>
-<tr><td>Artist</td><td>Jules Verne</td></tr>
-<tr><td>Book</td><td><em>Around the World in Eighty Days</em>
-(<em>Le tour du monde en quatre-vingts jours</em>)</td></tr>
-<tr><td>Notes</td><td>Wall-clock time plays a central role in the plot.
-European readers of the 1870s clearly held the U.S. press in
-deep contempt; the protagonists cross the U.S. without once
-reading a paper.
-An on-line French-language version of the book
-"with illustrations from the original 1873 French-language edition"
-is available at
-<a href="http://fourmilab.ch/etexts/www/tdm80j">http://fourmilab.ch/etexts/www/tdm80j</a>
-An on-line English-language translation of the book is available at
-<a href="http://www.literature.org/Works/Jules-Verne/eighty">http://www.literature.org/Works/Jules-Verne/eighty</a></td></tr>
-
-<tr><td> </td></tr>
-<tr><td>Artist</td><td>Nick Enright</td></tr>
-<tr><td>Play</td><td><em>Daylight Saving</em></td></tr>
-<tr><td>Copyright Date</td><td>1989</td></tr>
-<tr><td>Notes</td><td>
-A fast-paced comedy about love and loneliness as the clocks turn back.
-</td></tr>
-
-<tr><td> </td></tr>
-<tr><td>Artist</td><td>Umberto Eco</td></tr>
-<tr><td>Book</td><td><em>The Island of the Day Before</em>
-(<em>L'isola del giorno prima</em>)</td></tr>
-<tr><td>Copyright Date</td><td>1994</td></tr>
-<tr><td>Notes</td><td>
-"...the story of a 17th century Italian nobleman trapped near an island
-on the International Date Line. Time and time zones play an integral
-part in the novel." (Paul Eggert, 2006-04-22)
-</td></tr>
-<tr><td> </td></tr>
-<tr><td>Artist</td><td>John Dunning</td></tr>
-<tr><td>Book</td><td><a
-href="http://books.simonandschuster.com/Two-OClock-Eastern-Wartime/John-Dunning/9781439171530"><em>Two
-O'Clock, Eastern Wartime</em></a></td></tr>
-<tr><td>Copyright Date</td><td>2001</td></tr>
-<tr><td>Notes</td><td>
-Mystery, history, daylight saving time, and old-time radio.
-</td></tr>
-</table>
-<hr>
-<ul>
-<li>
-Surrealist artist Guy Billout's work "Date Line" appeared on page 103
-of the 1999-11 <em>Atlantic Monthly</em>.
-</li>
-<li>
-"Gloom, Gloom, Go Away" by Walter Kirn appeared on page 106 of <em>Time</em>
-magazine's 2002-11-11 issue; among other things, it proposed
-year-round DST as a way of lessening wintertime despair.
-</li>
-</ul>
-<h2>Movies</h2>
-<ul>
-<li>
-In the 1946 movie <em>A Matter of Life and Death</em>
-(U.S. title <em>Stairway to Heaven</em>)
-there is a reference to British Double Summer Time.
-The time does not play a large part in the plot;
-it's just a passing reference to the time when one of the
-characters was supposed to have died (but didn't).
-The IMDb page is at
-<a href="http://us.imdb.com/title/tt0038733/">
-http://us.imdb.com/title/tt0038733/
-</a>. (Dave Cantor)
-<li>
-The 1953 railway comedy movie <em>The Titfield Thunderbolt</em> includes a
-play on words on British Double Summer Time. Valentine's wife wants
-him to leave the pub and asks him, "Do you know what time it is?"
-And he, happy where he is, replies: "Yes, my love. Summer double time."
-IMDb page:
-<a href="http://us.imdb.com/title/tt0046436/">
-http://us.imdb.com/title/tt0046436/
-</a>. (Mark Brader, 2009-10-02)
-</li>
-<li>
-The premise of the 1999 caper movie <em>Entrapment</em> involves computers
-in an international banking network being shut down briefly at
-midnight in each time zone to avoid any problems at the transition
-from the year 1999 to 2000 in that zone. (Hmmmm.) If this shutdown
-is extended by 10 seconds, it will create a one-time opportunity for
-a gigantic computerized theft. To achieve this, at one location the
-crooks interfere with the microwave system supplying time signals to
-the computer, advancing the time by 0.1 second each minute over the
-last hour of 1999. (So this movie teaches us that 0.1 × 60 = 10.)
-IMDb page:
-<a href="http://us.imdb.com/title/tt0137494/">
-http://us.imdb.com/title/tt0137494/
-</a>. (Mark Brader, 2009-10-02)
-</li>
-<li>
-One mustn't forget the
-<a href="https://www.youtube.com/watch?v=k4EUTMPuvHo">trailer</a>
-(2014; 2:23) for the movie <em>Daylight Saving</em>.
-</li>
-</ul>
<h2>Comics</h2>
<ul>
<li>
Index: src/lib/libc/time/tz-how-to.html
diff -u src/lib/libc/time/tz-how-to.html:1.1 src/lib/libc/time/tz-how-to.html:1.2
--- src/lib/libc/time/tz-how-to.html:1.1 Fri Sep 16 13:12:06 2016
+++ src/lib/libc/time/tz-how-to.html Fri Oct 7 11:29:42 2016
@@ -12,8 +12,7 @@ Database</a> Source Files</h2>
times of day from the <a href="tz-link.htm">tz database</a>
source files. It might be helpful, but not absolutely necessary,
for the reader to have already downloaded the
-<a href="http://www.iana.org/time-zones/repository/tzdata-latest.tar.gz">latest
-release of the database</a> and become familiar with the basic layout
+latest release of the database and become familiar with the basic layout
of the data files. The format is explained in the “man
page” for the zic compiler, <code>zic.8.txt</code>, in
the <code>code</code> subdirectory.</p>
@@ -251,7 +250,7 @@ local standard time (different from wall
daylight saving time); or it can be suffixed with ‘g’,
‘u’, or ‘z’, all three of which mean the
standard time at the
-<a href="https://en.wikipedia.org/wiki/Prime_Meridian">prime meridan</a>.
+<a href="https://en.wikipedia.org/wiki/Prime_Meridian">prime meridian</a>.
‘g’ stands for “<a
href="https://en.wikipedia.org/wiki/Greenwich_Mean_Time">GMT</a>”;
‘u’ stands for “<a
Index: src/lib/libc/time/tz-link.htm
diff -u src/lib/libc/time/tz-link.htm:1.26 src/lib/libc/time/tz-link.htm:1.27
--- src/lib/libc/time/tz-link.htm:1.26 Fri Sep 16 13:12:06 2016
+++ src/lib/libc/time/tz-link.htm Fri Oct 7 11:29:42 2016
@@ -10,7 +10,7 @@
content="Sources for time zone and daylight saving time data">
<meta name="DC.Creator" content="Eggert, Paul">
<meta name="DC.Contributor" content="Olson, Arthur David">
-<meta name="DC.Date" content="2016-06-14">
+<meta name="DC.Date" content="2016-09-09">
<meta name="DC.Description"
content="Sources of information about time zones and daylight saving time">
<meta name="DC.Identifier"
@@ -42,7 +42,7 @@ This database (often called <code>zonein
<code><abbr>tz</abbr></code>)
is used by several implementations,
including
-<a href="http://www.gnu.org/software/libc/">the
+<a href="https://www.gnu.org/software/libc/">the
<abbr title="GNU's Not Unix">GNU</abbr>
C Library</a> (used in
<a href="https://en.wikipedia.org/wiki/Linux"><abbr>GNU</abbr>/Linux</a>),
@@ -65,13 +65,13 @@ title="Advanced Interactive eXecutive">A
<a href="https://en.wikipedia.org/wiki/BlackBerry_10">BlackBerry 10</a>,
<a href="http://www.apple.com/ios/"><abbr
title="iPhone OS">iOS</abbr></a>,
-<a href="http://windows.microsoft.com">Microsoft Windows</a>,
+<a href="http://www.apple.com/macos/"><abbr
+title="Mac Operating System">macOS</abbr></a>,
+<a href="https://www.microsoft.com/en-us/windows">Microsoft Windows</a>,
<a href="http://www.hp.com/go/openvms/">Open<abbr
title="Virtual Memory System">VMS</abbr></a>,
-<a href="https://www.oracle.com/database/index.html">Oracle Database</a>,
-<a href="http://oracle.com/solaris">Oracle Solaris</a>, and
-<a href="http://www.apple.com/osx/"><abbr title="Operating System Ten">OS
-X</abbr></a>.</p>
+<a href="https://www.oracle.com/database/index.html">Oracle Database</a>, and
+<a href="https://www.oracle.com/solaris">Oracle Solaris</a>.</p>
<p>
Each location in the database represents a region where all
clocks keeping local time have agreed since 1970.
@@ -103,47 +103,51 @@ for time stamps after 1960 this is more
href="https://en.wikipedia.org/wiki/Coordinated_Universal_Time">Coordinated
Universal Time</a> (<abbr>UTC</abbr>).
The database also records when daylight saving time was in use,
-along with alphabetic time zone abbreviations such as <abbr>EST</abbr>
+along with some time zone abbreviations such as <abbr>EST</abbr>
for Eastern Standard Time in the <abbr>US</abbr>.</p>
<p>
-In the <code><abbr>tz</abbr></code> database's
+The following <a
+href="https://en.wikipedia.org/wiki/Unix_shell">shell</a> commands download
+the latest release's two
+<a href="https://en.wikipedia.org/wiki/Tar_(computing)">tarballs</a>
+to a <abbr>GNU</abbr>/Linux or similar host.</p>
+<pre style="margin-left: 2em"><code>mkdir tzdb
+cd tzdb
+<a href="https://www.gnu.org/software/wget/">wget</a> --retr-symlinks 'ftp://ftp.iana.org/tz/tz*-latest.tar.gz'
+<a href="https://www.gnu.org/software/gzip/">gzip</a> -dc tzcode-latest.tar.gz | <a href="https://www.gnu.org/software/tar/">tar</a> -xf -
+gzip -dc tzdata-latest.tar.gz | tar -xf -
+</code></pre>
+<p>Alternatively, the following shell commands download the same
+release in a single-tarball format containing extra data
+useful for regression testing:</p>
+<pre style="margin-left: 2em"><code>wget --retr-symlinks 'ftp://ftp.iana.org/tz/tzdb-latest.tar.lz'
+<a href="http://www.nongnu.org/lzip/">lzip</a> -dc tzdb-latest.tar.lz | tar -xf -
+</code></pre>
+<p>These commands use convenience links to the latest of the
<a href="ftp://ftp.iana.org/tz/releases/"><abbr
title="File Transfer Protocol">FTP</abbr> releases</a>
-the code is in the file <code>tzcode<var>C</var>.tar.gz</code>,
-where <code><var>C</var></code> is the code's version;
-similarly, the data entries are in <code>tzdata<var>D</var>.tar.gz</code>,
-where <code><var>D</var></code> is the data's version.
+of the <code><abbr>tz</abbr></code> database.
+Older releases are in files named
+<code>tzcode<var>V</var>.tar.gz</code>,
+<code>tzdata<var>V</var>.tar.gz</code>, and
+<code>tzdb-<var>V</var>.tar.lz</code>,
+where <code><var>V</var></code> is the version.
Since 1996, each version has been a four-digit year followed by
lower-case letter (<samp>a</samp> through <samp>z</samp>,
then <samp>za</samp> through <samp>zz</samp>, then <samp>zza</samp>
through <samp>zzz</samp>, and so on).
-Convenience links to
-the <a href="ftp://ftp.iana.org/tz/tzcode-latest.tar.gz">latest
-code</a> and
-<a href="ftp://ftp.iana.org/tz/tzdata-latest.tar.gz">latest data</a> revisions
-are also available.
-The following <a
-href="https://en.wikipedia.org/wiki/Unix_shell">shell</a> commands download
-these files to a <abbr>GNU</abbr>/Linux or similar host;
-see the downloaded
-<code>README</code> file for what to do next.</p>
-<pre style="margin-left: 2em"><code>mkdir tz
-cd tz
-<a href="http://www.gnu.org/software/wget/">wget</a> --retr-symlinks 'ftp://ftp.iana.org/tz/tz*-latest.tar.gz'
-<a href="http://www.gnu.org/software/gzip/">gzip</a> -dc tzcode-latest.tar.gz | <a href="http://www.gnu.org/software/tar/">tar</a> -xf -
-gzip -dc tzdata-latest.tar.gz | tar -xf -
-</code></pre>
-<p>
-The code and data files can also be obtained from the
+The releases can also be obtained from the
<a href="http://www.iana.org/time-zones">Time Zone Database website</a>
of the <a href="http://www.iana.org">Internet Assigned Numbers
Authority (IANA)</a>.
An <a href="https://github.com/eggert/tz">unofficial development
repository</a> of the code and data is available
-in <a href="http://git-scm.com">Git</a> form
+in <a href="https://git-scm.com">Git</a> form
from <a href="https://github.com">GitHub</a>; be careful, as this
repository is less well tested and probably contains more errors.
<p>
+After extracting a distribution's files, see its
+<code>README</code> file for what to do next.
The code lets you compile the <code><abbr>tz</abbr></code> source files into
machine-readable binary files, one for each location. It also lets
you read a <code><abbr>tz</abbr></code> binary file and interpret time stamps for that
@@ -204,7 +208,7 @@ the Timing of Time Zone Changes</a> give
by inadequate notice by governments of time zone and daylight saving
rule changes.</li>
<li><a
-href="http://blog.jonudell.net/2009/10/23/a-literary-appreciation-of-the-olsonzoneinfotz-database/">A
+href="https://blog.jonudell.net/2009/10/23/a-literary-appreciation-of-the-olsonzoneinfotz-database/">A
literary appreciation of the Olson/Zoneinfo/tz database</a> comments on the
database's style.</li>
</ul>
@@ -240,15 +244,14 @@ names and shows location maps.</li>
</ul>
<h2>Network protocols for <code><abbr>tz</abbr></code> data</h2>
<ul>
-<li>The <a href="http://www.ietf.org">Internet Engineering Task Force</a>'s
+<li>The <a href="https://www.ietf.org">Internet Engineering Task Force</a>'s
<a href="https://datatracker.ietf.org/wg/tzdist/charter/">Time Zone Data
Distribution Service (tzdist) working group</a> defined <a
href="https://tools.ietf.org/html/rfc7808">TZDIST</a>
(Internet <abbr>RFC</abbr> 7808), a time zone data distribution service,
along with a <a href="https://tools.ietf.org/html/rfc7809">calendar access
protocol for transferring time zone data by reference</a>
-(Internet <abbr>RFC</abbr> 7809). This work was based
-on the iCalendar and CalConnect efforts described below.</li>
+(Internet <abbr>RFC</abbr> 7809).</li>
<li>The <a href="https://tools.ietf.org/html/rfc5545">
Internet Calendaring and Scheduling Core Object Specification
(iCalendar)</a> (Internet <abbr>RFC</abbr> 5445)
@@ -257,35 +260,12 @@ data; see its VTIMEZONE calendar compone
The iCalendar format requires specialized parsers and generators; a
variant <a href="https://tools.ietf.org/html/rfc6321">xCal</a>
(Internet <abbr>RFC</abbr> 6321) uses
-<a href="http://www.w3.org/XML/"><abbr
+<a href="https://www.w3.org/XML/"><abbr
title="Extensible Markup Language">XML</abbr></a> format, and a variant
<a href="https://tools.ietf.org/html/rfc7265">jCal</a>
(Internet <abbr>RFC</abbr> 7265)
uses <a href="http://www.json.org"><abbr
-title="JavaScript Object Notation">JSON</abbr></a> format.
-<a href="https://www.calconnect.org">CalConnect, The Calendaring and Scheduling
-Consortium</a> is promoting further work in this area. <a
-href="http://calconnect.org/publications/icalendartimezoneproblemsandrecommendationsv1.0.pdf">iCalendar
-TIMEZONE Problems and Recommendations</a> offers guidelines and
-recommendations for the use of VTIMEZONE and <code><abbr>tz</abbr></code>.</li>
-<li>The <a
-href="http://calconnect.org/publications/timezoneregistryandservicerecommendationsv1.0.pdf">Timezone
-Registry and Service Recommendations</a> of CalConnect's
-<a href="https://www.calconnect.org/about/technical-committees/tc-timezone">TIMEZONE
-Technical Committee</a> discusses a
-strategy for defining and deploying a time zone
-registration process that would establish unique names for each
-version of each <code><abbr>tz</abbr></code> zone, along with a polygonal
-representation of the geographical area corresponding to the
-zone.</li>
-<li>The <a
-href="http://lists.w3.org/Archives/Public/www-rdf-calendar/">www-rdf-calendar</a>
-list discusses <a
-href="http://www.w3.org/RDF/"><abbr
-title="Resource Description Framework">RDF</abbr></a>-based calendar
-and group scheduling systems, and has a <a
-href="http://www.w3.org/2002/12/cal/#tzd">workspace on time zone
-data</a> converted from <code><abbr>tz</abbr></code>.</li>
+title="JavaScript Object Notation">JSON</abbr></a> format.</li>
</ul>
<h2>Other <code><abbr>tz</abbr></code> compilers</h2>
<ul>
@@ -295,7 +275,7 @@ program that compiles
<code><abbr>tz</abbr></code> source into iCalendar-compatible VTIMEZONE files.
Vzic is freely
available under the <a
-href="http://www.gnu.org/copyleft/gpl.html"><abbr>GNU</abbr>
+href="https://www.gnu.org/copyleft/gpl.html"><abbr>GNU</abbr>
General Public License (<abbr
title="General Public License">GPL</abbr>)</a>.</li>
<li><a href="https://sourceforge.net/projects/tzical/">tziCal – tz
@@ -334,21 +314,41 @@ and compiles tz source and exposes <abbr
title="Application Program Interface">API</abbr>s for use. It is
freely available under the <abbr
title="Massachusetts Institute of Technology">MIT</abbr> license.</li>
+<li>Java-based compilers and libraries include:
+<ul>
<li>The <a
href="http://www.oracle.com/technetwork/java/javase/tzupdater-readme-136440.html">TZUpdater
tool</a> compiles <code><abbr>tz</abbr></code> source into the format used by
Oracle Java.</li>
+<li>The <a
+href="http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html">Java
+8 <code>java.time</code> <abbr>API</abbr></a> can be supplemented by <a
+href="http://www.threeten.org/threeten-extra/">ThreeTen-Extra</a>,
+which is freely available under a <abbr>BSD</abbr>-style license.</li>
<li><a href="http://www.joda.org/joda-time/">Joda-Time – Java date
and time <abbr>API</abbr></a> contains a class
<code>org.joda.time.tz.ZoneInfoCompiler</code> that compiles
-<code><abbr>tz</abbr></code> source into a Joda-specific binary format. Joda Time
-is freely available under a <abbr>BSD</abbr>-style license.</li>
+<code><abbr>tz</abbr></code> source into a binary format. It inspired
+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="http://www.apache.org/licenses/LICENSE-2.0">Apache License</a>.</li>
+<li><a href="https://github.com/MenoData/Time4J/">Time4J –
+Advanced date, time and interval library for Java</a> contains a class
+<code>net.time4j.tool.TimezoneRepositoryCompiler</code> that compiles
+<code><abbr>tz</abbr></code> source into a binary format. Time4J is
+available under the <a
+href="https://www.gnu.org/copyleft/lesser.html"><abbr>GNU</abbr> Lesser
+General Public License (<abbr title="Lesser General Public
+License">LGPL</abbr>)</a>.</li>
+<li><abbr>ICU</abbr> (mentioned above) contains compilers and
+Java-based libraries.</li>
+</ul>
<li><a href="http://nodatime.org">Noda Time – Date and
time <abbr>API</abbr> for .NET</a>
and <a href="http://www.babiej.demon.nl/Tz4Net/main.htm">TZ4Net</a>
-are similar to Joda Time, but for the .NET framework instead of
+are similar to Joda-Time and Time4J, but for the .NET framework instead of
Java. They are freely available under the
-<a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License</a>
+Apache License
and a <abbr>BSD</abbr>-style license, respectively.</li>
<li><a href="https://en.wikipedia.org/wiki/JavaScript">JavaScript</a>-based
compilers and libraries include:
@@ -364,6 +364,10 @@ Dates. It is freely available under the
translates <abbr>UT</abbr> to local time. It is freely available under
the <abbr>MIT</abbr> license.</li>
</ul>
+<li><a href="https://github.com/JuliaTime/">JuliaTime</a> contains a
+compiler from <code><abbr>tz</abbr></code> source into
+<a href="http://julialang.org/">Julia</a>. It is freely available
+under the <abbr>MIT</abbr> license.</li>
<li><a href="http://pytz.sourceforge.net">pytz – World Timezone
Definitions for Python</a> compiles <code><abbr>tz</abbr></code> source into
<a href="https://www.python.org">Python</a>.
@@ -389,16 +393,14 @@ license.</li>
<h2>Other <code><abbr>tz</abbr></code> binary file readers</h2>
<ul>
<li>The <a
-href="http://www.gnu.org/software/libc/"><abbr>GNU</abbr> C
+href="https://www.gnu.org/software/libc/"><abbr>GNU</abbr> C
Library</a>
has an independent, thread-safe implementation of
a <code><abbr>tz</abbr></code> binary file reader.
-This library is freely available under the
-<a href="http://www.gnu.org/copyleft/lesser.html">
-<abbr>GNU</abbr> Lesser General Public License
-(<abbr title="Lesser General Public License">LGPL</abbr>)</a>,
+This library is freely available under the LGPL
and is widely used in <abbr>GNU</abbr>/Linux systems.</li>
-<li><a href="https://www.gnome.org">GNOME</a>'s Glib has
+<li><a href="https://www.gnome.org">GNOME</a>'s
+<a href="https://developer.gnome.org/glib/">GLib</a> has
a <code><abbr>tz</abbr></code> binary file reader written in C that
creates a <code>GTimeZone</code> object representing sets
of <abbr>UT</abbr> offsets.
@@ -486,8 +488,8 @@ a <a href="https://wordpress.org">WordPr
available under a <abbr>BSD</abbr>-style license.</li>
<li><a href="http://www.relativedata.com/time-zone-master">Time Zone
Master</a> is a Microsoft Windows clock program that can automatically
-download, compile and use the <code>tzdata<var>D</var>.tar.gz</code>
-files as they are released. The Basic version is free.</li>
+download, compile and use <code>tz</code> releases. The Basic version
+is free.</li>
<li><a
href="http://veladg.com/velaterra.html">VelaTerra</a> is
an <abbr>OS X</abbr> program. Its developers
@@ -517,7 +519,8 @@ is another time zone database.</li>
<li><a href="http://tycho.usno.navy.mil/tzones.html">World Time Zones</a>
contains data from the Time Service Department of the
<abbr>US</abbr> Naval Observatory.</li>
-<li>The <a href="http://www.iata.org/publications/Pages/ssim.aspx">Standard
+<li>The <a
+href="http://www.iata.org/publications/store/Pages/standard-schedules-information.aspx">Standard
Schedules Information Manual</a> of the
International Air Transport Association
gives current time zone rules for airports served by commercial aviation.</li>
@@ -588,7 +591,7 @@ common.</li>
</ul>
<h2>Civil time concepts and history</h2>
<ul>
-<li><a href="http://www.nist.gov/pml/general/time/index.cfm">A
+<li><a href="http://physics.nist.gov/time">A
Walk through Time</a>
surveys the evolution of timekeeping.</li>
<li><a href="http://www.webexhibits.org/daylightsaving/">About Daylight
@@ -597,8 +600,6 @@ is an overall history of <abbr>DST</abbr
<li><a href="https://www.w3.org/TR/timezone/">Working with Time Zones</a>
contains guidelines and best practices for software applications that
deal with civil time.</li>
-<li><a href="http://energy.ca.gov/daylightsaving.html">Saving Time,
-Saving Energy</a> discusses a primary justification for <abbr>DST</abbr>.</li>
<li><a href="http://seizethedaylight.com/dst/">A Brief
History of Daylight Saving Time</a> summarizes some of the contentious
history of <abbr>DST</abbr>.</li>
@@ -656,7 +657,7 @@ hreflang="nl">Legal time in the Netherla
covers the history of local time in the Netherlands from ancient times.</dd>
<dt>New Zealand</dt>
<dd>The Department of Internal Affairs maintains a brief <a
-href="http://www.dia.govt.nz/Daylight-Saving-History">History of
+href="https://www.dia.govt.nz/Daylight-Saving-History">History of
Daylight Saving</a>. The privately-maintained <a
href="http://astrologyschool.com/nztime.html">History of New Zealand
time</a> has more details.</dd>
@@ -689,7 +690,8 @@ title="Network Time Protocol">NTP</abbr>
Time Protocol</a>
discusses how to synchronize clocks of
Internet hosts.</li>
-<li>The <a href="http://www.nist.gov/el/isd/ieee/ieee1588.cfm">Precision
+<li>The <a
+href="https://www.nist.gov/intelligent-systems-division/ieee-1588">Precision
Time Protocol</a> (<abbr
title="Institute of Electrical and Electronics Engineers">IEEE</abbr> 1588)
can achieve submicrosecond clock accuracy on a local area network.</li>
@@ -701,11 +703,6 @@ specifies a <a
href="https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol"><abbr>DHCP</abbr></a>
option for a server to configure
a client's time zone and daylight saving settings automatically.</li>
-<li><a href="http://gauss.gge.unb.ca/GMT.UT.and.the.RGO.html">A Few Facts
-Concerning <abbr>GMT</abbr>, <abbr>UT</abbr>, and
-the <abbr title="Royal Greenwich Observatory">RGO</abbr></a>
-answers questions like "What is the
-difference between <abbr>GMT</abbr> and <abbr>UTC</abbr>?"</li>
<li><a
href="http://www.cv.nrao.edu/~rfisher/Ephemerides/times.html">Astronomical
Times</a> explains more abstruse astronomical time scales like
@@ -714,7 +711,7 @@ Times</a> explains more abstruse astrono
<abbr title="Barycentric Dynamic Time">TDB</abbr>.
<a href="http://www.ucolick.org/~sla/leapsecs/timescales.html">Time
Scales</a> goes into more detail, particularly for historical variants.</li>
-<li>The <a href="http://iau.org"><abbr
+<li>The <a href="http://www.iau.org"><abbr
title="International Astronomical Union">IAU</abbr></a>'s <a
href="http://www.iausofa.org"><abbr
title="Standards Of Fundamental Astronomy">SOFA</abbr></a>
@@ -728,10 +725,8 @@ code for converting among time scales li
Space Flight – Reference Systems – Time Conventions</a>
briefly explains interplanetary space flight timekeeping.</li>
<li><a
-href="http://www.giss.nasa.gov/tools/mars24/help/notes.html">Technical
-Notes on Mars Solar Time as Adopted by the Mars24 Sunclock</a> briefly
-describes Mars Coordinated Time (<abbr
-title="Mars Coordinated Time">MTC</abbr>) and the
+href="http://www.giss.nasa.gov/tools/mars24/help/notes.html">Mars24 Sunclock
+– Time on Mars</a> describes Airy Mean Time (<abbr>AMT</abbr>) and the
diverse local time
scales used by each landed mission on Mars.</li>
<li><a href="http://leapsecond.com">LeapSecond.com</a> is
@@ -747,7 +742,7 @@ when leap seconds occur.</li>
<li>The <a
href="https://pairlist6.pair.net/mailman/listinfo/leapsecs">Leap
Second Discussion List</a> covers <a
-href="http://gauss.gge.unb.ca/papers.pdf/gpsworld.november99.pdf">McCarthy
+href="http://www2.unb.ca/gge/Resources/gpsworld.november99.pdf">McCarthy
and Klepczynski's proposal to discontinue leap seconds</a>,
discussed further in
<a href="http://www.cl.cam.ac.uk/~mgk25/time/metrologia-leapsecond.pdf">The
@@ -765,7 +760,7 @@ zone names, abbreviations, identifiers,
contains French translations for "Eastern European Summer Time",
"<abbr title="Eastern European Summer Time">EEST</abbr>", and
"Bucharest". Its
-<a href="http://unicode.org/cldr/charts/by_type/index.html">by-type
+<a href="http://www.unicode.org/cldr/charts/latest/by_type/">by-type
charts</a> show these values for many locales. Data values are available in
both <abbr title="Locale Data Markup Language">LDML</abbr>
(an <abbr>XML</abbr> format) and <abbr>JSON</abbr>.
@@ -809,10 +804,10 @@ practice. For example, in English-speaki
but in China it denotes 8 hours ahead of <abbr>UTC</abbr>,
and French-speaking North Americans prefer
"<abbr title="Heure Normale du Centre">HNC</abbr>" to
-"<abbr>CST</abbr>". For <abbr>POSIX</abbr> the <code><abbr>tz</abbr></code>
-database contains English abbreviations for all time stamps but in
-many cases these are merely inventions of the database
-maintainers.</li>
+"<abbr>CST</abbr>". The <code><abbr>tz</abbr></code>
+database contains English abbreviations for many time stamps;
+unfortunately some of these abbreviations were merely the database maintainers'
+inventions, and are gradually being removed.</li>
<li>Numeric time zone abbreviations typically count hours east of
<abbr>UTC</abbr>, e.g., +09 for Japan and
−10 for Hawaii. However, the <abbr>POSIX</abbr>
@@ -827,7 +822,7 @@ settings like <code><abbr>TZ</abbr>="Asi
confusion, handle old time stamps better, and insulate you better from
any future changes to the rules. One should never set
<abbr>POSIX</abbr> <code><abbr>TZ</abbr></code> to a value like
-<code>"GMT-9"</code>, though, since this would falsely claim that
+<code>"GMT-9"</code>, though, since this would incorrectly imply that
local time is nine hours ahead of <abbr>UTC</abbr> and the time zone
is called "<abbr>GMT</abbr>".</li>
</ul>
Index: src/lib/libc/time/tzfile.5
diff -u src/lib/libc/time/tzfile.5:1.23 src/lib/libc/time/tzfile.5:1.24
--- src/lib/libc/time/tzfile.5:1.23 Fri Oct 9 13:21:45 2015
+++ src/lib/libc/time/tzfile.5 Fri Oct 7 11:29:42 2016
@@ -1,8 +1,8 @@
-.\" $NetBSD: tzfile.5,v 1.23 2015/10/09 17:21:45 christos Exp $
+.\" $NetBSD: tzfile.5,v 1.24 2016/10/07 15:29:42 christos Exp $
.\"
.\" This file is in the public domain, so clarified as of
.\" 1996-06-05 by Arthur David Olson ([email protected]).
-.Dd October 6, 2014
+.Dd October 6, 2016
.Dt TZFILE 5
.Os
.Sh NAME
@@ -138,6 +138,13 @@ POSIX-TZ-environment-variable-style stri
after the last transition time stored in the file
(with nothing between the newlines if there is no POSIX representation for
such instants).
+The POSIX-style string must must agree with the local time type after
+both data's last transition times; for example, given the string
+.Dq WET0WEST,M3.5.0,M10.5.0/3
+then if a last transition time is in July, the transition's local time
+type must specify a daylight-saving time abbreviated
+.Dq WEST
+that is one hour east of UT.
.Pp
For version-3-format time zone files, the POSIX-TZ-style string may
use two minor extensions to the POSIX TZ format, as described in
Index: src/lib/libc/time/tzset.3
diff -u src/lib/libc/time/tzset.3:1.34 src/lib/libc/time/tzset.3:1.35
--- src/lib/libc/time/tzset.3:1.34 Thu Oct 29 18:42:55 2015
+++ src/lib/libc/time/tzset.3 Fri Oct 7 11:29:42 2016
@@ -1,5 +1,5 @@
-.\" $NetBSD: tzset.3,v 1.34 2015/10/29 22:42:55 wiz Exp $
-.Dd October 29, 2015
+.\" $NetBSD: tzset.3,v 1.35 2016/10/07 15:29:42 christos Exp $
+.Dd October 6, 2016
.Dt TZSET 3
.Os
.Sh NAME
@@ -186,6 +186,14 @@ is missing, then summer time does not ap
Upper- and lowercase letters are explicitly allowed.
Any characters except a leading colon (:), digits, comma (,), minus (-),
plus (+), and NUL bytes are allowed.
+Alternatively, a designation can be surrounded by angle brackets
+.Dv \*[Lt]
+and
+.Dv \*[Gt] ;
+in this case, the designation can contain any characters other than
+.Dv \*[Gt]
+and
+.Dv NUL .
.It Cm offset
Indicates the value one must add to the local time to arrive at
Coordinated Universal Time.
Index: src/lib/libc/time/zdump.8
diff -u src/lib/libc/time/zdump.8:1.14 src/lib/libc/time/zdump.8:1.15
--- src/lib/libc/time/zdump.8:1.14 Thu Oct 23 14:45:58 2014
+++ src/lib/libc/time/zdump.8 Fri Oct 7 11:29:42 2016
@@ -1,5 +1,5 @@
-.\" $NetBSD: zdump.8,v 1.14 2014/10/23 18:45:58 christos Exp $
-.Dd October 23, 2014
+.\" $NetBSD: zdump.8,v 1.15 2016/10/07 15:29:42 christos Exp $
+.Dd October 6, 2016
.Dt ZDUMP 8
.Os
.Sh NAME
@@ -26,7 +26,18 @@ These options are available:
.Bl -tag -width XXXXXXXXX -compact
.It Fl \-version
Output version information and exit.
+.It Fl i
+.Em This option is experimental: its behavior may change in future versions.
+Output a description of time intervals.
+For each
+.Ar zonename
+on the command line, output an interval-format description of the
+zone.
+See
+.Sx "INTERVAL FORMAT"
+below.
.It Fl v
+Output a verbose description of time intervals.
For each
.Ar zonename
on the command line,
@@ -37,30 +48,30 @@ each detected time discontinuity,
the time at one day less than the highest possible time value,
and the time at the highest possible time value.
Each line is followed by
-.Dl isdst= D
+.Em isdst=D
where
-.Dl D
+.Em D
is positive, zero, or negative depending on whether
the given time is daylight saving time, standard time,
or an unknown time type, respectively.
Each line is also followed by
-.Dl gmtoff= N
+.Em gmtoff=N
if the given local time is known to be
-.D N
+.Em N
seconds east of Greenwich.
.It Fl c Ar [loyear,]highyear
-Cut off verbose output at the given year(s).
+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
-.Dl loyear
+.Em loyear
of 1970 excludes a transition occurring at 1970-01-01 00:00:00 UTC but a
-.Dl hiyear
+.Em hiyear
of 1970 includes the transition.
The default cutoff is
-.Dl \*-500,2500 .
+.Em \&-500,2500 .
.It Fl t Ar [lotime,]hightime
-Cut off verbose output at the given time(s),
+Cut off interval output at the given time(s),
given in decimal seconds since 1970-01-01 00:00:00
Coordinated Universal Time (UTC).
The
@@ -76,13 +87,116 @@ except omit the times relative to the ex
This generates output that is easier to compare to that of
implementations with different time representations.
.El
+.Sh "INTERVAL FORMAT"
+.Em This format is experimental: it may change in future versions.
+.Pp
+The interval format is a compact text representation that is intended
+to be both human- and machine-readable.
+It consists of an empty line, then a line
+.Dq TZ=string
+where
+.Dv string
+is a double-quoted string giving the zone name, a second line
+.Dq \&- \&- interval
+describing the time interval before the first transition if any, and
+zero or more following lines
+.Dq date time interval
+one line for each transition time and following interval.
+Fields are separated by single tabs.
+.Pp
+Dates are in
+.Dv yyyy-mm-dd
+format and times are in 24-hour
+.Dv hh:mm:ss
+format where
+.Dv hh \*[Lt] 24 .
+Times are in local time immediately after the transition.
+A time interval description consists of a UT offset in signed
+.Dv \&+- hh : mm : ss
+format, a time zone abbreviation, and an isdst flag.
+An abbreviation that equals the UT offset is omitted; other abbreviations are
+double-quoted strings unless they consist of one or more alphabetic
+characters.
+An isdst flag is omitted for standard time, and otherwise
+is a decimal integer that is unsigned and positive (typically 1) for
+daylight saving time and negative for unknown.
+.Pp
+In times and UT offsets, the seconds are omitted if they are zero, and
+the minutes are also omitted if they are also zero.
+Positive UT offsets are east of Greenwich. The UT offset \&-00 denotes a UT
+placeholder in areas where the actual offset is unspecified; by
+convention, this occurs when the UT offset is zero and the time zone
+abbreviation begins with
+.Dq \&-
+or is
+.Dq zzz .
+.Pp
+In double-quoted strings, escape sequences represent unusual
+characters. The escape sequences are \es for space, and \e", \e\e,
+\ef, \en, \er, \et, and \ev with their usual meaning in the C
+programming language.
+E.g., the double-quoted string
+.Sq "CET\es\e"\e\e"
+represents the character sequence
+.Sq CET
+.Pp
+Here is an example of the output, with the leading empty line omitted.
+(This example is shown with tab stops set far enough apart so that the
+tabbed columns line up.)
+.Bd -literal
+TZ="Pacific/Honolulu"
+.Ed
+.Bl -column "XXXX-XX-XX" "HH:MM:SS" "-HH:MM:SS" "TZT" "X" -compact
+.It - Ta - Ta -10:31:26 Ta LMT Ta
+.It 1896-01-13 Ta 12:01:26 Ta -10:30 Ta HST Ta
+.It 1933-04-30 Ta 03 Ta -09:30 Ta HDT Ta 1
+.It 1933-05-21 Ta 11 Ta -10:30 Ta HST Ta
+.It 1942-02-09 Ta 03 Ta -09:30 Ta HDT Ta 1
+.It 1945-09-30 Ta 01 Ta -10:30 Ta HST Ta
+.It 1947-06-08 Ta 02:30 Ta -10 Ta HST Ta
+.El
+.Pp
+Here, local time begins 10 hours, 31 minutes and 26 seconds west of
+UT, and is a standard time abbreviated LMT. Immediately after the
+first transition, the date is 1896-01-13 and the time is 12:01:26, and
+the following time interval is 10.5 hours west of UT, a standard time
+abbreviated HST.
+Immediately after the second transition, the date is
+1933-04-30 and the time is 03:00:00 and the following time interval is
+9.5 hours west of UT, is abbreviated HDT, and is daylight saving time.
+Immediately after the last transition the date is 1947-06-08 and the
+time is 02:30:00, and the following time interval is 10 hours west of
+UT, a standard time abbreviated HST.
+.Pp
+Here are excerpts from another example:
+.Bd -literal
+TZ="Europe/Astrakhan"
+.Ed
+.Bl -column "XXXX-XX-XX" "HH:MM:SS" "-HH:MM:SS" "TZT" "X" -compact
+.It - Ta - Ta +03:12:12 Ta LMT Ta
+.It 1924-04-30 Ta 23:47:48 Ta +03 Ta Ta
+.It 1930-06-21 Ta 01 Ta +04 Ta Ta
+.It 1981-04-01 Ta 01 Ta +05 Ta Ta 1
+.It 1981-09-30 Ta 23 Ta +04 Ta Ta
+.It \&... Ta Ta Ta Ta
+.It 2014-10-26 Ta 01 Ta +03 Ta Ta
+.It 2016-03-27 Ta 03 Ta +04 Ta Ta
+.El
+.Pp
+This time zone is east of UT, so its UT offsets are positive. Also,
+many of its time zone abbreviations are omitted since they duplicate
+the text of the UT offset.
.Sh LIMITATIONS
Time discontinuities are found by sampling the results returned by localtime
at twelve-hour intervals.
This works in all real-world cases;
one can construct artificial time zones for which this fails.
.Pp
-In the output,
+In the
+.Fl v
+and
+.Fl V
+output,
.Dq UT
denotes the value returned by
.Xr gmtime 3 ,
@@ -92,8 +206,8 @@ No attempt is currently made to have the
.Dq UTC
for newer and
.Dq UT
-for older time stamps,
-partly because the exact date of the introduction of UTC is problematic.
+for older time stamps, partly because the exact date of the
+introduction of UTC is problematic.
.Sh SEE ALSO
.Xr ctime 3 ,
.Xr tzfile 5 ,
Index: src/lib/libc/time/zdump.c
diff -u src/lib/libc/time/zdump.c:1.43 src/lib/libc/time/zdump.c:1.44
--- src/lib/libc/time/zdump.c:1.43 Tue Mar 15 11:16:01 2016
+++ src/lib/libc/time/zdump.c Fri Oct 7 11:29:42 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: zdump.c,v 1.43 2016/03/15 15:16:01 christos Exp $ */
+/* $NetBSD: zdump.c,v 1.44 2016/10/07 15:29:42 christos Exp $ */
/*
** This file is in the public domain, so clarified as of
** 2009-05-17 by Arthur David Olson.
@@ -6,7 +6,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: zdump.c,v 1.43 2016/03/15 15:16:01 christos Exp $");
+__RCSID("$NetBSD: zdump.c,v 1.44 2016/10/07 15:29:42 christos Exp $");
#endif /* !defined lint */
/*
@@ -145,6 +145,26 @@ typedef long intmax_t;
# include <stdbool.h>
#endif
+#ifndef TYPE_BIT
+#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
+#endif /* !defined TYPE_BIT */
+
+#ifndef TYPE_SIGNED
+#define TYPE_SIGNED(type) (((type) -1) < 0)
+#endif /* !defined TYPE_SIGNED */
+
+#ifndef INT_STRLEN_MAXIMUM
+/*
+** 302 / 1000 is log10(2.0) rounded up.
+** Subtract one for the sign bit if the type is signed;
+** add one for integer division truncation;
+** add one more for a minus sign if the type is signed.
+*/
+#define INT_STRLEN_MAXIMUM(type) \
+ ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
+ 1 + TYPE_SIGNED(type))
+#endif /* !defined INT_STRLEN_MAXIMUM */
+
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif /* !defined EXIT_SUCCESS */
@@ -254,8 +274,9 @@ enum { SECSPER400YEARS_FITS = SECSPERLYE
# define timezone_t char **
#endif
-#if !HAVE_POSIX_DECLS
extern char ** environ;
+
+#if !HAVE_POSIX_DECLS
extern int getopt(int argc, char * const argv[],
const char * options);
extern char * optarg;
@@ -284,6 +305,8 @@ static intmax_t delta(struct tm *, struc
static void dumptime(struct tm const *);
static time_t hunt(timezone_t, char *, time_t, time_t);
static void show(timezone_t, char *, time_t, bool);
+static void showtrans(char const *, struct tm const *, time_t, char const *,
+ char const *);
static const char *tformat(void);
static time_t yeartot(intmax_t) ATTRIBUTE_PURE;
@@ -319,6 +342,19 @@ sumsize(size_t a, size_t b)
return sum;
}
+/* Return a pointer to a newly allocated buffer of size SIZE, exiting
+ on failure. SIZE should be nonzero. */
+static void *
+xmalloc(size_t size)
+{
+ void *p = malloc(size);
+ if (!p) {
+ perror(progname);
+ exit(EXIT_FAILURE);
+ }
+ return p;
+}
+
#if ! HAVE_TZSET
# undef tzset
# define tzset zdump_tzset
@@ -406,19 +442,13 @@ tzalloc(char const *val)
while (*e++)
continue;
- env = malloc(sumsize(sizeof *environ,
+ env = xmalloc(sumsize(sizeof *environ,
(e - environ) * sizeof *environ));
- if (! env) {
- err(EXIT_FAILURE, "malloc");
- }
to = 1;
for (e = environ; (env[to] = *e); e++)
to += strncmp(*e, "TZ=", 3) != 0;
}
- env0 = malloc(sumsize(sizeof "TZ=", strlen(val)));
- if (! env0) {
- err(EXIT_FAILURE, "malloc");
- }
+ env0 = xmalloc(sumsize(sizeof "TZ=", strlen(val)));
env[0] = strcat(strcpy(env0, "TZ="), val);
environ = fakeenv = env;
tzset();
@@ -537,10 +567,7 @@ saveabbr(char **buf, size_t *bufalloc, s
/* Make the new buffer at least twice as long as the
old, to avoid O(N**2) behavior on repeated calls. */
*bufalloc = sumsize(*bufalloc, ablen + 1);
- *buf = malloc(*bufalloc);
- if (! *buf) {
- err(EXIT_FAILURE, "malloc");
- }
+ *buf = xmalloc(*bufalloc);
}
return strcpy(*buf, ab);
}
@@ -560,10 +587,18 @@ __dead static void
usage(FILE *const stream, const int status)
{
(void) fprintf(stream,
-_("%s: usage: %s [--version] [--help] [-{vV}] [-{ct} [lo,]hi] zonename ...\n"
+_("%s: usage: %s OPTIONS ZONENAME ...\n"
+ "Options include:\n"
+ " -c [L,]U Start at year L (default -500), end before year U (default 2500)\n"
+ " -t [L,]U Start at time L, end before time U (in seconds since 1970)\n"
+ " -i List transitions briefly (format is experimental)\n" \
+ " -v List transitions verbosely\n"
+ " -V List transitions a bit less verbosely\n"
+ " --help Output this help\n"
+ " --version Output version info\n"
"\n"
"Report bugs to %s.\n"),
- progname, progname, REPORT_BUGS_TO);
+ progname, progname, REPORT_BUGS_TO);
if (status == EXIT_SUCCESS)
close_file(stream);
exit(status);
@@ -575,7 +610,6 @@ main(int argc, char *argv[])
/* These are static so that they're initially zero. */
static char * abbrev;
static size_t abbrevsize;
- static struct tm newtm;
int i;
bool vflag;
@@ -585,11 +619,7 @@ main(int argc, char *argv[])
time_t cutlotime;
time_t cuthitime;
time_t now;
- time_t t;
- time_t newt;
- struct tm tm;
- struct tm * tmp;
- struct tm * newtmp;
+ bool iflag = false;
cutlotime = absolute_min_time;
cuthitime = absolute_max_time;
@@ -611,9 +641,10 @@ main(int argc, char *argv[])
vflag = Vflag = false;
cutarg = cuttimes = NULL;
for (;;)
- switch (getopt(argc, argv, "c:t:vV")) {
+ switch (getopt(argc, argv, "c:it:vV")) {
case 'c': cutarg = optarg; break;
case 't': cuttimes = optarg; break;
+ case 'i': iflag = true; break;
case 'v': vflag = true; break;
case 'V': Vflag = true; break;
case -1:
@@ -625,7 +656,7 @@ main(int argc, char *argv[])
}
arg_processing_done:;
- if (vflag | Vflag) {
+ if (iflag | vflag | Vflag) {
intmax_t lo;
intmax_t hi;
char *loend, *hiend;
@@ -682,7 +713,9 @@ main(int argc, char *argv[])
}
}
gmtzinit();
- now = time(NULL);
+ INITIALIZE (now);
+ if (! (iflag | vflag | Vflag))
+ now = time(NULL);
longest = 0;
for (i = optind; i < argc; i++) {
size_t arglen = strlen(argv[i]);
@@ -693,49 +726,67 @@ main(int argc, char *argv[])
for (i = optind; i < argc; ++i) {
timezone_t tz = tzalloc(argv[i]);
char const *ab;
+ time_t t;
+ struct tm tm, newtm;
+ bool tm_ok;
+
if (!tz) {
errx(EXIT_FAILURE, "%s", argv[i]);
}
- if (! (vflag | Vflag)) {
+ if (! (iflag | vflag | Vflag)) {
show(tz, argv[i], now, false);
tzfree(tz);
continue;
}
warned = false;
t = absolute_min_time;
- if (!Vflag) {
+ if (! (iflag | Vflag)) {
show(tz, argv[i], t, true);
t += SECSPERDAY;
show(tz, argv[i], t, true);
}
if (t < cutlotime)
t = cutlotime;
- tmp = my_localtime_rz(tz, &t, &tm);
- if (tmp)
+ tm_ok = my_localtime_rz(tz, &t, &tm) != NULL;
+ if (tm_ok) {
ab = saveabbr(&abbrev, &abbrevsize, &tm);
- else
+ if (iflag) {
+ showtrans("\nTZ=%f", &tm, t, ab, argv[i]);
+ showtrans("-\t-\t%Q", &tm, t, ab, argv[i]);
+ }
+ } else
ab = NULL;
while (t < cuthitime) {
- newt = ((t < absolute_max_time - SECSPERDAY / 2
- && t + SECSPERDAY / 2 < cuthitime)
- ? t + SECSPERDAY / 2
- : cuthitime);
- newtmp = localtime_rz(tz, &newt, &newtm);
- if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) :
- (delta(&newtm, &tm) != (newt - t) ||
- newtm.tm_isdst != tm.tm_isdst ||
- strcmp(abbr(&newtm), ab) != 0)) {
+ time_t newt = ((t < absolute_max_time - SECSPERDAY / 2
+ && t + SECSPERDAY / 2 < cuthitime)
+ ? t + SECSPERDAY / 2 : cuthitime);
+ struct tm *newtmp = localtime_rz(tz, &newt, &newtm);
+ bool newtm_ok = newtmp != NULL;
+ if (! (tm_ok & newtm_ok
+ ? (delta(&newtm, &tm) == newt - t
+ && newtm.tm_isdst == tm.tm_isdst
+ && strcmp(abbr(&newtm), ab) == 0)
+ : tm_ok == newtm_ok)) {
newt = hunt(tz, argv[i], t, newt);
newtmp = localtime_rz(tz, &newt, &newtm);
- if (newtmp)
- ab = saveabbr(&abbrev, &abbrevsize,
- &newtm);
+ newtm_ok = newtmp != NULL;
+ if (iflag)
+ showtrans("%Y-%m-%d\t%L\t%Q",
+ newtmp, newt, newtm_ok ?
+ abbr(&newtm) : NULL, argv[i]);
+ else {
+ show(tz, argv[i], newt - 1, true);
+ show(tz, argv[i], newt, true);
+ }
}
t = newt;
- tm = newtm;
- tmp = newtmp;
+ tm_ok = newtm_ok;
+ if (newtm_ok) {
+ ab = saveabbr(&abbrev, &abbrevsize, &newtm);
+ tm = newtm;
+ }
}
- if (!Vflag) {
+ if (! (iflag | Vflag)) {
t = absolute_max_time;
t -= SECSPERDAY;
show(tz, argv[i], t, true);
@@ -801,12 +852,11 @@ hunt(timezone_t tz, char *name, time_t l
char const * ab;
time_t t;
struct tm lotm;
- struct tm * lotmp;
struct tm tm;
- struct tm * tmp;
+ bool lotm_ok = my_localtime_rz(tz, &lot, &lotm) != NULL;
+ bool tm_ok;
- lotmp = my_localtime_rz(tz, &lot, &lotm);
- if (lotmp)
+ if (lotm_ok)
ab = saveabbr(&loab, &loabsize, &lotm);
else
ab = NULL;
@@ -820,18 +870,17 @@ hunt(timezone_t tz, char *name, time_t l
++t;
else if (t >= hit)
--t;
- tmp = my_localtime_rz(tz, &t, &tm);
- if ((lotmp == NULL || tmp == NULL) ? (lotmp == tmp) :
- (delta(&tm, &lotm) == (t - lot) &&
- tm.tm_isdst == lotm.tm_isdst &&
- strcmp(abbr(&tm), ab) == 0)) {
- lot = t;
- lotm = tm;
- lotmp = tmp;
+ tm_ok = my_localtime_rz(tz, &t, &tm) != NULL;
+ if (lotm_ok & tm_ok
+ ? (delta(&tm, &lotm) == t - lot
+ && tm.tm_isdst == lotm.tm_isdst
+ && strcmp(abbr(&tm), ab) == 0)
+ : lotm_ok == tm_ok) {
+ lot = t;
+ if (tm_ok)
+ lotm = tm;
} else hit = t;
}
- show(tz, name, lot, true);
- show(tz, name, hit, true);
return hit;
}
@@ -875,13 +924,20 @@ adjusted_yday(struct tm const *a, struct
/* If A is the broken-down local time and B the broken-down UTC for
the same instant, return A's UTC offset in seconds, where positive
- offsets are east of Greenwich. On failure, return LONG_MIN. */
+ offsets are east of Greenwich. On failure, return LONG_MIN.
+
+ If T is nonnull, *T is the time stamp that corresponds to A; call
+ my_gmtime_r and use its result instead of B. Otherwise, B is the
+ possibly nonnull result of an earlier call to my_gmtime_r. */
static long
-gmtoff(struct tm const *a, struct tm const *b)
+gmtoff(struct tm const *a, time_t *t, struct tm const *b)
{
#ifdef TM_GMTOFF
return a->TM_GMTOFF;
#else
+ struct tm tm;
+ if (t)
+ b = my_gmtime_r(t, &tm);
if (! b)
return LONG_MIN;
else {
@@ -920,7 +976,7 @@ show(timezone_t tz, char *zone, time_t t
if (*abbr(tmp) != '\0')
(void) printf(" %s", abbr(tmp));
if (v) {
- long off = gmtoff(tmp, gmtmp);
+ long off = gmtoff(tmp, NULL, gmtmp);
(void) printf(" isdst=%d", tmp->tm_isdst);
if (off != LONG_MIN)
(void) printf(" gmtoff=%ld", off);
@@ -931,6 +987,204 @@ show(timezone_t tz, char *zone, time_t t
abbrok(abbr(tmp), zone);
}
+/* Store into BUF, of size SIZE, a formatted local time taken from *TM.
+ Use ISO 8601 format +HH:MM:SS. Omit :SS if SS is zero, and omit
+ :MM too if MM is also zero.
+
+ Return the length of the resulting string. If the string does not
+ fit, return the length that the string would have been if it had
+ fit; do not overrun the output buffer. */
+static int
+format_local_time(char *buf, size_t size, struct tm const *tm)
+{
+ int ss = tm->tm_sec, mm = tm->tm_min, hh = tm->tm_hour;
+ return (ss
+ ? snprintf(buf, size, "%02d:%02d:%02d", hh, mm, ss)
+ : mm
+ ? snprintf(buf, size, "%02d:%02d", hh, mm)
+ : snprintf(buf, size, "%02d", hh));
+}
+
+/* Store into BUF, of size SIZE, a formatted UTC offset for the
+ localtime *TM corresponding to time T. Use ISO 8601 format
+ +HH:MM:SS, or -HH:MM:SS for time stamps west of Greenwich. Omit
+ :SS if :SS is zero, and omit :MM too if :MM is also zero. If the
+ time stamp represents an unknown UTC offset, use the format -00.
+
+ Return the length of the resulting string, or -1 if the result is
+ not representable as a string. If the string does not fit, return
+ the length that the string would have been if it had fit; do not
+ overrun the output buffer. */
+static int
+format_utc_offset(char *buf, size_t size, struct tm const *tm, time_t t)
+{
+ long off = gmtoff(tm, &t, NULL);
+ char sign = ((off < 0
+ || (off == 0
+ && (*abbr(tm) == '-' || strcmp(abbr(tm), "zzz") == 0)))
+ ? '-' : '+');
+ long hh;
+ int mm, ss;
+ if (off < 0)
+ {
+ if (off == LONG_MIN)
+ return -1;
+ off = -off;
+ }
+ ss = off % 60;
+ mm = off / 60 % 60;
+ hh = off / 60 / 60;
+ return (ss
+ ? snprintf(buf, size, "%c%02ld:%02d:%02d", sign, hh, mm, ss)
+ : mm
+ ? snprintf(buf, size, "%c%02ld:%02d", sign, hh, mm)
+ : snprintf(buf, size, "%c%02ld", sign, hh));
+}
+
+/* Store into BUF (of size SIZE) a quoted string representation of P.
+ If the representation's length is less than SIZE, return the
+ length; the representation is not null terminated. Otherwise
+ return SIZE, to indicate that BUF is too small. */
+static size_t
+format_quoted_string(char *buf, size_t size, char const *p)
+{
+ char *b = buf;
+ size_t s = size;
+ if (!s)
+ return size;
+ *b++ = '"', s--;
+ for (;;) {
+ char c = *p++;
+ if (s <= 1)
+ return size;
+ switch (c) {
+ default: *b++ = c, s--; continue;
+ case '\0': *b++ = '"', s--; return size - s;
+ case '"': case '\\': break;
+ case ' ': c = 's'; break;
+ case '\f': c = 'f'; break;
+ case '\n': c = 'n'; break;
+ case '\r': c = 'r'; break;
+ case '\t': c = 't'; break;
+ case '\v': c = 'v'; break;
+ }
+ *b++ = '\\', *b++ = c, s -= 2;
+ }
+}
+
+/* Store into BUF (of size SIZE) a time stamp formatted by TIME_FMT.
+ TM is the broken-down time, T the seconds count, AB the time zone
+ abbreviation, and ZONE_NAME the zone name. Return true if
+ successful, false if the output would require more than SIZE bytes.
+ TIME_FMT uses the same format that strftime uses, with these
+ additions:
+
+ %f zone name
+ %L local time as per format_local_time
+ %Q like "U\t%Z\tD" where U is the UTC offset as for format_utc_offset
+ and D is the isdst flag; except omit D if it is zero, omit %Z if
+ it equals U, quote and escape %Z if it contains nonalphabetics,
+ and omit any trailing tabs. */
+
+static bool
+istrftime(char *buf, size_t size, char const *time_fmt,
+ struct tm const *tm, time_t t, char const *ab, char const *zone_name)
+{
+ char *b = buf;
+ size_t s = size;
+ char const *f = time_fmt, *p;
+
+ for (p = f; ; p++)
+ if (*p == '%' && p[1] == '%')
+ p++;
+ else if (!*p
+ || (*p == '%'
+ && (p[1] == 'f' || p[1] == 'L' || p[1] == 'Q'))) {
+ size_t formatted_len;
+ size_t f_prefix_len = p - f;
+ size_t f_prefix_copy_size = p - f + 2;
+ char fbuf[100];
+ bool oversized = sizeof fbuf <= f_prefix_copy_size;
+ char *f_prefix_copy = oversized ? xmalloc(f_prefix_copy_size) : fbuf;
+ memcpy(f_prefix_copy, f, f_prefix_len);
+ strcpy(f_prefix_copy + f_prefix_len, "X");
+ formatted_len = strftime(b, s, f_prefix_copy, tm);
+ if (oversized)
+ free(f_prefix_copy);
+ if (formatted_len == 0)
+ return false;
+ formatted_len--;
+ b += formatted_len, s -= formatted_len;
+ if (!*p++)
+ break;
+ switch (*p) {
+ case 'f':
+ formatted_len = format_quoted_string(b, s, zone_name);
+ break;
+ case 'L':
+ formatted_len = format_local_time(b, s, tm);
+ break;
+ case 'Q':
+ {
+ bool show_abbr;
+ int offlen = format_utc_offset(b, s, tm, t);
+ if (! (0 <= offlen && (size_t)offlen < s))
+ return false;
+ show_abbr = strcmp(b, ab) != 0;
+ b += offlen, s -= offlen;
+ if (show_abbr) {
+ char const *abp;
+ size_t len;
+ if (s <= 1)
+ return false;
+ *b++ = '\t', s--;
+ for (abp = ab; is_alpha(*abp); abp++)
+ continue;
+ len = (!*abp && *ab
+ ? (size_t)snprintf(b, s, "%s", ab)
+ : format_quoted_string(b, s, ab));
+ if (s <= len)
+ return false;
+ b += len, s -= len;
+ }
+ formatted_len = (tm->tm_isdst
+ ? snprintf(b, s, &"\t\t%d"[show_abbr], tm->tm_isdst)
+ : 0);
+ }
+ break;
+ }
+ if (! (formatted_len < s))
+ return false;
+ b += formatted_len, s -= formatted_len;
+ f = p + 1;
+ }
+ *b = '\0';
+ return true;
+}
+
+/* Show a time transition. */
+static void
+showtrans(char const *time_fmt, struct tm const *tm, time_t t, char const *ab,
+ char const *zone_name)
+{
+ if (!tm) {
+ printf(tformat(), t);
+ putchar('\n');
+ } else {
+ char stackbuf[1000];
+ size_t size = sizeof stackbuf;
+ char *buf = stackbuf;
+ char *bufalloc = NULL;
+ while (! istrftime(buf, size, time_fmt, tm, t, ab, zone_name)) {
+ size = sumsize(size, size);
+ free(bufalloc);
+ buf = bufalloc = xmalloc(size);
+ }
+ puts(buf);
+ free(bufalloc);
+ }
+}
+
static const char *
abbr(struct tm const *tmp)
{
Index: src/lib/libc/time/zic.c
diff -u src/lib/libc/time/zic.c:1.62 src/lib/libc/time/zic.c:1.63
--- src/lib/libc/time/zic.c:1.62 Tue Sep 20 11:03:07 2016
+++ src/lib/libc/time/zic.c Fri Oct 7 11:29:42 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: zic.c,v 1.62 2016/09/20 15:03:07 christos Exp $ */
+/* $NetBSD: zic.c,v 1.63 2016/10/07 15:29:42 christos Exp $ */
/*
** This file is in the public domain, so clarified as of
** 2006-07-17 by Arthur David Olson.
@@ -10,7 +10,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: zic.c,v 1.62 2016/09/20 15:03:07 christos Exp $");
+__RCSID("$NetBSD: zic.c,v 1.63 2016/10/07 15:29:42 christos Exp $");
#endif /* !defined lint */
#include "private.h"
@@ -19,6 +19,7 @@ __RCSID("$NetBSD: zic.c,v 1.62 2016/09/2
#include <stdarg.h>
#include <unistd.h>
+#include <util.h>
#define ZIC_VERSION_PRE_2013 '2'
#define ZIC_VERSION '3'
@@ -116,7 +117,9 @@ extern int optind;
# define link(from, to) (errno = ENOTSUP, -1)
#endif
#if ! HAVE_SYMLINK
+# define lstat(name, st) stat(name, st)
# define symlink(from, to) (errno = ENOTSUP, -1)
+# define S_ISLNK(m) 0
#endif
static void addtt(zic_t starttime, int type);
@@ -124,7 +127,7 @@ static int addtype(zic_t, char const *,
static void leapadd(zic_t, bool, int, int);
static void adjleap(void);
static void associate(void);
-static void dolink(const char * fromfield, const char * tofield);
+static void dolink(const char *, const char *, bool);
static char ** getfields(char * buf);
static zic_t gethms(const char * string, const char * errstring,
bool);
@@ -138,7 +141,7 @@ static bool inzsub(char **, int, int);
static int itsdir(const char * name);
static bool is_alpha(char a);
static char lowerit(char);
-static bool mkdirs(char *);
+static void mkdirs(char const *, bool);
static void newabbr(const char * abbr);
static zic_t oadd(zic_t t1, zic_t t2);
static void outzone(const struct zone * zp, int ntzones);
@@ -154,7 +157,7 @@ static bool yearistype(int year, const c
enum { PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1 };
/* If true, work around a bug in Qt 5.6.1 and earlier, which mishandles
- tzdata binary files whose POSIX-TZ-style strings contain '<'; see
+ tz binary files whose POSIX-TZ-style strings contain '<'; see
QTBUG-53071 <https://bugreports.qt.io/browse/QTBUG-53071>. This
workaround will no longer be needed when Qt 5.6.1 and earlier are
obsolete, say in the year 2021. */
@@ -365,6 +368,7 @@ static const int len_years[2] = {
static struct attype {
zic_t at;
+ bool dontmerge;
unsigned char type;
} * attypes;
static zic_t gmtoffs[TZ_MAX_TYPES];
@@ -506,15 +510,15 @@ warning(const char *const string, ...)
}
static void
-close_file(FILE *stream, char const *name)
+close_file(FILE *stream, char const *dir, char const *name)
{
char const *e = (ferror(stream) ? _("I/O error")
: fclose(stream) != 0 ? strerror(errno) : NULL);
if (e) {
- fprintf(stderr, "%s: ", progname);
- if (name)
- fprintf(stderr, "%s: ", name);
- fprintf(stderr, "%s\n", e);
+ fprintf(stderr, "%s: %s%s%s%s%s\n", progname,
+ dir ? dir : "", dir ? "/" : "",
+ name ? name : "", name ? ": " : "",
+ e);
exit(EXIT_FAILURE);
}
}
@@ -529,10 +533,30 @@ usage(FILE *stream, int status)
"Report bugs to %s.\n"),
progname, progname, REPORT_BUGS_TO);
if (status == EXIT_SUCCESS)
- close_file(stream, NULL);
+ close_file(stream, NULL, NULL);
exit(status);
}
+/* Change the working directory to DIR, possibly creating DIR and its
+ ancestors. After this is done, all files are accessed with names
+ relative to DIR. */
+static void
+change_directory (char const *dir)
+{
+ if (chdir(dir) != 0) {
+ int chdir_errno = errno;
+ if (chdir_errno == ENOENT) {
+ mkdirs(dir, false);
+ chdir_errno = chdir(dir) == 0 ? 0 : errno;
+ }
+ if (chdir_errno != 0) {
+ fprintf(stderr, _("%s: Can't chdir to %s: %s\n"),
+ progname, dir, strerror(chdir_errno));
+ exit(EXIT_FAILURE);
+ }
+ }
+}
+
static const char * psxrules;
static const char * lcltime;
static const char * directory;
@@ -565,7 +589,7 @@ main(int argc, char **argv)
for (i = 1; i < argc; ++i)
if (strcmp(argv[i], "--version") == 0) {
printf("zic %s%s\n", PKGVERSION, TZVERSION);
- close_file(stdout, NULL);
+ close_file(stdout, NULL, NULL);
return EXIT_SUCCESS;
} else if (strcmp(argv[i], "--help") == 0) {
usage(stdout, EXIT_SUCCESS);
@@ -648,6 +672,7 @@ _("%s: More than one -L option specified
if (errors)
return EXIT_FAILURE;
associate();
+ change_directory(directory);
for (i = 0; i < nzones; i = j) {
/*
** Find the next non-continuation zone entry.
@@ -661,7 +686,7 @@ _("%s: More than one -L option specified
*/
for (i = 0; i < nlinks; ++i) {
eat(links[i].l_filename, links[i].l_linenum);
- dolink(links[i].l_from, links[i].l_to);
+ dolink(links[i].l_from, links[i].l_to, false);
if (noise)
for (j = 0; j < nlinks; ++j)
if (strcmp(links[i].l_to,
@@ -670,11 +695,11 @@ _("%s: More than one -L option specified
}
if (lcltime != NULL) {
eat(_("command line"), 1);
- dolink(lcltime, TZDEFAULT);
+ dolink(lcltime, TZDEFAULT, true);
}
if (psxrules != NULL) {
eat(_("command line"), 1);
- dolink(psxrules, TZDEFRULES);
+ dolink(psxrules, TZDEFRULES, true);
}
if (warnings && (ferror(stderr) || fclose(stderr) != 0))
return EXIT_FAILURE;
@@ -751,112 +776,99 @@ namecheck(const char *name)
return componentcheck(name, component, cp);
}
-static char *
-relname(char const *dir, char const *base)
-{
- if (*base == '/')
- return ecpyalloc(base);
- else {
- size_t dir_len = strlen(dir);
- bool needs_slash = dir_len && dir[dir_len - 1] != '/';
- char *result = zic_malloc(dir_len + needs_slash + strlen(base) + 1);
- result[dir_len] = '/';
- strcpy(result + dir_len + needs_slash, base);
- return memcpy(result, dir, dir_len);
- }
-}
-
static void
-dolink(char const *fromfield, char const *tofield)
+dolink(char const *fromfield, char const *tofield, bool staysymlink)
{
- char * fromname;
- char * toname;
int fromisdir;
+ bool todirs_made = false;
+ int link_errno;
- fromname = relname(directory, fromfield);
- toname = relname(directory, tofield);
/*
** We get to be careful here since
** there's a fair chance of root running us.
*/
- fromisdir = itsdir(fromname);
+ fromisdir = itsdir(fromfield);
if (fromisdir) {
char const *e = strerror(fromisdir < 0 ? errno : EPERM);
- fprintf(stderr, _("%s: link from %s failed: %s"),
- progname, fromname, e);
+ fprintf(stderr, _("%s: link from %s/%s failed: %s\n"),
+ progname, directory, fromfield, e);
exit(EXIT_FAILURE);
}
- if (link(fromname, toname) != 0) {
- int link_errno = errno;
- bool retry_if_link_supported = false;
-
- if (link_errno == ENOENT || link_errno == ENOTSUP) {
- if (! mkdirs(toname))
- exit(EXIT_FAILURE);
- retry_if_link_supported = true;
+ if (staysymlink)
+ staysymlink = itsdir(tofield) == 2;
+ if (remove(tofield) == 0)
+ todirs_made = true;
+ else if (errno != ENOENT) {
+ char const *e = strerror(errno);
+ fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"),
+ progname, directory, tofield, e);
+ exit(EXIT_FAILURE);
+ }
+ link_errno = (staysymlink ? ENOTSUP
+ : link(fromfield, tofield) == 0 ? 0 : errno);
+ if (link_errno == ENOENT && !todirs_made) {
+ mkdirs(tofield, true);
+ todirs_made = true;
+ link_errno = link(fromfield, tofield) == 0 ? 0 : errno;
+ }
+ if (link_errno != 0) {
+ const char *s = fromfield;
+ const char *t;
+ char *p;
+ size_t dotdots = 0;
+ char *symlinkcontents;
+ int symlink_errno;
+
+ do
+ t = s;
+ while ((s = strchr(s, '/'))
+ && strncmp(fromfield, tofield, ++s - fromfield) == 0);
+
+ for (s = tofield + (t - fromfield); *s; s++)
+ dotdots += *s == '/';
+ symlinkcontents = emalloc(3 * dotdots + strlen(t) + 1);
+ for (p = symlinkcontents; dotdots-- != 0; p += 3)
+ memcpy(p, "../", 3);
+ strcpy(p, t);
+ symlink_errno = symlink(symlinkcontents, tofield) == 0 ? 0 : errno;
+ if (symlink_errno == ENOENT && !todirs_made) {
+ mkdirs(tofield, true);
+ symlink_errno = symlink(symlinkcontents, tofield) == 0 ? 0 : errno;
}
- if ((link_errno == EEXIST || link_errno == ENOTSUP)
- && itsdir(toname) == 0
- && (remove(toname) == 0 || errno == ENOENT))
- retry_if_link_supported = true;
- if (retry_if_link_supported && link_errno != ENOTSUP)
- link_errno = link(fromname, toname) == 0 ? 0 : errno;
- if (link_errno != 0) {
- const char *s = fromfield;
- const char *t;
- char *p;
- size_t dotdots = 0;
- char *symlinkcontents;
- int symlink_result;
-
- do
- t = s;
- while ((s = strchr(s, '/'))
- && strncmp(fromfield, tofield, ++s - fromfield) == 0);
-
- for (s = tofield + (t - fromfield); *s; s++)
- dotdots += *s == '/';
- symlinkcontents = zic_malloc(3 * dotdots + strlen(t) + 1);
- for (p = symlinkcontents; dotdots-- != 0; p += 3)
- memcpy(p, "../", 3);
- strcpy(p, t);
- symlink_result = symlink(symlinkcontents, toname);
- free(symlinkcontents);
- if (symlink_result == 0) {
- if (link_errno != ENOTSUP)
- warning(_("symbolic link used because hard link failed: %s"),
- strerror (link_errno));
- } else {
- FILE *fp, *tp;
- int c;
- fp = fopen(fromname, "rb");
- if (!fp) {
- const char *e = strerror(errno);
- fprintf(stderr,
- _("%s: Can't read %s: %s\n"),
- progname, fromname, e);
- exit(EXIT_FAILURE);
- }
- tp = fopen(toname, "wb");
- if (!tp) {
- const char *e = strerror(errno);
- fprintf(stderr,
- _("%s: Can't create %s: %s\n"),
- progname, toname, e);
- exit(EXIT_FAILURE);
- }
- while ((c = getc(fp)) != EOF)
- putc(c, tp);
- close_file(fp, fromname);
- close_file(tp, toname);
- if (link_errno != ENOTSUP)
- warning(_("copy used because hard link failed: %s"),
- strerror (link_errno));
+ free(symlinkcontents);
+ if (symlink_errno == 0) {
+ if (link_errno != ENOTSUP)
+ warning(_("symbolic link used because hard link failed: %s"),
+ strerror(link_errno));
+ } else {
+ FILE *fp, *tp;
+ int c;
+ fp = fopen(fromfield, "rb");
+ if (!fp) {
+ char const *e = strerror(errno);
+ fprintf(stderr, _("%s: Can't read %s/%s: %s\n"),
+ progname, directory, fromfield, e);
+ exit(EXIT_FAILURE);
+ }
+ tp = fopen(tofield, "wb");
+ if (!tp) {
+ char const *e = strerror(errno);
+ fprintf(stderr, _("%s: Can't create %s/%s: %s\n"),
+ progname, directory, tofield, e);
+ exit(EXIT_FAILURE);
}
+ while ((c = getc(fp)) != EOF)
+ putc(c, tp);
+ close_file(fp, directory, fromfield);
+ close_file(tp, directory, tofield);
+ if (link_errno != ENOTSUP)
+ warning(_("copy used because hard link failed: %s"),
+ strerror(link_errno));
+ else if (symlink_errno != ENOTSUP)
+ warning(_("copy used because symbolic link failed: %s"),
+ strerror(symlink_errno));
}
}
- free(fromname);
- free(toname);
}
#define TIME_T_BITS_IN_FILE 64
@@ -902,21 +914,26 @@ static const zic_t early_time = (WORK_AR
? BIG_BANG
: MINVAL(zic_t, TIME_T_BITS_IN_FILE));
-/* Return 1 if NAME is a directory, 0 if it's something else, -1 if trouble. */
+/* Return 1 if NAME is a directory, 2 if a symbolic link, 0 if
+ something else, -1 (setting errno) if trouble. */
static int
itsdir(char const *name)
{
struct stat st;
- int res = stat(name, &st);
+ int res = lstat(name, &st);
+ if (res == 0) {
#ifdef S_ISDIR
- if (res == 0)
- return S_ISDIR(st.st_mode) != 0;
-#endif
- if (res == 0 || errno == EOVERFLOW) {
- char *nameslashdot = relname(name, ".");
- bool dir = stat(nameslashdot, &st) == 0 || errno == EOVERFLOW;
+ return S_ISDIR(st.st_mode) ? 1 : S_ISLNK(st.st_mode) ? 2 : 0;
+#else
+ size_t n = strlen(name);
+ char *nameslashdot = emalloc(n + 3);
+ bool dir;
+ memcpy(nameslashdot, name, n);
+ strcpy(&nameslashdot[n], &"/."[! (n && name[n - 1] != '/')]);
+ dir = lstat(nameslashdot, &st) == 0;
free(nameslashdot);
return dir;
+#endif
}
return -1;
}
@@ -1090,7 +1107,7 @@ _("%s: panic: Invalid l_value %d\n"),
}
free(fields);
}
- close_file(fp, filename);
+ close_file(fp, NULL, filename);
if (wantcont)
error(_("expected continuation line not found"));
}
@@ -1640,9 +1657,9 @@ writezone(const char *const name, const
int leapcnt32, leapi32;
int timecnt32, timei32;
int pass;
- char * fullname;
static const struct tzhead tzh0;
static struct tzhead tzh;
+ bool dir_checked = false;
zic_t one = 1;
zic_t y2038_boundary = one << 31;
int nats = timecnt + WORK_AROUND_QTBUG_53071;
@@ -1675,8 +1692,9 @@ writezone(const char *const name, const
attypes[fromi].type;
continue;
}
- if (toi == 0 ||
- attypes[toi - 1].type != attypes[fromi].type)
+ if (toi == 0
+ || attypes[fromi].dontmerge
+ || attypes[toi - 1].type != attypes[fromi].type)
attypes[toi++] = attypes[fromi];
}
timecnt = toi;
@@ -1741,27 +1759,31 @@ writezone(const char *const name, const
--leapcnt32;
++leapi32;
}
- fullname = relname(directory, name);
/*
** Remove old file, if any, to snap links.
*/
- if (itsdir(fullname) == 0 && remove(fullname) != 0 && errno != ENOENT) {
+ if (remove(name) == 0)
+ dir_checked = true;
+ else if (errno != ENOENT) {
const char *e = strerror(errno);
- fprintf(stderr, _("%s: Can't remove %s: %s\n"),
- progname, fullname, e);
+ fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"),
+ progname, directory, name, e);
exit(EXIT_FAILURE);
}
- if ((fp = fopen(fullname, "wb")) == NULL) {
- if (! mkdirs(fullname))
- exit(EXIT_FAILURE);
- if ((fp = fopen(fullname, "wb")) == NULL) {
- const char *e = strerror(errno);
-
- fprintf(stderr, _("%s: Can't create %s: %s\n"),
- progname, fullname, e);
- exit(EXIT_FAILURE);
- }
+ fp = fopen(name, "wb");
+ if (!fp) {
+ int fopen_errno = errno;
+ if (fopen_errno == ENOENT && !dir_checked) {
+ mkdirs(name, true);
+ fp = fopen(name, "wb");
+ fopen_errno = errno;
+ }
+ if (!fp) {
+ fprintf(stderr, _("%s: Can't create %s/%s: %s\n"),
+ progname, directory, name, strerror(fopen_errno));
+ exit(EXIT_FAILURE);
+ }
}
for (pass = 1; pass <= 2; ++pass) {
int thistimei, thistimecnt;
@@ -1957,9 +1979,8 @@ writezone(const char *const name, const
putc(ttisgmts[i], fp);
}
fprintf(fp, "\n%s\n", string);
- close_file(fp, fullname);
+ close_file(fp, directory, name);
free(ats);
- free(fullname);
}
static char const *
@@ -2303,6 +2324,7 @@ outzone(const struct zone *zpfirst, int
int compat;
bool do_extend;
int version;
+ int lastatmax = -1;
max_abbr_len = 2 + max_format_len + max_abbrvar_len;
max_envvar_len = 2 * max_abbr_len + 5 * 9;
@@ -2539,6 +2561,10 @@ outzone(const struct zone *zpfirst, int
offset = oadd(zp->z_gmtoff, rp->r_stdoff);
type = addtype(offset, ab, rp->r_stdoff != 0,
rp->r_todisstd, rp->r_todisgmt);
+ if (rp->r_hiyear == ZIC_MAX
+ && ! (0 <= lastatmax
+ && ktime < attypes[lastatmax].at))
+ lastatmax = timecnt;
addtt(ktime, type);
}
}
@@ -2571,6 +2597,8 @@ error(_("can't determine time zone abbre
starttime = tadd(starttime, -gmtoff);
}
}
+ if (0 <= lastatmax)
+ attypes[lastatmax].dontmerge = true;
if (do_extend) {
/*
** If we're extending the explicitly listed observations
@@ -2593,21 +2621,8 @@ error(_("can't determine time zone abbre
if (attypes[i].at > lastat->at)
lastat = &attypes[i];
if (lastat->at < rpytime(&xr, max_year - 1)) {
- /*
- ** Create new type code for the redundant entry,
- ** to prevent it being optimized away.
- */
- if (typecnt >= TZ_MAX_TYPES) {
- error(_("too many local time types"));
- exit(EXIT_FAILURE);
- }
- gmtoffs[typecnt] = gmtoffs[lastat->type];
- isdsts[typecnt] = isdsts[lastat->type];
- ttisstds[typecnt] = ttisstds[lastat->type];
- ttisgmts[typecnt] = ttisgmts[lastat->type];
- abbrinds[typecnt] = abbrinds[lastat->type];
- ++typecnt;
addtt(rpytime(&xr, max_year + 1), typecnt-1);
+ attypes[timecnt - 1].dontmerge = true;
}
}
writezone(zpfirst->z_name, envvar, version);
@@ -2635,6 +2650,7 @@ addtt(zic_t starttime, int type)
}
attypes = growalloc(attypes, sizeof *attypes, timecnt, &timecnt_alloc);
attypes[timecnt].at = starttime;
+ attypes[timecnt].dontmerge = false;
attypes[timecnt].type = type;
++timecnt;
}
@@ -3041,45 +3057,46 @@ mp = _("time zone abbreviation differs f
strncpy(&chars[charcnt], string, sizeof(chars) - charcnt - 1);
charcnt += i;
}
-
-static bool
-mkdirs(char *argname)
+
+/* Ensure that the directories of ARGNAME exist, by making any missing
+ ones. If ANCESTORS, do this only for ARGNAME's ancestors; otherwise,
+ do it for ARGNAME too. Exit with failure if there is trouble. */
+static void
+mkdirs(char const *argname, bool ancestors)
{
char * name;
char * cp;
- if (argname == NULL || *argname == '\0')
- return true;
cp = name = ecpyalloc(argname);
- while ((cp = strchr(cp + 1, '/')) != 0) {
- *cp = '\0';
+
+ /* Do not mkdir a root directory, as it must exist. */
#ifdef HAVE_DOS_FILE_NAMES
- /*
- ** DOS drive specifier?
- */
- if (is_alpha(name[0]) && name[1] == ':' && name[2] == '\0') {
- *cp = '/';
- continue;
- }
+ if (is_alpha(name[0]) && name[1] == ':')
+ cp += 2;
#endif
+ while (*cp == '/')
+ cp++;
+
+ while (cp && ((cp = strchr(cp, '/')) || !ancestors)) {
+ if (cp)
+ *cp = '\0';
/*
** Try to create it. It's OK if creation fails because
** the directory already exists, perhaps because some
- ** other process just created it.
+ ** other process just created it. For simplicity do
+ ** not check first whether it already exists, as that
+ ** is checked anyway if the mkdir fails.
*/
if (mkdir(name, MKDIR_UMASK) != 0) {
int err = errno;
- if (itsdir(name) <= 0) {
- char const *e = strerror(err);
- warning(_("%s: Can't create directory"
- " %s: %s"),
- progname, name, e);
- free(name);
- return false;
- }
+ if (err != EEXIST && itsdir(name) < 0) {
+ error(_("%s: Can't create directory %s: %s"),
+ progname, name, strerror(err));
+ exit(EXIT_FAILURE);
+ }
}
- *cp = '/';
+ if (cp)
+ *cp++ = '/';
}
free(name);
- return true;
}