# 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= 2016i
# Email address for bug reports.
BUGEMAIL= tz@iana.org
YEARISTYPE= ./yearistype
# Non-default libraries needed to link.
-# Add -lintl if you want to use 'gettext' on Solaris.
LDLIBS=
# Add the following to the end of the "CFLAGS=" line as needed.
# -DHAVE_DECL_ASCTIME_R=0 if <time.h> does not declare asctime_r
# -DHAVE_DIRECT_H if mkdir needs <direct.h> (MS-Windows)
# -DHAVE_DOS_FILE_NAMES if file names have drive specifiers etc. (MS-DOS)
-# -DHAVE_GETTEXT=1 if 'gettext' works (GNU, Linux, Solaris); also see LDLIBS
+# -DHAVE_GETTEXT=1 if 'gettext' works (e.g., GNU/Linux, FreeBSD, Solaris)
# -DHAVE_INCOMPATIBLE_CTIME_R=1 if your system's time.h declares
-# ctime_r and asctime_r incompatibly with the POSIX standard (Solaris 8).
+# ctime_r and asctime_r incompatibly with the POSIX standard
+# (Solaris when _POSIX_PTHREAD_SEMANTICS is not defined).
# -DHAVE_INTTYPES_H=1 if you have a pre-C99 compiler with "inttypes.h"
# -DHAVE_LINK=0 if your system lacks a link function
# -DHAVE_LOCALTIME_R=0 if your system lacks a localtime_r function
# -DHAVE_SYS_WAIT_H=0 if your compiler lacks a "sys/wait.h"
# -DHAVE_TZSET=0 if your system lacks a tzset function
# -DHAVE_UNISTD_H=0 if your compiler lacks a "unistd.h" (Microsoft C++ 7?)
+# -DEPOCH_LOCAL=1 if the 'time' function returns local time not UT
+# -DEPOCH_OFFSET=N if the 'time' function returns a value N greater
+# than what POSIX specifies, assuming local time is UT.
+# For example, N is 252460800 on AmigaOS.
# -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU=1
# if you do not want run time warnings about formats that may cause
# year 2000 grief
CFLAGS=
# Linker flags. Default to $(LFLAGS) for backwards compatibility
-# to tzcode2012h and earlier.
+# to release 2012h and earlier.
LDFLAGS= $(LFLAGS)
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)
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 = \
# 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 :; \
time2posix.3.txt \
tzfile.5.txt tzselect.8.txt zic.8.txt zdump.8.txt \
date.1.txt
-COMMON= CONTRIBUTING LICENSE Makefile NEWS README Theory
+COMMON= CONTRIBUTING LICENSE Makefile NEWS README Theory version
WEB_PAGES= tz-art.htm tz-how-to.html tz-link.htm
DOCS= $(MANS) date.1 $(MANTXTS) $(WEB_PAGES)
PRIMARY_YDATA= africa antarctica asia australasia \
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. . .
cp date $(DESTDIR)$(BINDIR)/.
cp -f date.1 $(DESTDIR)$(MANDIR)/man1/.
-version.h:
- (echo 'static char const PKGVERSION[]="($(PACKAGE)) ";' && \
- echo 'static char const TZVERSION[]="$(VERSION)";' && \
- echo 'static char const REPORT_BUGS_TO[]="$(BUGEMAIL)";') >$@
+version: $(VERSION_DEPS)
+ { (type git) >/dev/null 2>&1 && \
+ V=`git describe --match '[0-9][0-9][0-9][0-9][a-z]*' \
+ --abbrev=7 --dirty` || \
+ V=$(VERSION); } && \
+ printf '%s\n' "$$V" >$@.out
+ mv $@.out $@
+
+version.h: version
+ VERSION=`cat version` && printf '%s\n' \
+ 'static char const PKGVERSION[]="($(PACKAGE)) ";' \
+ "static char const TZVERSION[]=\"$$VERSION\";" \
+ 'static char const REPORT_BUGS_TO[]="$(BUGEMAIL)";' \
+ >$@.out
+ mv $@.out $@
zdump: $(TZDOBJS)
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(TZDOBJS) $(LDLIBS)
chmod +x yearistype
leapseconds: $(LEAP_DEPS)
- $(AWK) -f leapseconds.awk leap-seconds.list >$@
+ $(AWK) -f leapseconds.awk leap-seconds.list >$@.out
+ mv $@.out $@
# Arguments to pass to submakes of install_data.
# They can be overridden by later submake arguments.
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 >$@.out
+ wd=`pwd` && \
+ zones=`$(AWK) -v wd="$$wd" \
+ '/^Zone/{print wd "/tzs.dir/" $$2}' $(TDATA) \
+ | LC_ALL=C sort` && \
+ ./zdump -i -c $(TZS_YEAR) $$zones >>$@.out
+ sed 's,^TZ=".*tzs\.dir/,TZ=",' $@.out >$@.sed.out
+ rm -fr tzs.dir $@.out
+ mv $@.sed.out $@
+
+# 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) $@
date: $(DATEOBJS)
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(DATEOBJS) $(LDLIBS)
-tzselect: tzselect.ksh
- sed \
+tzselect: tzselect.ksh version
+ VERSION=`cat 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)|' \
- <$? >$@
- chmod +x $@
+ -e 's|\(TZVERSION\)=.*|\1='"$$VERSION"'|' \
+ <$@.ksh >$@.out
+ chmod +x $@.out
+ mv $@.out $@
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 && \
sharp='#' && \
- ! grep -Env $(SAFE_LINE) Makefile $(MANS) date.1 $(MANTXTS) \
- $(MISC) $(SOURCES) $(WEB_PAGES) && \
+ ! grep -Env $(SAFE_LINE) $(MANS) date.1 $(MANTXTS) \
+ $(MISC) $(SOURCES) $(WEB_PAGES) \
+ CONTRIBUTING LICENSE Makefile README version && \
! grep -Env $(SAFE_SHARP_LINE) $(TDATA) backzone \
leapseconds yearistype.sh zone.tab && \
! grep -Env $(OK_LINE) $(ENCHILADA)
check_white_space: $(ENCHILADA)
- ! grep -En ' '$(TAB_CHAR)"|$$(printf '[\f\r\v]')" $(ENCHILADA)
+ patfmt=' \t|[\f\r\v]' && pat=`printf "$$patfmt\\n"` && \
+ ! grep -En "$$pat" $(ENCHILADA)
! grep -n '[[:space:]]$$' $(ENCHILADA)
CHECK_CC_LIST = { n = split($$1,a,/,/); for (i=2; i<=n; i++) print a[1], a[i]; }
|| exit; \
done
+check_tzs: $(TZS) $(TZS_NEW)
+ diff -u $(TZS) $(TZS_NEW)
+
check_web: $(WEB_PAGES)
$(VALIDATE_ENV) $(VALIDATE) $(VALIDATE_FLAGS) $(WEB_PAGES)
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)
zic.8.txt: zic.8
$(MANTXTS): workman.sh
- LC_ALL=C sh workman.sh `expr $@ : '\(.*\)\.txt$$'` >$@
+ LC_ALL=C sh workman.sh `expr $@ : '\(.*\)\.txt$$'` >$@.out
+ mv $@.out $@
# Set the time stamps to those of the git repository, if available,
# and if the files have not changed since then.
# to be the maximum of the files it depends on.
set-timestamps.out: $(ENCHILADA)
rm -f $@
- if files=`git ls-files $(ENCHILADA)` && \
+ if (type git) >/dev/null 2>&1 && \
+ files=`git ls-files $(ENCHILADA)` && \
touch -md @1 test.out; then \
rm -f test.out && \
for file in $$files; do \
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.
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.
else \
quiet_option=''; \
fi && \
+ wd=`pwd` && \
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="$$wd/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;; \
*) 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: tzcode$(VERSION).tar.gz tzdata$(VERSION).tar.gz
+tarballs traditional_tarballs signatures traditional_signatures: version
+ VERSION=`cat version` && \
+ $(MAKE) VERSION="$$VERSION" $@_version
+
+tarballs_version: traditional_tarballs_version tzdb-$(VERSION).tar.lz
+traditional_tarballs_version: \
+ tzcode$(VERSION).tar.gz tzdata$(VERSION).tar.gz
+signatures_version: traditional_signatures_version tzdb-$(VERSION).tar.lz.asc
+traditional_signatures_version: \
+ tzcode$(VERSION).tar.gz.asc tzdata$(VERSION).tar.gz.asc \
tzcode$(VERSION).tar.gz: set-timestamps.out
LC_ALL=C && export LC_ALL && \
tar $(TARFLAGS) -cf - \
$(COMMON) $(DOCS) $(SOURCES) | \
- gzip $(GZIPFLAGS) > $@
+ gzip $(GZIPFLAGS) >$@.out
+ mv $@.out $@
tzdata$(VERSION).tar.gz: set-timestamps.out
LC_ALL=C && export LC_ALL && \
tar $(TARFLAGS) -cf - $(COMMON) $(DATA) $(MISC) | \
- gzip $(GZIPFLAGS) > $@
-
-signatures: tzcode$(VERSION).tar.gz.asc tzdata$(VERSION).tar.gz.asc
+ gzip $(GZIPFLAGS) >$@.out
+ mv $@.out $@
+
+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 >$@.out
+ mv $@.out $@
tzcode$(VERSION).tar.gz.asc: tzcode$(VERSION).tar.gz
gpg --armor --detach-sign $?
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; \
.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
News for the tz database
+Release 2016i - 2016-11-01 23:19:52 -0700
+
+ Briefly: Cyprus split into two time zones on 2016-10-30, and Tonga
+ reintroduces DST on 2016-11-06.
+
+ Changes to future time stamps
+
+ Pacific/Tongatapu begins DST on 2016-11-06 at 02:00, ending on
+ 2017-01-15 at 03:00. Assume future observances in Tonga will be
+ from the first Sunday in November through the third Sunday in
+ January, like Fiji. (Thanks to Pulu ʻAnau.) Switch to numeric
+ time zone abbreviations for this zone.
+
+ Changes to past and future time stamps
+
+ Northern Cyprus is now +03 year round, causing a split in Cyprus
+ time zones starting 2016-10-30 at 04:00. This creates a zone
+ Asia/Famagusta. (Thanks to Even Scharning and Matt Johnson.)
+
+ Antarctica/Casey switched from +08 to +11 on 2016-10-22.
+ (Thanks to Steffen Thorsen.)
+
+ Changes to past time stamps
+
+ Several corrections were made for pre-1975 time stamps in Italy.
+ These affect Europe/Malta, Europe/Rome, Europe/San_Marino, and
+ Europe/Vatican.
+
+ First, the 1893-11-01 00:00 transition in Italy used the new UT
+ offset (+01), not the old (+00:49:56). (Thanks to Michael
+ Deckers.)
+
+ Second, rules for daylight saving in Italy were changed to agree
+ with Italy's National Institute of Metrological Research (INRiM)
+ except for 1944, as follows (thanks to Pierpaolo Bernardi, Brian
+ Inglis, and Michael Deckers):
+
+ The 1916-06-03 transition was at 24:00, not 00:00.
+
+ The 1916-10-01, 1919-10-05, and 1920-09-19 transitions were at
+ 00:00, not 01:00.
+
+ The 1917-09-30 and 1918-10-06 transitions were at 24:00, not
+ 01:00.
+
+ The 1944-09-17 transition was at 03:00, not 01:00. This
+ particular change is taken from Italian law as INRiM's table,
+ (which says 02:00) appears to have a typo here. Also, keep the
+ 1944-04-03 transition for Europe/Rome, as Rome was controlled by
+ Germany then.
+
+ The 1967-1970 and 1972-1974 fallback transitions were at 01:00,
+ not 00:00.
+
+ Changes to code
+
+ The code should now be buildable on AmigaOS merely by setting the
+ appropriate Makefile variables. (From a patch by Carsten Larsen.)
+
+
+Release 2016h - 2016-10-19 23:17:57 -0700
+
+ Changes to future time stamps
+
+ Asia/Gaza and Asia/Hebron end DST on 2016-10-29 at 01:00, not
+ 2016-10-21 at 00:00. (Thanks to Sharef Mustafa.) Predict that
+ future fall transitions will be on the last Saturday of October
+ at 01:00, which is consistent with predicted spring transitions
+ on the last Saturday of March. (Thanks to Tim Parenti.)
+
+ Changes to past time stamps
+
+ In Turkey, transitions in 1986-1990 were at 01:00 standard time
+ not at 02:00, and the spring 1994 transition was on March 20, not
+ March 27. (Thanks to Kıvanç Yazan.)
+
+ Changes to past and future time zone abbreviations
+
+ Asia/Colombo now uses numeric time zone abbreviations like "+0530"
+ instead of alphabetic ones like "IST" and "LKT". Various
+ English-language sources use "IST", "LKT" and "SLST", with no
+ working consensus. (Usage of "SLST" mentioned by Sadika
+ Sumanapala.)
+
+ Changes to code
+
+ zic no longer mishandles relativizing file names when creating
+ symbolic links like /etc/localtime, when these symbolic links
+ are outside the usual directory hierarchy. This fixes a bug
+ introduced in 2016g. (Problem reported by Andreas Stieger.)
+
+ Changes to build procedure
+
+ New rules 'traditional_tarballs' and 'traditional_signatures' for
+ building just the traditional-format distribution. (Requested by
+ Deborah Goldsmith.)
+
+ The file 'version' is now put into the tzdata tarball too.
+ (Requested by Howard Hinnant.)
+
+ Changes to documentation and commentary
+
+ The 'Theory' file now has a section on interface stability.
+ (Requested by Paul Koning.) It also mentions features like
+ tm_zone and localtime_rz that have long been supported by the
+ reference code.
+
+ tz-link.htm has improved coverage of time zone boundaries suitable
+ for geolocation. (Thanks to heads-ups from Evan Siroky and Matt
+ Johnson.)
+
+ The US commentary now mentions Allen and the "day of two noons".
+
+ The Fiji commentary mentions the government's 2016-10-03 press
+ release. (Thanks to Raymond Kumar.)
+
+
+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
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.)
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.
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.)
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
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
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.
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
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)
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
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
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.)
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.)
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
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.
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).
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,
* 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
rules change (as in the United States in 1987), all programs that
do time conversion must be recompiled to ensure proper results.
+* The TZ environment variable is process-global, which makes it hard
+ to write efficient, thread-safe applications that need access
+ to multiple time zones.
+
* In POSIX, there's no tamper-proof way for a process to learn the
system's best idea of local wall clock. (This is important for
applications that an administrator wants used only at certain times -
daylight saving time shifts - as might be required to limit phone
calls to off-peak hours.)
+* POSIX provides no convenient and efficient way to determine the UT
+ offset and time zone abbreviation of arbitrary time stamps,
+ particularly for time zone settings that do not fit into the
+ POSIX model.
+
* POSIX requires that systems ignore leap seconds.
* The tz code attempts to support all the time_t implementations
"new" programs (a la POSIX) and "old" programs (as zone names and
offsets).
-* To handle places where more than two time zone abbreviations are used,
- the functions "localtime" and "gmtime" set tzname[tmp->tm_isdst]
- (where "tmp" is the value the function returns) to the time zone
- abbreviation to be used. This differs from POSIX, where the elements
- of tzname are only changed as a result of calls to tzset.
+* The code supports platforms with a UT offset member in struct tm,
+ e.g., tm_gmtoff.
+
+* The code supports platforms with a time zone abbreviation member in
+ struct tm, e.g., tm_zone.
* Since the "TZ" environment variable can now be used to control time
conversion, the "daylight" and "timezone" variables are no longer
needed. (These variables are defined and set by "tzset"; however, their
values will not be used by "localtime.")
-* The "localtime" function has been set up to deliver correct results
- for near-minimum or near-maximum time_t values. (A comment in the
- source code tells how to get compatibly wrong results).
+* Functions tzalloc, tzfree, localtime_rz, and mktime_z for
+ more-efficient thread-safe applications that need to use
+ multiple time zones. The tzalloc and tzfree functions
+ allocate and free objects of type timezone_t, and localtime_rz
+ and mktime_z are like localtime_r and mktime with an extra
+ timezone_t argument. The functions were inspired by NetBSD.
* A function "tzsetwall" has been added to arrange for the system's
best approximation to local wall clock time to be delivered by
Points of interest to folks with other systems:
-* This package is already part of many POSIX-compliant hosts,
- including BSD, HP, Linux, Network Appliance, SCO, SGI, and Sun.
+* Code compatible with this package is already part of many platforms,
+ including GNU/Linux, Android, the BSDs, Chromium OS, Cygwin, AIX, iOS,
+ BlackBery 10, macOS, Microsoft Windows, OpenVMS, and Solaris.
On such hosts, the primary use of this package
is to update obsolete time zone rule tables.
To do this, you may need to compile the time zone compiler
'zic' supplied with this package instead of using the system 'zic',
- since the format of zic's input changed slightly in late 1994,
- and many vendors still do not support the new input format.
+ since the format of zic's input is occasionally extended,
+ and a platform may still be shipping an older zic.
* The UNIX Version 7 "timezone" function is not present in this package;
it's impossible to reliably map timezone's arguments (a "minutes west
* In SVR2, time conversion fails for near-minimum or near-maximum
time_t values when doing conversions for places that don't use UT.
This package takes care to do these conversions correctly.
+ A comment in the source code tells how to get compatibly wrong
+ results.
The functions that are conditionally compiled if STD_INSPIRED is defined
should, at this point, be looked on primarily as food for thought. They are
better.
+----- Interface stability -----
+
+The tz code and data supply the following interfaces:
+
+ * A set of zone names as per "Names of time zone rules" above.
+
+ * Library functions described in "Time and date functions" above.
+
+ * The programs tzselect, zdump, and zic, documented in their man pages.
+
+ * The format of zic input files, documented in the zic man page.
+
+ * The format of zic output files, documented in the tzfile man page.
+
+ * The format of zone table files, documented in zone1970.tab.
+
+ * The format of the country code file, documented in iso3166.tab.
+
+When these interfaces are changed, an effort is made to preserve
+backward compatibility. For example, tz data files typically do not
+rely on recently-added zic features, so that users can run older zic
+versions to process newer data files.
+
+Interfaces not listed above are less stable. For example, users
+should not rely on particular UT offsets or abbreviations for time
+stamps, as data entries are often based on guesswork and these guesses
+may be corrected or improved.
+
+
----- Calendrical issues -----
Calendrical issues are a bit out of scope for a time zone database,
# http://www.libyaherald.com/2013/10/24/correction-no-time-change-tomorrow/
#
# From Paul Eggert (2013-10-25):
-# For now, assume they're reverting to the pre-2012 rules of permanent UTC+2.
+# For now, assume they're reverting to the pre-2012 rules of permanent UT +02.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Libya 1951 only - Oct 14 2:00 1:00 S
# http://www.spri.cam.ac.uk/bob/periant.htm
# for information.
# Unless otherwise specified, we have no time zone information.
-#
-# Except for the French entries,
-# I made up all time zone abbreviations mentioned here; corrections welcome!
+
# FORMAT is '-00' and GMTOFF is 0 for locations while uninhabited.
# Argentina - year-round bases
# previously sealers and scientific personnel wintered
# Margaret Turner reports
# http://web.archive.org/web/20021204222245/http://www.dstc.qut.edu.au/DST/marg/daylight.html
-# (1999-09-30) that they're UTC+5, with no DST;
+# (1999-09-30) that they're UT +05, with no DST;
# presumably this is when they have visitors.
#
# year-round bases
# Background:
# http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
+# From Steffen Thorsen (2016-10-28):
+# Australian Antarctica Division informed us that Casey changed time
+# zone to UTC+11 in "the morning of 22nd October 2016".
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Casey 0 - -00 1969
- 8:00 - AWST 2009 Oct 18 2:00
- # Australian Western Std Time
- 11:00 - CAST 2010 Mar 5 2:00 # Casey Time
- 8:00 - AWST 2011 Oct 28 2:00
- 11:00 - CAST 2012 Feb 21 17:00u
- 8:00 - AWST
+ 8:00 - +08 2009 Oct 18 2:00
+ 11:00 - +11 2010 Mar 5 2:00
+ 8:00 - +08 2011 Oct 28 2:00
+ 11:00 - +11 2012 Feb 21 17:00u
+ 8:00 - +08 2016 Oct 22
+ 11:00 - +11
Zone Antarctica/Davis 0 - -00 1957 Jan 13
- 7:00 - DAVT 1964 Nov # Davis Time
+ 7:00 - +07 1964 Nov
0 - -00 1969 Feb
- 7:00 - DAVT 2009 Oct 18 2:00
- 5:00 - DAVT 2010 Mar 10 20:00u
- 7:00 - DAVT 2011 Oct 28 2:00
- 5:00 - DAVT 2012 Feb 21 20:00u
- 7:00 - DAVT
+ 7:00 - +07 2009 Oct 18 2:00
+ 5:00 - +05 2010 Mar 10 20:00u
+ 7:00 - +07 2011 Oct 28 2:00
+ 5:00 - +05 2012 Feb 21 20:00u
+ 7:00 - +07
Zone Antarctica/Mawson 0 - -00 1954 Feb 13
- 6:00 - MAWT 2009 Oct 18 2:00 # Mawson Time
- 5:00 - MAWT
+ 6:00 - +06 2009 Oct 18 2:00
+ 5:00 - +05
# References:
# Casey Weather (1998-02-26)
# http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Indian/Kerguelen 0 - -00 1950 # Port-aux-Français
- 5:00 - TFT # ISO code TF Time
+ 5:00 - +05
#
# year-round base in the main continent
# Dumont d'Urville, Île des Pétrels, -6640+14001, since 1956-11
# It was destroyed by fire on 1952-01-14.
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Antarctica/DumontDUrville 0 - zzz 1947
- 10:00 - PMT 1952 Jan 14 # Port-Martin Time
- 0 - zzz 1956 Nov
- 10:00 - DDUT # Dumont-d'Urville Time
+Zone Antarctica/DumontDUrville 0 - -00 1947
+ 10:00 - +10 1952 Jan 14
+ 0 - -00 1956 Nov
+ 10:00 - +10
# France & Italy - year-round base
# Concordia, -750600+1232000, since 2005
# correct, but they should be quite close to the actual dates.
#
# From Paul Eggert (2014-03-21):
-# The CET-switching Troll rules require zic from tzcode 2014b or later, so as
+# The CET-switching Troll rules require zic from tz 2014b or later, so as
# suggested by Bengt-Inge Larsson comment them out for now, and approximate
# with only UTC and CEST. Uncomment them when 2014b is more prevalent.
#
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-#Rule Troll 2005 max - Mar 1 1:00u 1:00 CET
-Rule Troll 2005 max - Mar lastSun 1:00u 2:00 CEST
-#Rule Troll 2005 max - Oct lastSun 1:00u 1:00 CET
-#Rule Troll 2004 max - Nov 7 1:00u 0:00 UTC
+#Rule Troll 2005 max - Mar 1 1:00u 1:00 +01
+Rule Troll 2005 max - Mar lastSun 1:00u 2:00 +02
+#Rule Troll 2005 max - Oct lastSun 1:00u 1:00 +01
+#Rule Troll 2004 max - Nov 7 1:00u 0:00 +00
# Remove the following line when uncommenting the above '#Rule' lines.
-Rule Troll 2004 max - Oct lastSun 1:00u 0:00 UTC
+Rule Troll 2004 max - Oct lastSun 1:00u 0:00 +00
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Antarctica/Troll 0 - -00 2005 Feb 12
0:00 Troll %s
# http://www.worldtimezone.com/dst_news/dst_news_armenia03.html
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Yerevan 2:58:00 - LMT 1924 May 2
- 3:00 - YERT 1957 Mar # Yerevan Time
- 4:00 RussiaAsia YER%sT 1991 Mar 31 2:00s
- 3:00 1:00 YERST 1991 Sep 23 # independence
- 3:00 RussiaAsia AM%sT 1995 Sep 24 2:00s
- 4:00 - AMT 1997
- 4:00 RussiaAsia AM%sT 2012 Feb 9
- 4:00 - AMT
+ 3:00 - +03 1957 Mar
+ 4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s
+ 3:00 RussiaAsia +03/+04 1995 Sep 24 2:00s
+ 4:00 - +04 1997
+ 4:00 RussiaAsia +04/+05
# Azerbaijan
Rule Azer 1997 2015 - Oct lastSun 5:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Baku 3:19:24 - LMT 1924 May 2
- 3:00 - BAKT 1957 Mar # Baku Time
- 4:00 RussiaAsia BAK%sT 1991 Mar 31 2:00s
- 3:00 1:00 BAKST 1991 Aug 30 # independence
- 3:00 RussiaAsia AZ%sT 1992 Sep lastSun 2:00s
- 4:00 - AZT 1996 # Azerbaijan Time
- 4:00 EUAsia AZ%sT 1997
- 4:00 Azer AZ%sT
+ 3:00 - +03 1957 Mar
+ 4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s
+ 3:00 RussiaAsia +03/+04 1992 Sep lastSun 2:00s
+ 4:00 - +04 1996
+ 4:00 EUAsia +04/+05 1997
+ 4:00 Azer +04/+05
# Bahrain
# See Asia/Qatar.
# Milne says 6:24:40 was the meridian of the time ball observatory at Rangoon.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Asia/Rangoon 6:24:40 - LMT 1880 # or Yangon
+Zone Asia/Yangon 6:24:40 - LMT 1880 # or Rangoon
6:24:40 - RMT 1920 # Rangoon Mean Time?
6:30 - BURT 1942 May # Burma Time
9:00 - JST 1945 May 3
# Lewiston (ME) Daily Sun (1939-05-29), p 17, said "Even the time is
# different - the occupied districts going by Tokyo time, an hour
# ahead of that prevailing in the rest of Shanghai." Guess that the
-# Xujiahui Observatory was under French control and stuck with UT+8.
+# Xujiahui Observatory was under French control and stuck with UT +08.
#
# In earlier versions of this file, China had many separate Zone entries, but
# this was based on what were apparently incorrect data in Shanks & Pottenger.
# Proposed in 1918 and theoretically in effect until 1949 (although in practice
# mainly observed in coastal areas), the five zones were:
#
-# Changbai Time ("Long-white Time", Long-white = Heilongjiang area) UT+8.5
+# Changbai Time ("Long-white Time", Long-white = Heilongjiang area) UT +08:30
# Asia/Harbin (currently a link to Asia/Shanghai)
# Heilongjiang (except Mohe county), Jilin
#
-# Zhongyuan Time ("Central plain Time") UT+8
+# Zhongyuan Time ("Central plain Time") UT +08
# Asia/Shanghai
# most of China
# This currently represents most other zones as well,
# as apparently these regions have been the same since 1970.
# Milne gives 8:05:43.2 for Xujiahui Observatory time; round to nearest.
-# Guo says Shanghai switched to UT+8 "from the end of the 19th century".
+# Guo says Shanghai switched to UT +08 "from the end of the 19th century".
#
-# Long-shu Time (probably due to Long and Shu being two names of that area) UT+7
+# Long-shu Time (probably due to Long and Shu being two names of the area) UT +07
# Asia/Chongqing (currently a link to Asia/Shanghai)
# Guangxi, Guizhou, Hainan, Ningxia, Sichuan, Shaanxi, and Yunnan;
# most of Gansu; west Inner Mongolia; west Qinghai; and the Guangdong
# counties Deqing, Enping, Kaiping, Luoding, Taishan, Xinxing,
# Yangchun, Yangjiang, Yu'nan, and Yunfu.
#
-# Xin-zang Time ("Xinjiang-Tibet Time") UT+6
+# Xin-zang Time ("Xinjiang-Tibet Time") UT +06
# Asia/Urumqi
# This currently represents Kunlun Time as well,
# as apparently the two regions have been the same since 1970.
# Shihezi, Changji, Yanqi, Heshuo, Tuokexun, Tulufan, Shanshan, Hami,
# Fukang, Kuitun, Kumukuli, Miquan, Qitai, and Turfan.
#
-# Kunlun Time UT+5.5
+# Kunlun Time UT +05:30
# Asia/Kashgar (currently a link to Asia/Urumqi)
# West Tibet, including Pulan, Aheqi, Shufu, Shule;
# West Xinjiang, including Aksu, Atushi, Yining, Hetian, Cele, Luopu, Nileke,
# having the same time as Beijing.
# From Paul Eggert (2014-06-30):
-# In the early days of the PRC, Tibet was given its own time zone (UT+6) but
-# this was withdrawn in 1959 and never reinstated; see Tubten Khétsun,
+# In the early days of the PRC, Tibet was given its own time zone (UT +06)
+# but this was withdrawn in 1959 and never reinstated; see Tubten Khétsun,
# Memories of life in Lhasa under Chinese Rule, Columbia U Press, ISBN
# 978-0231142861 (2008), translator's introduction by Matthew Akester, p x.
# As this is before our 1970 cutoff, Tibet doesn't need a separate zone.
# Republics, the Soviet Union, the Kuomintang, and the People's Republic of
# China, and tracking down all these organizations' timekeeping rules would be
# quite a trick. Approximate this lost history by a transition from LMT to
-# XJT at the start of 1928, the year of accession of the warlord Jin Shuren,
+# UT +06 at the start of 1928, the year of accession of the warlord Jin Shuren,
# which happens to be the date given by Shanks & Pottenger (no doubt as a
-# guess) as the transition from LMT. Ignore the usage of UT+8 before
-# 1986-02-01 under the theory that the transition date to UT+8 is unknown and
+# guess) as the transition from LMT. Ignore the usage of +08 before
+# 1986-02-01 under the theory that the transition date to +08 is unknown and
# that the sort of users who prefer Asia/Urumqi now typically ignored the
-# UT+8 mandate back then.
+# +08 mandate back then.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
# Beijing time, used throughout China; represented by Shanghai.
# be found from historical government announcement database.
# From Paul Eggert (2014-07-03):
-# As per Yu-Cheng Chuang, say that Taiwan was at UT+9 from 1937-10-01
+# As per Yu-Cheng Chuang, say that Taiwan was at UT +09 from 1937-10-01
# until 1945-09-21 at 01:00, overriding Shanks & Pottenger.
# Likewise, use Yu-Cheng Chuang's data for DST in Taiwan.
###############################################################################
# Cyprus
-#
+
# Milne says the Eastern Telegraph Company used 2:14:00. Stick with LMT.
+# IATA SSIM (1998-09) has Cyprus using EU rules for the first time.
+
+# From Paul Eggert (2016-09-09):
+# Yesterday's Cyprus Mail reports that Northern Cyprus followed Turkey's
+# lead and switched from +02/+03 to +03 year-round.
+# http://cyprus-mail.com/2016/09/08/two-time-zones-cyprus-turkey-will-not-turn-clocks-back-next-month/
#
+# From Even Scharning (2016-10-31):
+# Looks like the time zone split in Cyprus went through last night.
+# http://cyprus-mail.com/2016/10/30/cyprus-new-division-two-time-zones-now-reality/
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Cyprus 1975 only - Apr 13 0:00 1:00 S
Rule Cyprus 1975 only - Oct 12 0:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Tbilisi 2:59:11 - LMT 1880
2:59:11 - TBMT 1924 May 2 # Tbilisi Mean Time
- 3:00 - TBIT 1957 Mar # Tbilisi Time
- 4:00 RussiaAsia TBI%sT 1991 Mar 31 2:00s
- 3:00 1:00 TBIST 1991 Apr 9 # independence
- 3:00 RussiaAsia GE%sT 1992 # Georgia Time
- 3:00 E-EurAsia GE%sT 1994 Sep lastSun
- 4:00 E-EurAsia GE%sT 1996 Oct lastSun
- 4:00 1:00 GEST 1997 Mar lastSun
- 4:00 E-EurAsia GE%sT 2004 Jun 27
- 3:00 RussiaAsia GE%sT 2005 Mar lastSun 2:00
- 4:00 - GET
+ 3:00 - +03 1957 Mar
+ 4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s
+ 3:00 RussiaAsia +03/+04 1992
+ 3:00 E-EurAsia +03/+04 1994 Sep lastSun
+ 4:00 E-EurAsia +04/+05 1996 Oct lastSun
+ 4:00 1:00 +05 1997 Mar lastSun
+ 4:00 E-EurAsia +04/+05 2004 Jun 27
+ 3:00 RussiaAsia +03/+04 2005 Mar lastSun 2:00
+ 4:00 - +04
# East Timor
# summary published by the Time and Frequency Laboratory of the
# Research Center for Calibration, Instrumentation and Metrology,
# Indonesia, <http://time.kim.lipi.go.id/time-eng.php> (2006-09-29).
-# The abbreviations are:
+# The time zone abbreviations and UT offsets are:
#
-# WIB - UTC+7 - Waktu Indonesia Barat (Indonesia western time)
-# WITA - UTC+8 - Waktu Indonesia Tengah (Indonesia central time)
-# WIT - UTC+9 - Waktu Indonesia Timur (Indonesia eastern time)
+# WIB - +07 - Waktu Indonesia Barat (Indonesia western time)
+# WITA - +08 - Waktu Indonesia Tengah (Indonesia central time)
+# WIT - +09 - Waktu Indonesia Timur (Indonesia eastern time)
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
# Java, Sumatra
Rule Kyrgyz 1997 2004 - Oct lastSun 2:30 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Bishkek 4:58:24 - LMT 1924 May 2
- 5:00 - FRUT 1930 Jun 21 # Frunze Time
- 6:00 RussiaAsia FRU%sT 1991 Mar 31 2:00s
- 5:00 1:00 FRUST 1991 Aug 31 2:00 # independence
- 5:00 Kyrgyz KG%sT 2005 Aug 12 # Kyrgyzstan Time
- 6:00 - KGT
+ 5:00 - +05 1930 Jun 21
+ 6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s
+ 5:00 RussiaAsia +05/+06 1991 Aug 31 2:00
+ 5:00 Kyrgyz +05/+06 2005 Aug 12
+ 6:00 - +06
###############################################################################
# Bill Bonnet (2005-05-19) reports that the US Embassy in Ulaanbaatar says
# there is only one time zone and that DST is observed, citing Microsoft
# Windows XP as the source. Risto Nykänen (2005-05-16) reports that
-# travelmongolia.org says there are two time zones (UTC+7, UTC+8) with no DST.
+# travelmongolia.org says there are two time zones (UT +07, +08) with no DST.
# Oscar van Vlijmen (2005-05-20) reports that the Mongolian Embassy in
# Washington, DC says there are two time zones, with DST observed.
# He also found
# From Paul Eggert (2015-03-03):
# http://www.timeanddate.com/time/change/west-bank/ramallah?year=2014
# says that the fall 2014 transition was Oct 23 at 24:00.
-# For future dates, guess the last Friday in March at 24:00 through
-# the first Friday on or after October 21 at 00:00. This is consistent with
-# the predictions in today's editions of the following URLs:
-# http://www.timeanddate.com/time/change/gaza-strip/gaza
-# http://www.timeanddate.com/time/change/west-bank/hebron
# From Hannah Kreitem (2016-03-09):
# http://www.palestinecabinet.gov.ps/WebSite/ar/ViewDetails?ID=31728
#
# From Paul Eggert (2016-03-12):
# Predict spring transitions on March's last Saturday at 01:00 from now on.
-# Leave fall predictions alone for now.
+
+# From Sharef Mustafa (2016-10-19):
+# [T]he Palestinian cabinet decision (Mar 8th 2016) published on
+# http://www.palestinecabinet.gov.ps/WebSite/Upload/Decree/GOV_17/16032016134830.pdf
+# states that summer time will end on Oct 29th at 01:00.
+#
+# From Tim Parenti (2016-10-19):
+# Predict fall transitions on October's last Saturday at 01:00 from now on.
+# This is consistent with the 2016 transition as well as our spring
+# predictions.
+#
+# From Paul Eggert (2016-10-19):
+# It's also consistent with predictions in the following URLs today:
+# http://www.timeanddate.com/time/change/gaza-strip/gaza
+# http://www.timeanddate.com/time/change/west-bank/hebron
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
Rule Palestine 2012 2014 - Mar lastThu 24:00 1:00 S
Rule Palestine 2012 only - Sep 21 1:00 0 -
Rule Palestine 2013 only - Sep Fri>=21 0:00 0 -
-Rule Palestine 2014 max - Oct Fri>=21 0:00 0 -
+Rule Palestine 2014 2015 - Oct Fri>=21 0:00 0 -
Rule Palestine 2015 only - Mar lastFri 24:00 1:00 S
Rule Palestine 2016 max - Mar lastSat 1:00 1:00 S
+Rule Palestine 2016 max - Oct lastSat 1:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Gaza 2:17:52 - LMT 1900 Oct
# earlier date.
#
# Shanks & Pottenger also state that until 1968-05-01 Saudi Arabia had two
-# time zones; the other zone, at UTC+4, was in the far eastern part of
+# time zones; the other zone, at UT +04, was in the far eastern part of
# the country. Ignore this, as it's before our 1970 cutoff.
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
# People who live in regions under Tamil control can use [TZ='Asia/Kolkata'],
# as that zone has agreed with the Tamil areas since our cutoff date of 1970.
-# From K Sethu (2006-04-25):
-# I think the abbreviation LKT originated from the world of computers at
-# the time of or subsequent to the time zone changes by SL Government
-# twice in 1996 and probably SL Government or its standardization
-# agencies never declared an abbreviation as a national standard.
-#
-# I recollect before the recent change the government announcements
-# mentioning it as simply changing Sri Lanka Standard Time or Sri Lanka
-# Time and no mention was made about the abbreviation.
-#
-# If we look at Sri Lanka Department of Government's "Official News
-# Website of Sri Lanka" ... http://www.news.lk/ we can see that they
-# use SLT as abbreviation in time stamp at the beginning of each news
-# item....
-#
-# Within Sri Lanka I think LKT is well known among computer users and
-# administrators. In my opinion SLT may not be a good choice because the
-# nation's largest telcom / internet operator Sri Lanka Telcom is well
-# known by that abbreviation - simply as SLT (there IP domains are
-# slt.lk and sltnet.lk).
-#
-# But if indeed our government has adopted SLT as standard abbreviation
-# (that we have not known so far) then it is better that it be used for
-# all computers.
-
-# From Paul Eggert (2006-04-25):
-# One possibility is that we wait for a bit for the dust to settle down
-# and then see what people actually say in practice.
+# From Sadika Sumanapala (2016-10-19):
+# According to http://www.sltime.org (maintained by Measurement Units,
+# Standards & Services Department, Sri Lanka) abbreviation for Sri Lanka
+# standard time is SLST.
+#
+# From Paul Eggert (2016-10-18):
+# "SLST" seems to be reasonably recent and rarely-used outside time
+# zone nerd sources. I searched Google News and found three uses of
+# it in the International Business Times of India in February and
+# March of this year when discussing cricket match times, but nothing
+# since then (though there has been a lot of cricket) and nothing in
+# other English-language news sources. Our old abbreviation "LKT" is
+# even worse. For now, let's use a numeric abbreviation; we can
+# switch to "SLST" if it catches on.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Colombo 5:19:24 - LMT 1880
5:19:32 - MMT 1906 # Moratuwa Mean Time
- 5:30 - IST 1942 Jan 5
- 5:30 0:30 IHST 1942 Sep
- 5:30 1:00 IST 1945 Oct 16 2:00
- 5:30 - IST 1996 May 25 0:00
- 6:30 - LKT 1996 Oct 26 0:30
- 6:00 - LKT 2006 Apr 15 0:30
- 5:30 - IST
+ 5:30 - +0530 1942 Jan 5
+ 5:30 0:30 +0530/+06 1942 Sep
+ 5:30 1:00 +0530/+0630 1945 Oct 16 2:00
+ 5:30 - +0530 1996 May 25 0:00
+ 6:30 - +0630 1996 Oct 26 0:30
+ 6:00 - +06 2006 Apr 15 0:30
+ 5:30 - +0530
# Syria
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
# From Shanks & Pottenger.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Dushanbe 4:35:12 - LMT 1924 May 2
- 5:00 - DUST 1930 Jun 21 # Dushanbe Time
- 6:00 RussiaAsia DUS%sT 1991 Mar 31 2:00s
- 5:00 1:00 DUSST 1991 Sep 9 2:00s
- 5:00 - TJT # Tajikistan Time
+ 5:00 - +05 1930 Jun 21
+ 6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s
+ 5:00 1:00 +05/+06 1991 Sep 9 2:00s
+ 5:00 - +05
# Thailand
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
# From Shanks & Pottenger.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Ashgabat 3:53:32 - LMT 1924 May 2 # or Ashkhabad
- 4:00 - ASHT 1930 Jun 21 # Ashkhabad Time
- 5:00 RussiaAsia ASH%sT 1991 Mar 31 2:00
- 4:00 RussiaAsia ASH%sT 1991 Oct 27 # independence
- 4:00 RussiaAsia TM%sT 1992 Jan 19 2:00
- 5:00 - TMT
+ 4:00 - +04 1930 Jun 21
+ 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00
+ 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00
+ 5:00 - +05
# United Arab Emirates
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
# Byalokoz 1919 says Uzbekistan was 4:27:53.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Samarkand 4:27:53 - LMT 1924 May 2
- 4:00 - SAMT 1930 Jun 21 # Samarkand Time
- 5:00 - SAMT 1981 Apr 1
- 5:00 1:00 SAMST 1981 Oct 1
- 6:00 - TAST 1982 Apr 1 # Tashkent Time
- 5:00 RussiaAsia SAM%sT 1991 Sep 1 # independence
- 5:00 RussiaAsia UZ%sT 1992
- 5:00 - UZT
+ 4:00 - +04 1930 Jun 21
+ 5:00 - +05 1981 Apr 1
+ 5:00 1:00 +06 1981 Oct 1
+ 6:00 - +06 1982 Apr 1
+ 5:00 RussiaAsia +05/+06 1992
+ 5:00 - +05
# Milne says Tashkent was 4:37:10.8; round to nearest.
Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2
- 5:00 - TAST 1930 Jun 21 # Tashkent Time
- 6:00 RussiaAsia TAS%sT 1991 Mar 31 2:00
- 5:00 RussiaAsia TAS%sT 1991 Sep 1 # independence
- 5:00 RussiaAsia UZ%sT 1992
- 5:00 - UZT
+ 5:00 - +05 1930 Jun 21
+ 6:00 RussiaAsia +06/+07 1991 Mar 31 2:00
+ 5:00 RussiaAsia +05/+06 1992
+ 5:00 - +05
# Vietnam
# commencing at 2.00 am on Sunday 1st November, 2015 and ending at
# 3.00 am on Sunday 17th January, 2016.
-# From Paul Eggert (2015-09-01):
+# From Raymond Kumar (2016-10-04):
+# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVING-STARTS-ON-6th-NOVEMBER,-2016.aspx
+# "Fiji's daylight savings will begin on Sunday, 6 November 2016, when
+# clocks go forward an hour at 2am to 3am.... Daylight Saving will
+# end at 3.00am on Sunday 15th January 2017."
+
+# From Paul Eggert (2016-10-03):
# For now, guess DST from 02:00 the first Sunday in November to
# 03:00 the third Sunday in January. Although ad hoc, it matches
# transitions since late 2014 and seems more likely to match future
# Base the Bougainville entry on the Arawa-Kieta region, which appears to have
# the most people even though it was devastated in the Bougainville Civil War.
#
-# Although Shanks gives 1942-03-15 / 1943-11-01 for JST, these dates
+# Although Shanks gives 1942-03-15 / 1943-11-01 for UT +09, these dates
# are apparently rough guesswork from the starts of military campaigns.
# The World War II entries below are instead based on Arawa-Kieta.
# The Japanese occupied Kieta in July 1942,
# http://pwencycl.kgbudge.com/B/o/Bougainville.htm
# and seem to have controlled it until their 1945-08-21 surrender.
#
-# The Autonomous Region of Bougainville plans to switch from UTC+10 to UTC+11
-# on 2014-12-28 at 02:00. They call UTC+11 "Bougainville Standard Time";
+# The Autonomous Region of Bougainville switched from UT +10 to +11
+# on 2014-12-28 at 02:00. They call +11 "Bougainville Standard Time";
# abbreviate this as BST. See:
# http://www.bougainville24.com/bougainville-issues/bougainville-gets-own-timezone/
#
# From Paul Eggert (2014-06-27):
# The International Date Line Act 2011
# http://www.parliament.gov.ws/images/ACTS/International_Date_Line_Act__2011_-_Eng.pdf
-# changed Samoa from UTC-11 to UTC+13, effective "12 o'clock midnight, on
+# changed Samoa from UT -11 to +13, effective "12 o'clock midnight, on
# Thursday 29th December 2011". The International Date Line was adjusted
# accordingly.
# 1886-1891; Baker was similar but exact dates are not known.
# Inhabited by civilians 1935-1942; U.S. military bases 1943-1944;
# uninhabited thereafter.
-# Howland observed Hawaii Standard Time (UT-10:30) in 1937;
+# Howland observed Hawaii Standard Time (UT -10:30) in 1937;
# see page 206 of Elgen M. Long and Marie K. Long,
# Amelia Earhart: the Mystery Solved, Simon & Schuster (2000).
# So most likely Howland and Baker observed Hawaii Time from 1935
# Zealand time. I understand that is the time they keep locally, anyhow."
# For now, assume this practice goes back to the introduction of standard time
# in New Zealand, as this would make Chatham Islands time almost exactly match
-# LMT back when New Zealand was at UTC+11:30; also, assume Chatham Islands did
+# LMT back when New Zealand was at UT +11:30; also, assume Chatham Islands did
# not observe New Zealand's prewar DST.
###############################################################################
# The Federated States of Micronesia Visitors Board writes in
# The Federated States of Micronesia - Visitor Information (1999-01-26)
# http://www.fsmgov.org/info/clocks.html
-# that Truk and Yap are UTC+10, and Ponape and Kosrae are UTC+11.
-# We don't know when Kosrae switched from UTC+12; assume January 1 for now.
+# that Truk and Yap are UT +10, and Ponape and Kosrae are +11.
+# We don't know when Kosrae switched from +12; assume January 1 for now.
# Midway
# ordaining - by a masterpiece of diplomatic flattery - that
# the Fourth of July should be celebrated twice in that year."
-# Although Shanks & Pottenger says they both switched to UTC-11:30
-# in 1911, and to UTC-11 in 1950. many earlier sources give UTC-11
+# Although Shanks & Pottenger says they both switched to UT -11:30
+# in 1911, and to -11 in 1950. many earlier sources give -11
# for American Samoa, e.g., the US National Bureau of Standards
# circular "Standard Time Throughout the World", 1932.
-# Assume American Samoa switched to UTC-11 in 1911, not 1950,
+# Assume American Samoa switched to -11 in 1911, not 1950,
# and that after 1950 they agreed until (western) Samoa skipped a
# day in 2011. Assume also that the Samoas follow the US and New
# Zealand's "ST"/"DT" style of daylight-saving abbreviations.
Link Asia/Urumqi Asia/Kashgar
Link Asia/Kathmandu Asia/Katmandu
Link Asia/Macau Asia/Macao
+Link Asia/Yangon Asia/Rangoon
Link Asia/Ho_Chi_Minh Asia/Saigon
Link Asia/Jerusalem Asia/Tel_Aviv
Link Asia/Thimphu Asia/Thimbu
# Equatorial Guinea
#
-# Although Shanks says that Malabo switched from UTC to UTC+1 on 1963-12-15,
+# Although Shanks says that Malabo switched from UT +00 to +01 on 1963-12-15,
# a Google Books search says that London Calling, Issues 432-465 (1948), p 19,
-# says that Spanish Guinea was at GMT+1 back then. The Shanks data entries
+# says that Spanish Guinea was at +01 back then. The Shanks data entries
# are most likely wrong, but we have nothing better; use them here for now.
#
Zone Africa/Malabo 0:35:08 - LMT 1912
# From Paul Eggert (2014-08-11), after a heads-up from Stephen Colebourne:
# According to a Portuguese decree (1911-05-26)
# http://dre.pt/pdf1sdip/1911/05/12500/23132313.pdf
-# Portuguese India switched to GMT+5 on 1912-01-01.
+# Portuguese India switched to UT +05 on 1912-01-01.
#Zone Asia/Panaji [not enough info to complete]
# Cambodia
# From Paul Eggert (2014-10-11):
# See Asia/Ho_Chi_Minh for the source for most of this data. Also, guess
-# (1) Cambodia reverted to UT+7 on 1945-09-02, when Vietnam did, and
-# (2) they also reverted to UT+7 on 1953-11-09, the date of independence.
+# (1) Cambodia reverted to UT +07 on 1945-09-02, when Vietnam did, and
+# (2) they also reverted to +07 on 1953-11-09, the date of independence.
# These guesses are probably wrong but they're better than guessing no
# transitions there.
Zone Asia/Phnom_Penh 6:59:40 - LMT 1906 Jul 1
# Laos
# From Paul Eggert (2014-10-11):
# See Asia/Ho_Chi_Minh for the source for most of this data.
-# Trần's book says that Laos reverted to UT+7 on 1955-04-15.
-# Also, guess that Laos reverted to UT+7 on 1945-09-02, when Vietnam did;
+# Trần's book says that Laos reverted to UT +07 on 1955-04-15.
+# Also, guess that Laos reverted to +07 on 1945-09-02, when Vietnam did;
# this is probably wrong but it's better than guessing no transition.
Zone Asia/Vientiane 6:50:24 - LMT 1906 Jul 1
7:06:30 - PLMT 1911 May 1
#define SECSPERMIN 60
#endif /* !defined SECSPERMIN */
-#if !HAVE_POSIX_DECLS
extern char ** environ;
+
+#if !HAVE_POSIX_DECLS
extern char * optarg;
extern int optind;
extern char * tzname[];
# even though this is the opposite of what many people expect.
# POSIX has positive signs west of Greenwich, but many people expect
# positive signs east of Greenwich. For example, TZ='Etc/GMT+4' uses
-# the abbreviation "GMT+4" and corresponds to 4 hours behind UT
+# the abbreviation "-04" and corresponds to 4 hours behind UT
# (i.e. west of Greenwich) even though many people would expect it to
# mean 4 hours ahead of UT (i.e. east of Greenwich).
-#
-# In the draft 5 of POSIX 1003.1-200x, the angle bracket notation allows for
-# TZ='<GMT-4>+4'; if you want time zone abbreviations conforming to
-# ISO 8601 you can use TZ='<-0400>+4'. Thus the commonly-expected
-# offset is kept within the angle bracket (and is used for display)
-# while the POSIX sign is kept outside the angle bracket (and is used
-# for calculation).
-#
-# Do not use a TZ setting like TZ='GMT+4', which is four hours behind
-# GMT but uses the completely misleading abbreviation "GMT".
# Earlier incarnations of this package were not POSIX-compliant,
# and had lines such as
# 1:00 CET CEST CEMT Central Europe
# 1:00:14 SET Swedish (1879-1899)*
# 2:00 EET EEST Eastern Europe
-# 3:00 FET Further-eastern Europe (2011-2014)*
-# 3:00 MSK MSD MSM* Minsk, Moscow
+# 3:00 MSK MSD Moscow
# From Peter Ilieve (1994-12-04),
# The original six [EU members]: Belgium, France, (West) Germany, Italy,
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Russia 1917 only - Jul 1 23:00 1:00 MST # Moscow Summer Time
+#
+# Decree No. 142 (1917-12-22) http://istmat.info/node/28137
Rule Russia 1917 only - Dec 28 0:00 0 MMT # Moscow Mean Time
+#
+# Decree No. 497 (1918-05-30) http://istmat.info/node/30001
Rule Russia 1918 only - May 31 22:00 2:00 MDST # Moscow Double Summer Time
Rule Russia 1918 only - Sep 16 1:00 1:00 MST
#
# Decree No. 258 (1919-05-29) http://istmat.info/node/37949
Rule Russia 1919 only - May 31 23:00 2:00 MDST
-Rule Russia 1919 only - Jul 1 2:00 1:00 MSD
+#
+Rule Russia 1919 only - Jul 1 0:00u 1:00 MSD
Rule Russia 1919 only - Aug 16 0:00 0 MSK
+#
+# Decree No. 63 (1921-02-03) http://istmat.info/node/45840
Rule Russia 1921 only - Feb 14 23:00 1:00 MSD
-Rule Russia 1921 only - Mar 20 23:00 2:00 MSM # Midsummer
+#
+# Decree No. 121 (1921-03-07) http://istmat.info/node/45949
+Rule Russia 1921 only - Mar 20 23:00 2:00 +05
+#
Rule Russia 1921 only - Sep 1 0:00 1:00 MSD
Rule Russia 1921 only - Oct 1 0:00 0 -
# Act No. 925 of the Council of Ministers of the USSR (1980-10-24):
# From Alexander Bokovoy (2014-10-09):
# Belarussian government decided against changing to winter time....
# http://eng.belta.by/all_news/society/Belarus-decides-against-adjusting-time-in-Russias-wake_i_76335.html
-# From Paul Eggert (2014-10-08):
-# Hence Belarus can share time zone abbreviations with Moscow again.
#
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Minsk 1:50:16 - LMT 1880
3:00 Russia MSK/MSD 1990
3:00 - MSK 1991 Mar 31 2:00s
2:00 Russia EE%sT 2011 Mar 27 2:00s
- 3:00 - FET 2014 Oct 26 1:00s
- 3:00 - MSK
+ 3:00 - +03
# Belgium
#
# But these events all occurred before the 1970 cutoff,
# so record only the time in Rome.
#
-# From Paul Eggert (2006-03-22):
-# For Italian DST we have three sources: Shanks & Pottenger, Whitman, and
-# F. Pollastri
-# Day-light Saving Time in Italy (2006-02-03)
-# http://toi.iriti.cnr.it/uk/ienitlt.html
-# ('FP' below), taken from an Italian National Electrotechnical Institute
-# publication. When the three sources disagree, guess who's right, as follows:
-#
-# year FP Shanks&P. (S) Whitman (W) Go with:
-# 1916 06-03 06-03 24:00 06-03 00:00 FP & W
-# 09-30 09-30 24:00 09-30 01:00 FP; guess 24:00s
-# 1917 04-01 03-31 24:00 03-31 00:00 FP & S
-# 09-30 09-29 24:00 09-30 01:00 FP & W
-# 1918 03-09 03-09 24:00 03-09 00:00 FP & S
-# 10-06 10-05 24:00 10-06 01:00 FP & W
-# 1919 03-01 03-01 24:00 03-01 00:00 FP & S
-# 10-04 10-04 24:00 10-04 01:00 FP; guess 24:00s
-# 1920 03-20 03-20 24:00 03-20 00:00 FP & S
-# 09-18 09-18 24:00 10-01 01:00 FP; guess 24:00s
-# 1944 04-02 04-03 02:00 S (see C-Eur)
-# 09-16 10-02 03:00 FP; guess 24:00s
-# 1945 09-14 09-16 24:00 FP; guess 24:00s
-# 1970 05-21 05-31 00:00 S
-# 09-20 09-27 00:00 S
+# From Michael Deckers (2016-10-24):
+# http://www.ac-ilsestante.it/MERIDIANE/ora_legale quotes a law of 1893-08-10
+# ... [translated as] "The preceding dispositions will enter into
+# force at the instant at which, according to the time specified in
+# the 1st article, the 1st of November 1893 will begin...."
+#
+# From Pierpaolo Bernardi (2016-10-20):
+# The authoritative source for time in Italy is the national metrological
+# institute, which has a summary page of historical DST data at
+# http://www.inrim.it/res/tf/ora_legale_i.shtml
+# (2016-10-24):
+# http://www.renzobaldini.it/le-ore-legali-in-italia/
+# has still different data for 1944. It divides Italy in two, as
+# there were effectively two governments at the time, north of Gothic
+# Line German controlled territory, official government RSI, and south
+# of the Gothic Line, controlled by allied armies.
+#
+# From Brian Inglis (2016-10-23):
+# Viceregal LEGISLATIVE DECREE. 14 September 1944, no. 219.
+# Restoration of Standard Time. (044U0219) (OJ 62 of 30.9.1944) ...
+# Given the R. law decreed on 1944-03-29, no. 92, by which standard time is
+# advanced to sixty minutes later starting at hour two on 1944-04-02; ...
+# Starting at hour three on the date 1944-09-17 standard time will be resumed.
+#
+# From Paul Eggert (2016-10-27):
+# Go with INRiM for DST rules, except as corrected by Inglis for 1944
+# for the Kingdom of Italy. This is consistent with Renzo Baldini.
+# Model Rome's occupation by using using C-Eur rules from 1943-09-10
+# to 1944-06-04; although Rome was an open city during this period, it
+# was effectively controlled by Germany.
#
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Italy 1916 only - Jun 3 24:00 1:00 S
Rule Italy 1979 only - Sep 30 0:00s 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Rome 0:49:56 - LMT 1866 Sep 22
- 0:49:56 - RMT 1893 Nov 1 0:00s # Rome Mean
- 1:00 Italy CE%sT 1942 Nov 2 2:00s
- 1:00 C-Eur CE%sT 1944 Jul
+ 0:49:56 - RMT 1893 Oct 31 23:49:56 # Rome Mean
+ 1:00 Italy CE%sT 1943 Sep 10
+ 1:00 C-Eur CE%sT 1944 Jun 4
1:00 Italy CE%sT 1980
1:00 EU CE%sT
Rule Malta 1980 only - Mar 31 2:00 1:00 S
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 0:00s # Valletta
- 1:00 Italy CE%sT 1942 Nov 2 2:00s
- 1:00 C-Eur CE%sT 1945 Apr 2 2:00s
1:00 Italy CE%sT 1973 Mar 31
1:00 Malta CE%sT 1981
1:00 EU CE%sT
# Amsterdam mean time.
# The data entries before 1945 are taken from
-# http://www.phys.uu.nl/~vgent/wettijd/wettijd.htm
+# http://www.staff.science.uu.nl/~gent0113/wettijd/wettijd.htm
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Neth 1916 only - May 1 0:00 1:00 NST # Netherlands Summer Time
2:00 Poland CE%sT 1946
3:00 Russia MSK/MSD 1989 Mar 26 2:00s
2:00 Russia EE%sT 2011 Mar 27 2:00s
- 3:00 - FET 2014 Oct 26 2:00s
+ 3:00 - +03 2014 Oct 26 2:00s
2:00 - EET
# 78 RU-SPE Saint Petersburg
# 83 RU-NEN Nenets Autonomous Okrug
+# From Paul Eggert (2016-08-23):
+# The Soviets switched to UT-based time in 1919. Decree No. 59
+# (1919-02-08) http://istmat.info/node/35567 established UT-based time
+# zones, and Decree No. 147 (1919-03-29) http://istmat.info/node/35854
+# specified a transition date of 1919-07-01, apparently at 00:00 UT.
+# No doubt only the Soviet-controlled regions switched on that date;
+# later transitions to UT-based time in other parts of Russia are
+# taken from what appear to be guesses by Shanks.
+# (Thanks to Alexander Belopolsky for pointers to the decrees.)
+
# From Stepan Golosunov (2016-03-07):
# 11. Regions-violators, 1981-1982.
# Wikipedia refers to
# attributes the 1982 changes to the Act of the Council of Ministers
# of the USSR No. 126 from 18.02.1982. 1980-925.txt also adds
# Udmurtia to the list of affected territories and lists Khatangsky
-# district separately from Taymyr Autonomous Okurg. Probably erroneously.
+# district separately from Taymyr Autonomous Okrug. Probably erroneously.
#
# The affected territories are currently listed under Europe/Moscow,
# Asia/Yekaterinburg and Asia/Krasnoyarsk.
Zone Europe/Moscow 2:30:17 - LMT 1880
2:30:17 - MMT 1916 Jul 3 # Moscow Mean Time
- 2:31:19 Russia %s 1919 Jul 1 2:00
+ 2:31:19 Russia %s 1919 Jul 1 0:00u
3:00 Russia %s 1921 Oct
3:00 Russia MSK/MSD 1922 Oct
2:00 - EET 1930 Jun 21
# The 1988 transition is from USSR act No. 5 (1988-01-04).
Zone Europe/Volgograd 2:57:40 - LMT 1920 Jan 3
- 3:00 - TSAT 1925 Apr 6 # Tsaritsyn Time
- 3:00 - STAT 1930 Jun 21 # Stalingrad Time
- 4:00 - STAT 1961 Nov 11
- 4:00 Russia VOL%sT 1988 Mar 27 2:00s # Volgograd T
- 3:00 Russia VOL%sT 1991 Mar 31 2:00s
- 4:00 - VOLT 1992 Mar 29 2:00s
- 3:00 Russia MSK/MSD 2011 Mar 27 2:00s
- 4:00 - MSK 2014 Oct 26 2:00s
- 3:00 - MSK
+ 3:00 - +03 1930 Jun 21
+ 4:00 - +04 1961 Nov 11
+ 4:00 Russia +04/+05 1988 Mar 27 2:00s
+ 3:00 Russia +03/+04 1991 Mar 31 2:00s
+ 4:00 - +04 1992 Mar 29 2:00s
+ 3:00 Russia +03/+04 2011 Mar 27 2:00s
+ 4:00 - +04 2014 Oct 26 2:00s
+ 3:00 - +03
# From Paul Eggert (2016-03-18):
# Europe/Kirov covers:
# 43 RU-KIR Kirov Oblast
# The 1989 transition is from USSR act No. 227 (1989-03-14).
#
-Zone Europe/Kirov 3:18:48 - LMT 1919 Jul 1 2:00
+Zone Europe/Kirov 3:18:48 - LMT 1919 Jul 1 0:00u
3:00 - +03 1930 Jun 21
4:00 Russia +04/+05 1989 Mar 26 2:00s
3:00 Russia +03/+04 1991 Mar 31 2:00s
# Byalokoz 1919 says Samara was 3:20:20.
# The 1989 transition is from USSR act No. 227 (1989-03-14).
-Zone Europe/Samara 3:20:20 - LMT 1919 Jul 1 2:00
- 3:00 - SAMT 1930 Jun 21 # Samara Time
- 4:00 - SAMT 1935 Jan 27
- 4:00 Russia KUY%sT 1989 Mar 26 2:00s # Kuybyshev
- 3:00 Russia MSK/MSD 1991 Mar 31 2:00s
- 2:00 Russia EE%sT 1991 Sep 29 2:00s
- 3:00 - SAMT 1991 Oct 20 3:00
- 4:00 Russia SAM%sT 2010 Mar 28 2:00s
- 3:00 Russia SAM%sT 2011 Mar 27 2:00s
- 4:00 - SAMT
+Zone Europe/Samara 3:20:20 - LMT 1919 Jul 1 0:00u
+ 3:00 - +03 1930 Jun 21
+ 4:00 - +04 1935 Jan 27
+ 4:00 Russia +04/+05 1989 Mar 26 2:00s
+ 3:00 Russia +03/+04 1991 Mar 31 2:00s
+ 2:00 Russia +02/+03 1991 Sep 29 2:00s
+ 3:00 - +03 1991 Oct 20 3:00
+ 4:00 Russia +04/+05 2010 Mar 28 2:00s
+ 3:00 Russia +03/+04 2011 Mar 27 2:00s
+ 4:00 - +04
# From Paul Eggert (2016-03-18):
# Europe/Ulyanovsk covers:
# From Matt Johnson (2016-03-09):
# http://publication.pravo.gov.ru/Document/View/0001201603090051
-Zone Europe/Ulyanovsk 3:13:36 - LMT 1919 Jul 1 2:00
+Zone Europe/Ulyanovsk 3:13:36 - LMT 1919 Jul 1 0:00u
3:00 - +03 1930 Jun 21
4:00 Russia +04/+05 1989 Mar 26 2:00s
3:00 Russia +03/+04 1991 Mar 31 2:00s
Zone Asia/Yekaterinburg 4:02:33 - LMT 1916 Jul 3
3:45:05 - PMT 1919 Jul 15 4:00
- 4:00 - SVET 1930 Jun 21 # Sverdlovsk Time
- 5:00 Russia SVE%sT 1991 Mar 31 2:00s
- 4:00 Russia SVE%sT 1992 Jan 19 2:00s
- 5:00 Russia YEK%sT 2011 Mar 27 2:00s
- 6:00 - YEKT 2014 Oct 26 2:00s
- 5:00 - YEKT
+ 4:00 - +04 1930 Jun 21
+ 5:00 Russia +05/+06 1991 Mar 31 2:00s
+ 4:00 Russia +04/+05 1992 Jan 19 2:00s
+ 5:00 Russia +05/+06 2011 Mar 27 2:00s
+ 6:00 - +06 2014 Oct 26 2:00s
+ 5:00 - +05
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
# Byalokoz 1919 says Omsk was 4:53:30.
Zone Asia/Omsk 4:53:30 - LMT 1919 Nov 14
- 5:00 - OMST 1930 Jun 21 # Omsk Time
- 6:00 Russia OMS%sT 1991 Mar 31 2:00s
- 5:00 Russia OMS%sT 1992 Jan 19 2:00s
- 6:00 Russia OMS%sT 2011 Mar 27 2:00s
- 7:00 - OMST 2014 Oct 26 2:00s
- 6:00 - OMST
+ 5:00 - +05 1930 Jun 21
+ 6:00 Russia +06/+07 1991 Mar 31 2:00s
+ 5:00 Russia +05/+06 1992 Jan 19 2:00s
+ 6:00 Russia +06/+07 2011 Mar 27 2:00s
+ 7:00 - +07 2014 Oct 26 2:00s
+ 6:00 - +06
# From Paul Eggert (2016-02-22):
# Asia/Barnaul covers:
# Note that time belts (numbered from 2 (Moscow) to 12 according to their
# GMT/UTC offset and having too many exceptions like regions formally
# belonging to one belt but using time from another) were replaced
-# with time zones in 2011 with different numberings (there was a
+# with time zones in 2011 with different numbering (there was a
# 2-hour gap between second and third zones in 2011-2014).
# From Stepan Golosunov (2016-04-12):
#
# Thus, when Russia will switch to DST on the night of March 28, 2010
# Kemerovo region (Kemerovo oblast') will not change the clock.
-#
-# As a result, Kemerovo oblast' will be in the same time zone as
-# Novosibirsk, Omsk, Tomsk, Barnaul and Altai Republic.
# From Tim Parenti (2014-07-02), per Alexander Krivenyshev (2014-07-02):
# The Kemerovo region will remain at UTC+7 through the 2014-10-26 change, thus
# realigning itself with KRAT.
Zone Asia/Novokuznetsk 5:48:48 - LMT 1924 May 1
- 6:00 - KRAT 1930 Jun 21 # Krasnoyarsk Time
- 7:00 Russia KRA%sT 1991 Mar 31 2:00s
- 6:00 Russia KRA%sT 1992 Jan 19 2:00s
- 7:00 Russia KRA%sT 2010 Mar 28 2:00s
- 6:00 Russia NOV%sT 2011 Mar 27 2:00s # Novosibirsk
- 7:00 - NOVT 2014 Oct 26 2:00s
- 7:00 - KRAT # Krasnoyarsk Time
-
+ 6:00 - +06 1930 Jun 21
+ 7:00 Russia +07/+08 1991 Mar 31 2:00s
+ 6:00 Russia +06/+07 1992 Jan 19 2:00s
+ 7:00 Russia +07/+08 2010 Mar 28 2:00s
+ 6:00 Russia +06/+07 2011 Mar 27 2:00s
+ 7:00 - +07
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
# Asia/Krasnoyarsk covers...
# Byalokoz 1919 says Krasnoyarsk was 6:11:26.
Zone Asia/Krasnoyarsk 6:11:26 - LMT 1920 Jan 6
- 6:00 - KRAT 1930 Jun 21 # Krasnoyarsk Time
- 7:00 Russia KRA%sT 1991 Mar 31 2:00s
- 6:00 Russia KRA%sT 1992 Jan 19 2:00s
- 7:00 Russia KRA%sT 2011 Mar 27 2:00s
- 8:00 - KRAT 2014 Oct 26 2:00s
- 7:00 - KRAT
+ 6:00 - +06 1930 Jun 21
+ 7:00 Russia +07/+08 1991 Mar 31 2:00s
+ 6:00 Russia +06/+07 1992 Jan 19 2:00s
+ 7:00 Russia +07/+08 2011 Mar 27 2:00s
+ 8:00 - +08 2014 Oct 26 2:00s
+ 7:00 - +07
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
Zone Asia/Irkutsk 6:57:05 - LMT 1880
6:57:05 - IMT 1920 Jan 25 # Irkutsk Mean Time
- 7:00 - IRKT 1930 Jun 21 # Irkutsk Time
- 8:00 Russia IRK%sT 1991 Mar 31 2:00s
- 7:00 Russia IRK%sT 1992 Jan 19 2:00s
- 8:00 Russia IRK%sT 2011 Mar 27 2:00s
- 9:00 - IRKT 2014 Oct 26 2:00s
- 8:00 - IRKT
+ 7:00 - +07 1930 Jun 21
+ 8:00 Russia +08/+09 1991 Mar 31 2:00s
+ 7:00 Russia +07/+08 1992 Jan 19 2:00s
+ 8:00 Russia +08/+09 2011 Mar 27 2:00s
+ 9:00 - +09 2014 Oct 26 2:00s
+ 8:00 - +08
# From Tim Parenti (2014-07-06):
# http://publication.pravo.gov.ru/Document/View/0001201512300107
Zone Asia/Chita 7:33:52 - LMT 1919 Dec 15
- 8:00 - YAKT 1930 Jun 21 # Yakutsk Time
- 9:00 Russia YAK%sT 1991 Mar 31 2:00s
- 8:00 Russia YAK%sT 1992 Jan 19 2:00s
- 9:00 Russia YAK%sT 2011 Mar 27 2:00s
- 10:00 - YAKT 2014 Oct 26 2:00s
- 8:00 - IRKT 2016 Mar 27 2:00
- 9:00 - YAKT
+ 8:00 - +08 1930 Jun 21
+ 9:00 Russia +09/+10 1991 Mar 31 2:00s
+ 8:00 Russia +08/+09 1992 Jan 19 2:00s
+ 9:00 Russia +09/+10 2011 Mar 27 2:00s
+ 10:00 - +10 2014 Oct 26 2:00s
+ 8:00 - +08 2016 Mar 27 2:00
+ 9:00 - +09
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29):
# Byalokoz 1919 says Yakutsk was 8:38:58.
Zone Asia/Yakutsk 8:38:58 - LMT 1919 Dec 15
- 8:00 - YAKT 1930 Jun 21 # Yakutsk Time
- 9:00 Russia YAK%sT 1991 Mar 31 2:00s
- 8:00 Russia YAK%sT 1992 Jan 19 2:00s
- 9:00 Russia YAK%sT 2011 Mar 27 2:00s
- 10:00 - YAKT 2014 Oct 26 2:00s
- 9:00 - YAKT
+ 8:00 - +08 1930 Jun 21
+ 9:00 Russia +09/+10 1991 Mar 31 2:00s
+ 8:00 Russia +08/+09 1992 Jan 19 2:00s
+ 9:00 Russia +09/+10 2011 Mar 27 2:00s
+ 10:00 - +10 2014 Oct 26 2:00s
+ 9:00 - +09
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29):
# Go with Byalokoz.
Zone Asia/Vladivostok 8:47:31 - LMT 1922 Nov 15
- 9:00 - VLAT 1930 Jun 21 # Vladivostok Time
- 10:00 Russia VLA%sT 1991 Mar 31 2:00s
- 9:00 Russia VLA%sT 1992 Jan 19 2:00s
- 10:00 Russia VLA%sT 2011 Mar 27 2:00s
- 11:00 - VLAT 2014 Oct 26 2:00s
- 10:00 - VLAT
+ 9:00 - +09 1930 Jun 21
+ 10:00 Russia +10/+11 1991 Mar 31 2:00s
+ 9:00 Russia +09/+10 1992 Jan 19 2:00s
+ 10:00 Russia +10/+11 2011 Mar 27 2:00s
+ 11:00 - +11 2014 Oct 26 2:00s
+ 10:00 - +10
# From Tim Parenti (2014-07-03):
# This transition is no doubt wrong, but we have no better info.
Zone Asia/Khandyga 9:02:13 - LMT 1919 Dec 15
- 8:00 - YAKT 1930 Jun 21 # Yakutsk Time
- 9:00 Russia YAK%sT 1991 Mar 31 2:00s
- 8:00 Russia YAK%sT 1992 Jan 19 2:00s
- 9:00 Russia YAK%sT 2004
- 10:00 Russia VLA%sT 2011 Mar 27 2:00s
- 11:00 - VLAT 2011 Sep 13 0:00s # Decree 725?
- 10:00 - YAKT 2014 Oct 26 2:00s
- 9:00 - YAKT
+ 8:00 - +08 1930 Jun 21
+ 9:00 Russia +09/+10 1991 Mar 31 2:00s
+ 8:00 Russia +08/+09 1992 Jan 19 2:00s
+ 9:00 Russia +09/+10 2004
+ 10:00 Russia +10/+11 2011 Mar 27 2:00s
+ 11:00 - +11 2011 Sep 13 0:00s # Decree 725?
+ 10:00 - +10 2014 Oct 26 2:00s
+ 9:00 - +09
# From Tim Parenti (2014-07-03):
# The Zone name should be Asia/Yuzhno-Sakhalinsk, but that's too long.
Zone Asia/Sakhalin 9:30:48 - LMT 1905 Aug 23
- 9:00 - JCST 1937 Oct 1
- 9:00 - JST 1945 Aug 25
- 11:00 Russia SAK%sT 1991 Mar 31 2:00s # Sakhalin T
- 10:00 Russia SAK%sT 1992 Jan 19 2:00s
- 11:00 Russia SAK%sT 1997 Mar lastSun 2:00s
- 10:00 Russia SAK%sT 2011 Mar 27 2:00s
- 11:00 - SAKT 2014 Oct 26 2:00s
- 10:00 - SAKT 2016 Mar 27 2:00s
- 11:00 - SAKT
+ 9:00 - +09 1945 Aug 25
+ 11:00 Russia +11/+12 1991 Mar 31 2:00s # Sakhalin T
+ 10:00 Russia +10/+11 1992 Jan 19 2:00s
+ 11:00 Russia +11/+12 1997 Mar lastSun 2:00s
+ 10:00 Russia +10/+11 2011 Mar 27 2:00s
+ 11:00 - +11 2014 Oct 26 2:00s
+ 10:00 - +10 2016 Mar 27 2:00s
+ 11:00 - +11
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29):
# http://publication.pravo.gov.ru/Document/View/0001201604050038
Zone Asia/Magadan 10:03:12 - LMT 1924 May 2
- 10:00 - MAGT 1930 Jun 21 # Magadan Time
- 11:00 Russia MAG%sT 1991 Mar 31 2:00s
- 10:00 Russia MAG%sT 1992 Jan 19 2:00s
- 11:00 Russia MAG%sT 2011 Mar 27 2:00s
- 12:00 - MAGT 2014 Oct 26 2:00s
- 10:00 - MAGT 2016 Apr 24 2:00s
- 11:00 - MAGT
+ 10:00 - +10 1930 Jun 21 # Magadan Time
+ 11:00 Russia +11/+12 1991 Mar 31 2:00s
+ 10:00 Russia +10/+11 1992 Jan 19 2:00s
+ 11:00 Russia +11/+12 2011 Mar 27 2:00s
+ 12:00 - +12 2014 Oct 26 2:00s
+ 10:00 - +10 2016 Apr 24 2:00s
+ 11:00 - +11
# From Tim Parenti (2014-07-06):
# in Russian.) In addition, Srednekolymsk appears to be a much older
# settlement and the population of Zyryanka seems to be declining.
# Go with Srednekolymsk.
-#
-# Since Magadan Oblast moves to UTC+10 on 2014-10-26, we cannot keep using MAGT
-# as the abbreviation. Use SRET instead.
Zone Asia/Srednekolymsk 10:14:52 - LMT 1924 May 2
- 10:00 - MAGT 1930 Jun 21 # Magadan Time
- 11:00 Russia MAG%sT 1991 Mar 31 2:00s
- 10:00 Russia MAG%sT 1992 Jan 19 2:00s
- 11:00 Russia MAG%sT 2011 Mar 27 2:00s
- 12:00 - MAGT 2014 Oct 26 2:00s
- 11:00 - SRET # Srednekolymsk Time
+ 10:00 - +10 1930 Jun 21
+ 11:00 Russia +11/+12 1991 Mar 31 2:00s
+ 10:00 Russia +10/+11 1992 Jan 19 2:00s
+ 11:00 Russia +11/+12 2011 Mar 27 2:00s
+ 12:00 - +12 2014 Oct 26 2:00s
+ 11:00 - +11
# From Tim Parenti (2014-07-03):
# UTC+12 since at least then, too.
Zone Asia/Ust-Nera 9:32:54 - LMT 1919 Dec 15
- 8:00 - YAKT 1930 Jun 21 # Yakutsk Time
- 9:00 Russia YAKT 1981 Apr 1
- 11:00 Russia MAG%sT 1991 Mar 31 2:00s
- 10:00 Russia MAG%sT 1992 Jan 19 2:00s
- 11:00 Russia MAG%sT 2011 Mar 27 2:00s
- 12:00 - MAGT 2011 Sep 13 0:00s # Decree 725?
- 11:00 - VLAT 2014 Oct 26 2:00s
- 10:00 - VLAT
+ 8:00 - +08 1930 Jun 21
+ 9:00 Russia +09/+10 1981 Apr 1
+ 11:00 Russia +11/+12 1991 Mar 31 2:00s
+ 10:00 Russia +10/+11 1992 Jan 19 2:00s
+ 11:00 Russia +11/+12 2011 Mar 27 2:00s
+ 12:00 - +12 2011 Sep 13 0:00s # Decree 725?
+ 11:00 - +11 2014 Oct 26 2:00s
+ 10:00 - +10
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
# The Zone name should be Asia/Petropavlovsk-Kamchatski or perhaps
# Asia/Petropavlovsk-Kamchatsky, but these are too long.
Zone Asia/Kamchatka 10:34:36 - LMT 1922 Nov 10
- 11:00 - PETT 1930 Jun 21 # P-K Time
- 12:00 Russia PET%sT 1991 Mar 31 2:00s
- 11:00 Russia PET%sT 1992 Jan 19 2:00s
- 12:00 Russia PET%sT 2010 Mar 28 2:00s
- 11:00 Russia PET%sT 2011 Mar 27 2:00s
- 12:00 - PETT
+ 11:00 - +11 1930 Jun 21
+ 12:00 Russia +12/+13 1991 Mar 31 2:00s
+ 11:00 Russia +11/+12 1992 Jan 19 2:00s
+ 12:00 Russia +12/+13 2010 Mar 28 2:00s
+ 11:00 Russia +11/+12 2011 Mar 27 2:00s
+ 12:00 - +12
# From Tim Parenti (2014-07-03):
# 87 RU-CHU Chukotka Autonomous Okrug
Zone Asia/Anadyr 11:49:56 - LMT 1924 May 2
- 12:00 - ANAT 1930 Jun 21 # Anadyr Time
- 13:00 Russia ANA%sT 1982 Apr 1 0:00s
- 12:00 Russia ANA%sT 1991 Mar 31 2:00s
- 11:00 Russia ANA%sT 1992 Jan 19 2:00s
- 12:00 Russia ANA%sT 2010 Mar 28 2:00s
- 11:00 Russia ANA%sT 2011 Mar 27 2:00s
- 12:00 - ANAT
+ 12:00 - +12 1930 Jun 21
+ 13:00 Russia +13/+14 1982 Apr 1 0:00s
+ 12:00 Russia +12/+13 1991 Mar 31 2:00s
+ 11:00 Russia +11/+12 1992 Jan 19 2:00s
+ 12:00 Russia +12/+13 2010 Mar 28 2:00s
+ 11:00 Russia +11/+12 2011 Mar 27 2:00s
+ 12:00 - +12
# San Marino
# Turkey
-# From Amar Devegowda (2007-01-03):
-# The time zone rules for Istanbul, Turkey have not been changed for years now.
-# ... The latest rules are available at:
-# http://www.timeanddate.com/worldclock/timezone.html?n=107
-# From Steffen Thorsen (2007-01-03):
-# I have been able to find press records back to 1996 which all say that
-# DST started 01:00 local time and end at 02:00 local time. I am not sure
-# what happened before that. One example for each year from 1996 to 2001:
-# http://newspot.byegm.gov.tr/arsiv/1996/21/N4.htm
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING97/03/97X03X25.TXT
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING98/03/98X03X02.HTM
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING99/10/99X10X26.HTM#%2016
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2000/03/00X03X06.HTM#%2021
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2001/03/23x03x01.HTM#%2027
-# From Paul Eggert (2007-01-03):
-# Prefer the above source to Shanks & Pottenger for time stamps after 1990.
+# From Kıvanç Yazan (2016-09-25):
+# 1) For 1986-2006, DST started at 01:00 local and ended at 02:00 local, with
+# no exceptions.
+# 2) 1994's lastSun was overridden with Mar 20 ...
+# Here are official papers:
+# http://www.resmigazete.gov.tr/arsiv/19032.pdf - page 2 for 1986
+# http://www.resmigazete.gov.tr/arsiv/19400.pdf - page 4 for 1987
+# http://www.resmigazete.gov.tr/arsiv/19752.pdf - page 15 for 1988
+# http://www.resmigazete.gov.tr/arsiv/20102.pdf - page 6 for 1989
+# http://www.resmigazete.gov.tr/arsiv/20464.pdf - page 1 for 1990 - 1992
+# http://www.resmigazete.gov.tr/arsiv/21531.pdf - page 15 for 1993 - 1995
+# http://www.resmigazete.gov.tr/arsiv/21879.pdf - page 1 for overriding 1994
+# http://www.resmigazete.gov.tr/arsiv/22588.pdf - page 1 for 1996, 1997
+# http://www.resmigazete.gov.tr/arsiv/23286.pdf - page 10 for 1998 - 2000
+# http://www.resmigazete.gov.tr/eskiler/2001/03/20010324.htm#2 - for 2001
+# http://www.resmigazete.gov.tr/eskiler/2002/03/20020316.htm#2 - for 2002-2006
+# From Paul Eggert (2016-09-25):
+# Prefer the above sources to Shanks & Pottenger for time stamps after 1985.
# From Steffen Thorsen (2007-03-09):
# Starting 2007 though, it seems that they are adopting EU's 1:00 UTC
# Engineered Standard Time," said Twitter user @aysekarahasan.
# http://www.bbc.com/news/world-europe-34631326
+# From Burak AYDIN (2016-09-08):
+# Turkey will stay in Daylight Saving Time even in winter....
+# http://www.resmigazete.gov.tr/eskiler/2016/09/20160908-2.pdf
+#
+# From Paul Eggert (2016-09-07):
+# The change is permanent, so this is the new standard time in Turkey.
+# It takes effect today, which is not much notice.
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Turkey 1916 only - May 1 0:00 1:00 S
Rule Turkey 1916 only - Oct 1 0:00 0 -
2:00 - EET 2014 Mar 31 1:00u
2:00 EU EE%sT 2015 Oct 25 1:00u
2:00 1:00 EEST 2015 Nov 8 1:00u
- 2:00 EU EE%sT
+ 2:00 EU EE%sT 2016 Sep 7
+ 3:00 - +03
Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
# Ukraine
# Boulder, Colorado
# Judah.Levine@nist.gov
#
-# Last Update of leap second values: 5 January 2015
+# Last Update of leap second values: 8 July 2016
#
# The following line shows this last update date in NTP timestamp
# format. This is the date on which the most recent change to
# be identified by the unique pair of characters in the first two
# columns as shown below.
#
-#$ 3629404800
+#$ 3676924800
#
# The NTP timestamps are in units of seconds since the NTP epoch,
# which is 1 January 1900, 00:00:00. The Modified Julian Day number
# current -- the update time stamp, the data and the name of the file
# will not change.
#
-# Updated through IERS Bulletin C51
-# File expires on: 28 December 2016
+# Updated through IERS Bulletin C52
+# File expires on: 28 June 2017
#
-#@ 3691872000
+#@ 3707596800
#
2272060800 10 # 1 Jan 1972
2287785600 11 # 1 Jul 1972
3439756800 34 # 1 Jan 2009
3550089600 35 # 1 Jul 2012
3644697600 36 # 1 Jul 2015
+3692217600 37 # 1 Jan 2017
#
# the following special comment contains the
# hash value of the data in this file computed
# the hash line is also ignored in the
# computation.
#
-#h afc03691 8ff53838 42080ba1 cdd22f1 48192c10
+#h dacf2c42 2c4765d6 3c797af8 2cf630eb 699c8c67
Leap 2008 Dec 31 23:59:60 + S
Leap 2012 Jun 30 23:59:60 + S
Leap 2015 Jun 30 23:59:60 + S
+Leap 2016 Dec 31 23:59:60 + S
-# Updated through IERS Bulletin C51
-# File expires on: 28 December 2016
+# Updated through IERS Bulletin C52
+# File expires on: 28 June 2017
#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.
*/
tmp->TM_ZONE = ((char *)
#endif /* defined STD_INSPIRED */
-#ifdef time_tz
+#if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
+
+# ifndef USG_COMPAT
+# define daylight 0
+# define timezone 0
+# endif
+# ifndef ALTZONE
+# define altzone 0
+# endif
/* Convert from the underlying system's time_t to the ersatz time_tz,
- which is called 'time_t' in this file. */
+ which is called 'time_t' in this file. Typically, this merely
+ converts the time's integer width. On some platforms, the system
+ time is local time not UT, or uses some epoch other than the POSIX
+ epoch.
+
+ Although this code appears to define a function named 'time' that
+ returns time_t, the macros in private.h cause this code to actually
+ define a function named 'tz_time' that returns tz_time_t. The call
+ to sys_time invokes the underlying system's 'time' function. */
time_t
time(time_t *p)
{
time_t r = sys_time(0);
+ if (r != (time_t) -1) {
+ int_fast32_t offset = EPOCH_LOCAL ? (daylight ? timezone : altzone) : 0;
+ if (increment_overflow32(&offset, -EPOCH_OFFSET)
+ || increment_overflow_time (&r, offset)) {
+ errno = EOVERFLOW;
+ r = -1;
+ }
+ }
if (p)
*p = r;
return r;
ASCII plus
.RB ( + ),
and NUL bytes are allowed.
+Alternatively, a designation can be surrounded by angle brackets
+.B <
+and
+.BR > ;
+in this case, the designation can contain any characters other than
+.B >
+and NUL.
.TP
.I offset
Indicates the value one must add to the local time to arrive at
allowed. Any characters except a leading colon
(:), digits, comma (,), ASCII minus (-), ASCII
plus (+), and NUL bytes are allowed.
+ Alternatively, a designation can be surrounded by
+ angle brackets < and >; in this case, the
+ designation can contain any characters other than
+ > and NUL.
offset Indicates the value one must add to the local
time to arrive at Coordinated Universal Time.
# north of the Salmon River, and the towns of Burgdorf and Warren),
# Nevada (except West Wendover), Oregon (except the northern 3/4 of
# Malheur county), and Washington
+
+# From Paul Eggert (2016-08-20):
+# In early February 1948, in response to California's electricity shortage,
+# PG&E changed power frequency from 60 to 59.5 Hz during daylight hours,
+# causing electric clocks to lose six minutes per day. (This did not change
+# legal time, and is not part of the data here.) See:
+# Ross SA. An energy crisis from the past: Northern California in 1948.
+# Working Paper No. 8, Institute of Governmental Studies, UC Berkeley,
+# 1973-11. http://escholarship.org/uc/item/8x22k30c
+#
+# In another measure to save electricity, DST was instituted from 1948-03-14
+# at 02:01 to 1949-01-16 at 02:00, with the governor having the option to move
+# the fallback transition earlier. See pages 3-4 of:
+# http://clerk.assembly.ca.gov/sites/clerk.assembly.ca.gov/files/archive/Statutes/1948/48Vol1_Chapters.pdf
+#
+# In response:
+#
+# Governor Warren received a torrent of objecting mail, and it is not too much
+# to speculate that the objections to Daylight Saving Time were one important
+# factor in the defeat of the Dewey-Warren Presidential ticket in California.
+# -- Ross, p 25
+#
+# On December 8 the governor exercised the option, setting the date to January 1
+# (LA Times 1948-12-09). The transition time was 02:00 (LA Times 1949-01-01).
+#
+# Despite the controversy, in 1949 California voters approved Proposition 12,
+# which established DST from April's last Sunday at 01:00 until September's
+# last Sunday at 02:00. This was amended by 1962's Proposition 6, which changed
+# the fall-back date to October's last Sunday. See:
+# http://repository.uchastings.edu/cgi/viewcontent.cgi?article=1501&context=ca_ballot_props
+# http://repository.uchastings.edu/cgi/viewcontent.cgi?article=1636&context=ca_ballot_props
#
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
Rule CA 1948 only - Mar 14 2:01 1:00 D
# indicating that the normal ET rules are followed.
#
# From Paul Eggert (2014-08-19):
-# The 2014-08-13 Cabinet meeting decided to stay on UTC-4 year-round. See:
+# The 2014-08-13 Cabinet meeting decided to stay on UT -04 year-round. See:
# http://tcweeklynews.com/daylight-savings-time-to-be-maintained-p5353-127.htm
# Model this as a switch from EST/EDT to AST ...
# From Chris Walton (2014-11-04):
Url: http://www.gnu.org/software/libc/libc.html
Requires(pre): filesystem, coreutils
# COMMON-BEGIN
-Version: 2016f
+Version: 2016i
Release: 0
Source: ftp://ftp.iana.org/tz/releases/tzdata%{version}.tar.gz
Source1001: tzdata.manifest
** Thank you!
*/
+/* This string was in the Factory zone through version 2016f. */
#define GRANDPARENTED "Local time zone must be set--see zic manual page"
/*
/* Enable tm_gmtoff and tm_zone on GNUish systems. */
#define _GNU_SOURCE 1
-/* Fix asctime_r on Solaris 10. */
+/* Fix asctime_r on Solaris 11. */
#define _POSIX_PTHREAD_SEMANTICS 1
-/* Enable strtoimax on Solaris 10. */
+/* Enable strtoimax on pre-C99 Solaris 11. */
#define __EXTENSIONS__ 1
/*
/*
** Define HAVE_STDINT_H's default value here, rather than at the
-** start, since __GLIBC__'s value depends on previously-included
-** files.
-** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.)
+** start, since __GLIBC__ and INTMAX_MAX's values depend on
+** previously-included files. glibc 2.1 and Solaris 10 and later have
+** stdint.h, even with pre-C99 compilers.
*/
#ifndef HAVE_STDINT_H
#define HAVE_STDINT_H \
(199901 <= __STDC_VERSION__ \
|| 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
- || __CYGWIN__)
+ || __CYGWIN__ || INTMAX_MAX)
#endif /* !defined HAVE_STDINT_H */
#if HAVE_STDINT_H
# endif
#endif
-#ifndef SCNdFAST64
+#ifndef PRIdFAST64
# if INT_FAST64_MAX == LLONG_MAX
-# define SCNdFAST64 "lld"
+# define PRIdFAST64 "lld"
# else
-# define SCNdFAST64 "ld"
+# define PRIdFAST64 "ld"
# endif
#endif
+#ifndef SCNdFAST64
+# define SCNdFAST64 PRIdFAST64
+#endif
+
#ifndef INT_FAST32_MAX
# if INT_MAX >> 31 == 0
typedef long int_fast32_t;
** Workarounds for compilers/systems.
*/
+#ifndef EPOCH_LOCAL
+# define EPOCH_LOCAL 0
+#endif
+#ifndef EPOCH_OFFSET
+# define EPOCH_OFFSET 0
+#endif
+
/*
** Compile with -Dtime_tz=T to build the tz package with a private
** time_t type equivalent to T rather than the system-supplied time_t.
** (e.g., time_t wider than 'long', or unsigned time_t) even on
** typical platforms.
*/
-#ifdef time_tz
+#if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
# ifdef LOCALTIME_IMPLEMENTATION
static time_t sys_time(time_t *x) { return time(x); }
# endif
#define MINVAL(t, b) \
((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
-/* The minimum and maximum finite time values. This assumes no padding. */
+/* The minimum and maximum finite time values. This implementation
+ assumes no padding if time_t is signed and either the compiler is
+ pre-C11 or time_t is not one of the standard signed integer types. */
+#if 201112 <= __STDC_VERSION__
+static time_t const time_t_min
+ = (TYPE_SIGNED(time_t)
+ ? _Generic((time_t) 0,
+ signed char: SCHAR_MIN, short: SHRT_MIN,
+ int: INT_MIN, long: LONG_MIN, long long: LLONG_MIN,
+ default: MINVAL(time_t, TYPE_BIT(time_t)))
+ : 0);
+static time_t const time_t_max
+ = (TYPE_SIGNED(time_t)
+ ? _Generic((time_t) 0,
+ signed char: SCHAR_MAX, short: SHRT_MAX,
+ int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX,
+ default: MAXVAL(time_t, TYPE_BIT(time_t)))
+ : -1);
+#else
static time_t const time_t_min = MINVAL(time_t, TYPE_BIT(time_t));
static time_t const time_t_max = MAXVAL(time_t, TYPE_BIT(time_t));
+#endif
#ifndef INT_STRLEN_MAXIMUM
/*
# stuck on Summer daylight savings time even though the summer is over.
# From Paul Eggert (2013-09-05):
-# Perhaps San Luis operates on the legal fiction that it is at UTC-4
+# Perhaps San Luis operates on the legal fiction that it is at -04
# with perpetual summer time, but ordinary usage typically seems to
-# just say it's at UTC-3; see, for example,
+# just say it's at -03; see, for example,
# http://es.wikipedia.org/wiki/Hora_oficial_argentina
# We've documented similar situations as being plain changes to
# standard time, so let's do that here too. This does not change UTC
tzset();
warn = IN_NONE;
- p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn);
+ p = _fmt(format, t, s, s + maxsize, &warn);
#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
fprintf(stderr, "\n");
- if (format == NULL)
- fprintf(stderr, "NULL strftime format ");
- else fprintf(stderr, "strftime format \"%s\" ",
- format);
+ fprintf(stderr, "strftime format \"%s\" ", format);
fprintf(stderr, "yields only two digits of years in ");
if (warn == IN_SOME)
fprintf(stderr, "some locales");
*/
continue;
case 'z':
+#if defined TM_GMTOFF || defined USG_COMPAT || defined ALTZONE
{
long diff;
char const * sign;
- if (t->tm_isdst < 0)
- continue;
-#ifdef TM_GMTOFF
+# ifdef TM_GMTOFF
diff = t->TM_GMTOFF;
-#else /* !defined TM_GMTOFF */
+# else
/*
** C99 says that the UT offset must
** be computed by looking only at
** determinable, so output nothing if the
** appropriate variables are not available.
*/
+ if (t->tm_isdst < 0)
+ continue;
if (t->tm_isdst == 0)
-#ifdef USG_COMPAT
+# ifdef USG_COMPAT
diff = -timezone;
-#else /* !defined USG_COMPAT */
+# else
continue;
-#endif /* !defined USG_COMPAT */
+# endif
else
-#ifdef ALTZONE
+# ifdef ALTZONE
diff = -altzone;
-#else /* !defined ALTZONE */
+# else
continue;
-#endif /* !defined ALTZONE */
-#endif /* !defined TM_GMTOFF */
+# endif
+# endif
if (diff < 0) {
sign = "-";
diff = -diff;
(diff % MINSPERHOUR);
pt = _conv(diff, "%04d", pt, ptlim);
}
+#endif
continue;
case '+':
pt = _fmt(Locale->date_fmt, t, pt, ptlim,
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>
<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>
The webcomic <em>xkcd</em> has the strip
"<a href='http://xkcd.com/673/'>The Sun</a>" (2009-12-09) and the panels
"<a href='http://xkcd.com/1017/'>Backward in Time</a>" (2012-02-14),
-"<a href='http://xkcd.com/1061/'>EST</a>" (2012-05-28), and
+"<a href='http://xkcd.com/1061/'>EST</a>" (2012-05-28),
+"<a href='http://xkcd.com/1179/'>ISO 8601</a>" (2013-02-27),
"<a href='http://xkcd.com/1335/'>Now</a>" (2014-02-26), and
"<a href='http://xkcd.com/1655/'>Doomsday Clock</a>" (2016-03-14).
The related book <em>What If?</em> has an entry
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-11-01">
<meta name="DC.Description"
content="Sources of information about time zones and daylight saving time">
<meta name="DC.Identifier"
is a summary of attempts to organize and record relevant data in this
area.
</p>
-<h2>The <code><abbr title="time zone">tz</abbr></code> database</h2>
+<h2 id="tzdb">The <code><abbr title="time zone">tz</abbr></code> database</h2>
<p>
The <a href="https://en.wikipedia.org/wiki/Public_domain">public-domain</a>
time zone database contains code and data
<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>),
<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.
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
+A <a href="https://github.com/eggert/tz">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
location.</p>
-<h2>Changes to the <code><abbr>tz</abbr></code> database</h2>
+<h2 id="changes">Changes to the <code><abbr>tz</abbr></code> database</h2>
<p>
The <code><abbr>tz</abbr></code> code and data
are by no means authoritative. If you find errors, please
send changes to the <a href="mailto:tz@iana.org">time zone
mailing list</a>. You can also <a
-href="http://news.gmane.org/gmane.comp.time.tz">browse recent
-messages</a> sent to the mailing list, <a
-href="https://mm.icann.org/mailman/listinfo/tz">subscribe</a> to it,
+href="https://mm.icann.org/mailman/listinfo/tz">subscribe</a> to it
and browse the <a
href="http://mm.icann.org/pipermail/tz/">archive of old
messages</a>.</p>
<a href="https://tools.ietf.org/html/rfc6557">Procedures for
Maintaining the Time Zone Database</a> (Internet <abbr
title="Request For Comments">RFC</abbr> 6557).</p>
-<h2>Commentary on the <code><abbr>tz</abbr></code> database</h2>
+<h2 id="commentary">Commentary on the <code><abbr>tz</abbr></code> database</h2>
<ul>
<li>The article
<a href="https://en.wikipedia.org/wiki/Tz_database">tz database</a> is
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>
-<h2>Web sites using recent versions of the <code><abbr>tz</abbr></code> database</h2>
+<h2 id="web">Web sites using recent versions of the
+<code><abbr>tz</abbr></code> database</h2>
<p>
These are listed roughly in ascending order of complexity and fanciness.
</p>
also contains data about time zone boundaries; it supports queries via place
names and shows location maps.</li>
</ul>
-<h2>Network protocols for <code><abbr>tz</abbr></code> data</h2>
+<h2 id="protocols">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>
+along with <a href="https://tools.ietf.org/html/rfc7809">CalDAV</a>
+(Internet <abbr>RFC</abbr> 7809), a calendar access protocol for
+transferring time zone data by reference. The draft <a name="TZDIST-Geolocate"
+href="https://tools.ietf.org/html/draft-murchison-tzdist-geolocate-00">TZDIST
+Geolocate Extension</a> lets a client determine its time zone region
+from its geographic location using a <a
+href="https://tools.ietf.org/html/rfc5870">'geo' URI</a>.</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)
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>
+<h2 id="compilers">Other <code><abbr>tz</abbr></code> compilers</h2>
<ul>
<li><a href="https://sourceforge.net/projects/vzic/">Vzic</a> is a <a
href="https://en.wikipedia.org/wiki/C_%28programming_language%29">C</a>
<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
runtime library. It is freely available under the
<a href="http://creativecommons.org/licenses/by/4.0/">Creative Commons
Attribution 4.0 International Public License</a>.</li>
-<li><a href="http://site.icu-project.org">International Components for
+<li><a name="ICU" href="http://site.icu-project.org">International Components for
Unicode (<abbr>ICU</abbr>)</a> contains C/C++ and <a
href="https://en.wikipedia.org/wiki/Java_%28programming_language%29">Java</a>
libraries for internationalization that
has a compiler from <code><abbr>tz</abbr></code> source
and from <abbr title="Common Locale Data Repository">CLDR</abbr> data
-(mentioned below)
+(mentioned <a href="#CLDR">below</a>)
into an <abbr>ICU</abbr>-specific format.
<abbr>ICU</abbr> is freely available under a
<abbr>BSD</abbr>-style license.</li>
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 <a href="#ICU">above</a>) 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:
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>.
zone repository whose format
is either proprietary or an <abbr>XML</abbr>-encoded
representation.</li>
-<li><a href="http://tcl.tk">Tcl</a>
+<li><a name="Tcl" href="http://tcl.tk">Tcl</a>
contains a developer-oriented parser that compiles <code><abbr>tz</abbr></code>
source into text files, along with a runtime that can read those
files. Tcl is freely available under a <abbr>BSD</abbr>-style
license.</li>
</ul>
-<h2>Other <code><abbr>tz</abbr></code> binary file readers</h2>
+<h2 id="binary">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.
<li><a href="https://github.com/bigeasy/timezone">Timezone</a> is a
JavaScript library that supports date arithmetic that is time zone
aware. It is freely available under the <abbr>MIT</abbr> license.</li>
-<li>Tcl, mentioned above, also contains a
+<li>Tcl, mentioned <a href="#Tcl">above</a>, also contains a
<code><abbr>tz</abbr></code> binary file reader.</li>
<li><a href="http://search.cpan.org/perldoc?DateTime::TimeZone::Tzfile">
DateTime::TimeZone::Tzfile</a>
parses and uses <code><abbr>tz</abbr></code> binary data. It is freely
available under a <abbr>BSD</abbr>-style license.</li>
</ul>
-<h2>Other <code><abbr>tz</abbr></code>-based time zone software</h2>
+<h2 id="software">Other <code><abbr>tz</abbr></code>-based time zone software</h2>
<ul>
<li><a href="https://foxclocks.org">FoxClocks</a>
is an extension for <a href="https://www.google.com/chrome/">Google
under the <abbr>GPL</abbr>.</li>
<li>Microsoft Windows 8.1
and later has <code><abbr>tz</abbr></code> data and <abbr>CLDR</abbr>
-data (mentioned below) used by
+data (mentioned <a href="#CLDR">below</a>) used by
<a href="https://en.wikipedia.org/wiki/Windows_Runtime">Windows Runtime</a>
classes such as <a
href="https://msdn.microsoft.com/en-us/library/windows/apps/windows.globalization.datetimeformatting.datetimeformatter.aspx"><code>DateTimeFormatter</code></a>.
-<a
+<a name="System.TimeZoneInfo"
href="https://blogs.msdn.microsoft.com/bclteam/2007/06/07/exploring-windows-time-zones-with-system-timezoneinfo-josh-free/">Exploring
Windows Time Zones with <code>System.TimeZoneInfo</code></a> describes
the older, proprietary method of Microsoft Windows 2000 and later,
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
<a href="http://veladg.com/tzoffer.html">offer free
licenses</a> to <code><abbr>tz</abbr></code> contributors.</li>
</ul>
-<h2>Other time zone databases</h2>
+<h2 id="other-dbs">Other time zone databases</h2>
<ul>
<li><a href="http://www.astro.com/atlas">Time-zone Atlas</a>
is Astrodienst's Web version of Shanks and Pottenger's
sources and do not indicate which entries are guesswork.</li>
<li><a href="https://en.wikipedia.org/wiki/HP-UX">HP-UX</a> has a database in
its own <code>tztab</code>(4) format.</li>
-<li>Microsoft Windows has proprietary data mentioned above.</li>
+<li>Microsoft Windows has proprietary data mentioned
+<a href="#System.TimeZoneInfo">above</a>.</li>
<li><a href="http://www.worldtimeserver.com">World Time Server</a>
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>
</ul>
-<h2>Maps</h2>
+<h2 id="maps">Maps</h2>
<ul>
<li>The <a href="https://www.cia.gov/index.html">United States Central
Intelligence Agency (<abbr
mean solar and standard time, highlighting areas such as western China
where the two differ greatly. It's a bit out of date, unfortunately.</li>
</ul>
-<h2>Time zone boundaries</h2>
+<h2 id="boundaries">Time zone boundaries</h2>
+<p>Geographical boundaries between time zone regions are available
+from several <a href="https://en.wikipedia.org/wiki/Geolocation">geolocation</a>
+services and other sources.</p>
+<ul>
+<li>Databases of time zone boundaries include:
<ul>
+<li><a href="https://github.com/evansiroky/timezone-boundary-builder">Timezone
+Boundary Builder</a> extracts
+<a href="http://www.openstreetmap.org">Open Street Map</a> data to build
+boundaries of <code><abbr>tz</abbr></code> regions.
+Its code is freely available under the <abbr>MIT</abbr> license, and
+its data entries are freely available under the
+<a href="http://opendatacommons.org/licenses/odbl/">Open Data Commons
+Open Database License</a>. The maps' borders appear to be quite accurate.</li>
<li><a href="http://efele.net/maps/tz/"><abbr>TZ</abbr> timezones
maps</a> contains <a
href="https://en.wikipedia.org/wiki/Shapefile">shapefiles</a> of
-sets of <code><abbr>tz</abbr></code> regions.</li>
+sets of <code><abbr>tz</abbr></code> regions. This includes
+<a href="http://efele.net/maps/tz/world/">tz_world</a>, a shapefile
+for all the world's regions</li>
+<li><a
+href="https://github.com/straup/whereonearth-timezone">Whereonearth-timezone</a>
+is in <a href="http://geojson.org">GeoJSON</a> form, and combines the
+the tz_world shapefiles with the GeoPlanet dataset.</li>
+</ul></li>
+<li>Programmatic interfaces that map geographical coordinates via tz_world to
+<code><abbr>tz</abbr></code> regions include:
+<ul>
+<li><a href="https://github.com/mj1856/GeoTimeZone">GeoTimeZone</a> is
+written in <a
+href="https://en.wikipedia.org/wiki/C_Sharp_(programming_language)">C#</a>
+and is freely available under the <abbr>MIT</abbr> license.</li>
<li>The <a href="https://github.com/bradfitz/latlong">latlong package</a>
-maps geographical coordinates to a <code><abbr>tz</abbr></code> region.
-It is written in Go and is freely available under the Apache License.</li>
+is written in Go and is freely available under the Apache License.</li>
+<li><a href="https://github.com/drtimcooper/LatLongToTimezone">LatLongToTimezone</a>,
+in both Java and
+<a href="https://en.wikipedia.org/wiki/Swift_(programming_language)">Swift</a>
+form, is freely available under the MIT license.</li>
+<li>The <a
+href="https://github.com/MrMinimal64/timezonefinder">timezonefinder</a>
+library for Python is freely available under the MIT license.
+<li>The <a
+href="https://github.com/gunyarakun/timezone_finder">timezone_finder</a>
+library for Ruby is freely available under the MIT license.</li>
+<li>The <a href="https://www.npmjs.com/package/tz-lookup">tz-lookup module</a>
+for <a href="https://nodejs.org/en/">Node.js</a> is in the public domain.</li>
<li><a href="https://derickrethans.nl/what-time-is-it.html">What Time
is It Here?</a> applies <a href="https://www.mongodb.com">MongoDB</a>
geospatial query operators to shapefiles' data.</li>
+</ul></li>
+<li>Free access via a network API, if you register a key, is provided by
+the <a href="http://www.geonames.org/export/web-services.html#timezone">GeoNames Timezone web service</a>,
+the <a href="https://developers.google.com/maps/documentation/timezone/intro">Google Maps Time Zone API</a>, and
+the <a href="https://timezonedb.com">Time Zone Database & API</a>.
+Commercial network API access is provided
+by <a href="https://askgeo.com">AskGeo</a>
+and <a href="https://www.geogarage.com/blog/news-1/post/geogarage-time-zone-api-31">GeoGarage</a>.
+Also, an <a
+href="http://mm.icann.org/pipermail/tz/2016-October/024309.html">experimental
+server</a> is available for the TZDIST Geolocate Extension mentioned
+<a href="#TZDIST-Geolocate">above</a>.</li>
+<li>"<a
+href="http://stackoverflow.com/questions/16086962/how-to-get-a-time-zone-from-a-location-using-latitude-and-longitude-coordinates/16086964">How
+to get a time zone from a location using latitude and longitude
+coordinates?</a>" discusses other geolocation possibilities.</li>
<li><a href="http://statoids.com/statoids.html">Administrative
-Divisions of Countries ("Statoids")</a> contains lists of
+Divisions of Countries ("Statoids")</a> lists
political subdivision data related to time zones.</li>
<li><a href="http://home.kpn.nl/vanadovv/time/Multizones.html">Time
zone boundaries for multizone countries</a> summarizes legal
clocks any time after entering a new time zone; midnight changes are
common.</li>
</ul>
-<h2>Civil time concepts and history</h2>
+<h2 id="civil">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
<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>
<li><a href="http://statoids.com/tconcept.html">Basic Time
Zone Concepts</a> discusses terminological issues behind time zones.</li>
</ul>
-<h2>National histories of legal time</h2>
+<h2 id="national">National histories of legal time</h2>
<dl>
<dt>Australia</dt>
<dd>The Parliamentary Library has commissioned a <a
<dd>The Interior Ministry periodically issues <a
href="ftp://ftp.cs.huji.ac.il/pub/tz/announcements"
hreflang="he">announcements (in Hebrew)</a>.</dd>
+<dt>Italy</dt>
+<dd>The National Institute of Metrological Research maintains a
+<a href="http://www.inrim.it/res/tf/ora_legale_i.shtml">table of civil time
+(in Italian)</a>.</dd>
<dt>Mexico</dt>
<dd>The Investigation and Analysis Service of the Mexican Library of
Congress has published a <a
href="http://www.diputados.gob.mx/bibliot/publica/inveyana/polisoc/horver/index.htm"
hreflang="es">history of Mexican local time (in Spanish)</a>.</dd>
<dt>Malaysia</dt>
-<dd>See Singapore below.</dd>
+<dd>See Singapore <a href="#Singapore">below</a>.</dd>
<dt>Netherlands</dt>
<dd><a href="http://www.staff.science.uu.nl/~gent0113/wettijd/wettijd.htm"
hreflang="nl">Legal time in the Netherlands (in Dutch)</a>
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>
<dt>Singapore</dt>
-<dd><a
+<dd><a name="Singapore"
href="http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html">Why
is Singapore in the "Wrong" Time Zone?</a> details the
history of legal time in Singapore and Malaysia.</dd>
legal time in Britain</a> discusses in detail the country
with perhaps the best-documented history of clock adjustments.
The National Physical Laboratory also maintains an <a
-href="http://www.npl.co.uk/educate-explore/what-is-time/archive-of-summer-time-dates-1916-2006">Archive
+href="http://www.npl.co.uk/educate-explore/what-is-time/archive-of-summer-time-dates">Archive
of Summer time dates</a>.</dd>
<dt>United States</dt>
<dd>The Department of Transportation's <a
href="https://www.transportation.gov/regulations/recent-time-zone-proceedings">Recent
Time Zone Proceedings</a> lists changes to time zone boundaries.</dd>
</dl>
-<h2>Precision timekeeping</h2>
+<h2 id="precision">Precision timekeeping</h2>
<ul>
<li><a
href="http://literature.agilent.com/litweb/pdf/5965-7984E.pdf">The
to the theory and practice of precision timekeeping.</li>
<li><a href="http://www.ntp.org"><abbr
title="Network Time Protocol">NTP</abbr>: The Network
-Time Protocol</a>
+Time Protocol</a> (Internet <abbr>RFC</abbr> 5905)
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>
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
<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>
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
<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
without Leap Seconds</a> gives pointers on this
contentious issue.</li>
</ul>
-<h2>Time notation</h2>
+<h2 id="notation">Time notation</h2>
<ul>
-<li>The <a href="http://cldr.unicode.org">Unicode Common Locale Data
+<li>The <a name="CLDR" href="http://cldr.unicode.org">Unicode Common Locale Data
Repository (<abbr>CLDR</abbr>) Project</a> has localizations for time
zone names, abbreviations, identifiers, and formats. For example, it
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>.
<a href="https://www.w3.org/TR/xmlschema-2/#dateTime"><abbr>XML</abbr>
Schema: Datatypes – dateTime</a> specifies a format inspired by
<abbr>ISO</abbr> 8601 that is in common use in <abbr>XML</abbr> data.</li>
-<li>
-<a href="https://tools.ietf.org/html/rfc5322">Internet
-Message Format</a> (Internet <abbr>RFC</abbr> 5322) §3.3
+<li><a href="https://tools.ietf.org/html/rfc5322#section-3.3">§3.3 of
+Internet Message Format</a> (Internet <abbr>RFC</abbr> 5322)
specifies the time notation used in email and <a
href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol"><abbr>HTTP</abbr></a>
headers.</li>
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>
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>
-<h2>See also</h2>
+<h2 id="see-also">See also</h2>
<ul>
<li><a href="tz-art.htm">Time and the Arts</a></li>
</ul>
.SH NAME
tzfile \- time zone information
.SH DESCRIPTION
+.ie '\(lq'' .ds lq \&"\"
+.el .ds lq \(lq\"
+.ie '\(rq'' .ds rq \&"\"
+.el .ds rq \(rq\"
+.de q
+\\$3\*(lq\\$1\*(rq\\$2
+..
The time zone information files used by
.IR tzset (3)
begin with the magic characters "TZif" to identify them as
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
+.q "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
+.q "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
After the second header and data comes a newline-enclosed, POSIX-TZ-
environment-variable-style string for use in handling instants after
the last transition time stored in the file (with nothing between the
- newlines if there is no POSIX representation for such instants).
+ 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
+ "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 "WEST" that is one hour east of UT.
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
.I zonename
\&... ]
.SH DESCRIPTION
+.ie '\(lq'' .ds lq \&"\"
+.el .ds lq \(lq\"
+.ie '\(rq'' .ds rq \&"\"
+.el .ds rq \(rq\"
+.de q
+\\$3\*(lq\\$1\*(rq\\$2
+..
.ie \n(.g .ds - \f(CW-\fP
.el ds - \-
.I Zdump
.BI "\*-\*-version"
Output version information and exit.
.TP
+.B \*-i
+.I "(This option is experimental: its behavior may change in future versions.)"
+Output a description of time intervals. For each
+.I zonename
+on the command line, output an interval-format description of the
+zone. See
+.q "INTERVAL FORMAT"
+below.
+.TP
.B \*-v
+Output a verbose description of time intervals.
For each
.I zonename
on the command line,
implementations with different time representations.
.TP
.BI "\*-c " [loyear,]hiyear
-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
.BR \*-500,2500 .
.TP
.BI "\*-t " [lotime,]hitime
-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
As with
.BR \*-c ,
the cutoff's lower bound is exclusive and its upper bound is inclusive.
+.SH "INTERVAL FORMAT"
+.I "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
+.q "TZ=\fIstring\fP"
+where
+.I string
+is a double-quoted string giving the zone name, a second line
+.q "\*- \*- \fIinterval\fP"
+describing the time interval before the first transition if any, and
+zero or more following lines
+.q "\fIdate time interval\fP",
+one line for each transition time and following interval. Fields are
+separated by single tabs.
+.PP
+Dates are in
+.IR yyyy - mm - dd
+format and times are in 24-hour
+.IR hh : mm : ss
+format where
+.IR hh <24.
+Times are in local time immediately after the transition. A
+time interval description consists of a UT offset in signed
+.RI \(+- 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
+.q "\*-"
+or is
+.q "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
+\*(lq"CET\es\e"\e\e"\*(rq represents the character sequence \*(lqCET
+"\e\*(rq.\""
+.PP
+.ne 9
+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.)
+.nf
+.sp
+.if \n(.g .ft CW
+.if t .in +.5i
+.if n .in +2
+.nr w \w'1896-01-13 'u
+.ta \nwu +\nwu +\nwu +\nwu
+TZ="Pacific/Honolulu"
+- - -10:31:26 LMT
+1896-01-13 12:01:26 -10:30 HST
+1933-04-30 03 -09:30 HDT 1
+1933-05-21 11 -10:30 HST
+1942-02-09 03 -09:30 HDT 1
+1945-09-30 01 -10:30 HST
+1947-06-08 02:30 -10 HST
+.in
+.if \n(.g .ft
+.sp
+.fi
+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
+.ne 10
+Here are excerpts from another example:
+.nf
+.sp
+.if \n(.g .ft CW
+.if t .in +.5i
+.if n .in +2
+TZ="Europe/Astrakhan"
+- - +03:12:12 LMT
+1924-04-30 23:47:48 +03
+1930-06-21 01 +04
+1981-04-01 01 +05 1
+1981-09-30 23 +04
+\&...
+2014-10-26 01 +03
+2016-03-27 03 +04
+.in
+.if \n(.g .ft
+.sp
+.fi
+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, "UT" denotes the value returned by
+In the
+.B \*-v
+and
+.B \*-V
+output,
+.q "UT"
+denotes the value returned by
.IR gmtime (3),
which uses UTC for modern time stamps and some other UT flavor for
time stamps that predate the introduction of UTC.
-No attempt is currently made to have the output use "UTC" for newer
-and "UT" for older time stamps,
-partly because the exact date of the introduction of UTC is problematic.
+No attempt is currently made to have the output use
+.q "UTC"
+for newer and
+.q "UT"
+for older time stamps, partly because the exact date of the
+introduction of UTC is problematic.
.SH "SEE ALSO"
newctime(3), tzfile(5), zic(8)
.\" This file is in the public domain, so clarified as of
--version
Output version information and exit.
- -v For each zonename on the command line, print the time at the
- lowest possible time value, the time one day after the lowest
- possible time value, the times both one second before and
- exactly at 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 isdst=D
- where 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 gmtoff=N
- if the given local time is known to be N seconds east of
- Greenwich.
+ -i (This option is experimental: its behavior may change in future
+ versions.) Output a description of time intervals. For each
+ zonename on the command line, output an interval-format
+ description of the zone. See "INTERVAL FORMAT" below.
+
+ -v Output a verbose description of time intervals. For each
+ zonename on the command line, print the time at the lowest
+ possible time value, the time one day after the lowest possible
+ time value, the times both one second before and exactly at 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 isdst=D where 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 gmtoff=N if
+ the given local time is known to be N seconds east of Greenwich.
-V Like -v, except omit the times relative to the extreme time
values. This generates output that is easier to compare to that
of implementations with different time representations.
-c [loyear,]hiyear
- Cut off verbose output at the given year(s). Cutoff times are
+ 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 loyear
cutoff is -500,2500.
-t [lotime,]hitime
- Cut off verbose output at the given time(s), given in decimal
+ 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 zonename determines whether the count includes leap
seconds. As with -c, the cutoff's lower bound is exclusive and
its upper bound is inclusive.
+INTERVAL FORMAT
+ This format is experimental: it may change in future versions.
+
+ 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 "TZ=string" where string is a double-quoted string giving
+ the zone name, a second line "- - interval" describing the time
+ interval before the first transition if any, and zero or more following
+ lines "date time interval", one line for each transition time and
+ following interval. Fields are separated by single tabs.
+
+ Dates are in yyyy-mm-dd format and times are in 24-hour hh:mm:ss format
+ where hh<24. Times are in local time immediately after the transition.
+ A time interval description consists of a UT offset in signed
+ +-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.
+
+ 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 "-" or is "zzz".
+
+ In double-quoted strings, escape sequences represent unusual
+ characters. The escape sequences are \s for space, and \", \\, \f, \n,
+ \r, \t, and \v with their usual meaning in the C programming language.
+ E.g., the double-quoted string ""CET\s\"\\"" represents the character
+ sequence "CET "\".
+
+ 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.)
+
+ TZ="Pacific/Honolulu"
+ - - -10:31:26 LMT
+ 1896-01-13 12:01:26 -10:30 HST
+ 1933-04-30 03 -09:30 HDT 1
+ 1933-05-21 11 -10:30 HST
+ 1942-02-09 03 -09:30 HDT 1
+ 1945-09-30 01 -10:30 HST
+ 1947-06-08 02:30 -10 HST
+
+ 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.
+
+ Here are excerpts from another example:
+
+ TZ="Europe/Astrakhan"
+ - - +03:12:12 LMT
+ 1924-04-30 23:47:48 +03
+ 1930-06-21 01 +04
+ 1981-04-01 01 +05 1
+ 1981-09-30 23 +04
+ ...
+ 2014-10-26 01 +03
+ 2016-03-27 03 +04
+
+ 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.
+
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.
- In the output, "UT" denotes the value returned by gmtime(3), which uses
- UTC for modern time stamps and some other UT flavor for time stamps
- that predate the introduction of UTC. No attempt is currently made to
- have the output use "UTC" for newer and "UT" for older time stamps,
- partly because the exact date of the introduction of UTC is
+ In the -v and -V output, "UT" denotes the value returned by gmtime(3),
+ which uses UTC for modern time stamps and some other UT flavor for time
+ stamps that predate the introduction of UTC. No attempt is currently
+ made to have the output use "UTC" for newer and "UT" for older time
+ stamps, partly because the exact date of the introduction of UTC is
problematic.
SEE ALSO
# define HAVE_STDINT_H \
(199901 <= __STDC_VERSION__ \
|| 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
- || __CYGWIN__)
+ || __CYGWIN__ || INTMAX_MAX)
#endif
#if HAVE_STDINT_H
# include "stdint.h"
# 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 */
# 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;
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;
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
while (*e++)
continue;
- env = malloc(sumsize(sizeof *environ,
- (e - environ) * sizeof *environ));
- if (! env) {
- perror(progname);
- exit(EXIT_FAILURE);
- }
+ env = xmalloc(sumsize(sizeof *environ,
+ (e - environ) * sizeof *environ));
to = 1;
for (e = environ; (env[to] = *e); e++)
to += strncmp(*e, "TZ=", 3) != 0;
}
- env0 = malloc(sumsize(sizeof "TZ=", strlen(val)));
- if (! env0) {
- perror(progname);
- exit(EXIT_FAILURE);
- }
+ env0 = xmalloc(sumsize(sizeof "TZ=", strlen(val)));
env[0] = strcat(strcpy(env0, "TZ="), val);
environ = fakeenv = env;
tzset();
to avoid O(N**2) behavior on repeated calls. */
*bufalloc = sumsize(*bufalloc, ablen + 1);
- *buf = malloc(*bufalloc);
- if (! *buf) {
- perror(progname);
- exit(EXIT_FAILURE);
- }
+ *buf = xmalloc(*bufalloc);
}
return strcpy(*buf, ab);
}
usage(FILE * const stream, const int status)
{
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);
/* These are static so that they're initially zero. */
static char * abbrev;
static size_t abbrevsize;
- static struct tm newtm;
register int i;
register bool vflag;
register time_t cutlotime;
register time_t cuthitime;
time_t now;
- time_t t;
- time_t newt;
- struct tm tm;
- register struct tm * tmp;
- register struct tm * newtmp;
+ bool iflag = false;
cutlotime = absolute_min_time;
cuthitime = absolute_max_time;
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:
}
arg_processing_done:;
- if (vflag | Vflag) {
+ if (iflag | vflag | Vflag) {
intmax_t lo;
intmax_t hi;
char *loend, *hiend;
}
}
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]);
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) {
perror(argv[i]);
return EXIT_FAILURE;
}
- 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);
+ if (iflag) {
+ showtrans("\nTZ=%f", &tm, t, ab, argv[i]);
+ showtrans("-\t-\t%Q", &tm, t, ab, argv[i]);
+ }
+ }
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)) {
- newt = hunt(tz, argv[i], t, newt);
- newtmp = localtime_rz(tz, &newt, &newtm);
- if (newtmp)
- ab = saveabbr(&abbrev, &abbrevsize,
- &newtm);
- }
- t = newt;
- tm = newtm;
- tmp = newtmp;
+ 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);
+ 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_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);
char const * ab;
time_t t;
struct tm lotm;
- register struct tm * lotmp;
struct tm tm;
- register 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);
for ( ; ; ) {
time_t diff = hit - lot;
++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;
}
/* 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 {
if (*abbr(tmp) != '\0')
printf(" %s", abbr(tmp));
if (v) {
- long off = gmtoff(tmp, gmtmp);
+ long off = gmtoff(tmp, NULL, gmtmp);
printf(" isdst=%d", tmp->tm_isdst);
if (off != LONG_MIN)
printf(" gmtoff=%ld", off);
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 && 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
+ ? 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 (! (0 <= formatted_len && 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 char const *
abbr(struct tm const *tmp)
{
#include "tzfile.h"
#include <stdarg.h>
+#include <stddef.h>
#define ZIC_VERSION_PRE_2013 '2'
#define ZIC_VERSION '3'
typedef int_fast64_t zic_t;
#define ZIC_MIN INT_FAST64_MIN
#define ZIC_MAX INT_FAST64_MAX
+#define PRIdZIC PRIdFAST64
#define SCNdZIC SCNdFAST64
#ifndef ZIC_MAX_ABBR_LEN_WO_WARN
#define MKDIR_UMASK 0755
#endif
+/* The maximum ptrdiff_t value, for pre-C99 platforms. */
+#ifndef PTRDIFF_MAX
+static ptrdiff_t const PTRDIFF_MAX = MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t));
+#endif
+
+/* The type and printf format for line numbers. */
+typedef intmax_t lineno;
+#define PRIdLINENO PRIdMAX
+
struct rule {
const char * r_filename;
- int r_linenum;
+ lineno r_linenum;
const char * r_name;
zic_t r_loyear; /* for example, 1986 */
zic_t r_stdoff; /* offset from standard time */
const char * r_abbrvar; /* variable part of abbreviation */
- int r_todo; /* a rule to do (used in outzone) */
+ bool r_todo; /* a rule to do (used in outzone) */
zic_t r_temp; /* used in outzone */
};
struct zone {
const char * z_filename;
- int z_linenum;
+ lineno z_linenum;
const char * z_name;
zic_t z_gmtoff;
zic_t z_stdoff;
struct rule * z_rules;
- int z_nrules;
+ ptrdiff_t z_nrules;
struct rule z_untilrule;
zic_t z_untiltime;
# 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);
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);
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);
+static void outzone(const struct zone * zp, ptrdiff_t ntzones);
static zic_t rpytime(const struct rule * rp, zic_t wantedy);
static void rulesub(struct rule * rp,
const char * loyearp, const char * hiyearp,
const char * typep, const char * monthp,
const char * dayp, const char * timep);
static zic_t tadd(zic_t t1, zic_t t2);
-static bool yearistype(int year, const char * type);
+static bool yearistype(zic_t year, const char * type);
/* Bound on length of what %z can expand to. */
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. */
static bool leapseen;
static zic_t leapminyear;
static zic_t leapmaxyear;
-static int linenum;
+static lineno linenum;
static int max_abbrvar_len = PERCENT_Z_LEN_BOUND;
static int max_format_len;
static zic_t max_year;
static zic_t min_year;
static bool noise;
static const char * rfilename;
-static int rlinenum;
+static lineno rlinenum;
static const char * progname;
-static int timecnt;
-static int timecnt_alloc;
+static ptrdiff_t timecnt;
+static ptrdiff_t timecnt_alloc;
static int typecnt;
/*
#define YR_ONLY 2
static struct rule * rules;
-static int nrules; /* number of rules */
-static int nrules_alloc;
+static ptrdiff_t nrules; /* number of rules */
+static ptrdiff_t nrules_alloc;
static struct zone * zones;
-static int nzones; /* number of zones */
-static int nzones_alloc;
+static ptrdiff_t nzones; /* number of zones */
+static ptrdiff_t nzones_alloc;
struct link {
const char * l_filename;
- int l_linenum;
+ lineno l_linenum;
const char * l_from;
const char * l_to;
};
static struct link * links;
-static int nlinks;
-static int nlinks_alloc;
+static ptrdiff_t nlinks;
+static ptrdiff_t nlinks_alloc;
struct lookup {
const char * l_word;
static struct attype {
zic_t at;
+ bool dontmerge;
unsigned char type;
} * attypes;
static zic_t gmtoffs[TZ_MAX_TYPES];
}
static void *
-growalloc(void *ptr, size_t itemsize, int nitems, int *nitems_alloc)
+growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
{
if (nitems < *nitems_alloc)
return ptr;
else {
- int nitems_max = INT_MAX - WORK_AROUND_QTBUG_53071;
- int amax = nitems_max < SIZE_MAX ? nitems_max : SIZE_MAX;
+ ptrdiff_t nitems_max = PTRDIFF_MAX - WORK_AROUND_QTBUG_53071;
+ ptrdiff_t amax = nitems_max < SIZE_MAX ? nitems_max : SIZE_MAX;
if ((amax - 1) / 3 * 2 < *nitems_alloc)
- memory_exhausted(_("int overflow"));
- *nitems_alloc = *nitems_alloc + (*nitems_alloc >> 1) + 1;
+ memory_exhausted(_("integer overflow"));
+ *nitems_alloc += (*nitems_alloc >> 1) + 1;
return erealloc(ptr, size_product(*nitems_alloc, itemsize));
}
}
*/
static void
-eats(const char *const name, const int num, const char *const rname,
- const int rnum)
+eats(char const *name, lineno num, char const *rname, lineno rnum)
{
filename = name;
linenum = num;
}
static void
-eat(const char *const name, const int num)
+eat(char const *name, lineno num)
{
eats(name, num, NULL, -1);
}
** on BSD systems.
*/
if (filename)
- fprintf(stderr, _("\"%s\", line %d: "), filename, linenum);
+ fprintf(stderr, _("\"%s\", line %"PRIdLINENO": "), filename, linenum);
vfprintf(stderr, string, args);
if (rfilename != NULL)
- fprintf(stderr, _(" (rule from \"%s\", line %d)"),
+ fprintf(stderr, _(" (rule from \"%s\", line %"PRIdLINENO")"),
rfilename, rlinenum);
fprintf(stderr, "\n");
}
}
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);
}
}
"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;
int
main(int argc, char **argv)
{
- register int i;
- register int j;
- register int c;
+ register int c, k;
+ register ptrdiff_t i, j;
#ifdef S_IWGRP
umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
_("wild compilation-time specification of zic_t"));
return EXIT_FAILURE;
}
- for (i = 1; i < argc; ++i)
- if (strcmp(argv[i], "--version") == 0) {
+ for (k = 1; k < argc; k++)
+ if (strcmp(argv[k], "--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) {
+ } else if (strcmp(argv[k], "--help") == 0) {
usage(stdout, EXIT_SUCCESS);
}
while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF && c != -1)
adjleap();
}
- for (i = optind; i < argc; ++i)
- infile(argv[i]);
+ for (k = optind; k < argc; k++)
+ infile(argv[k]);
if (errors)
return EXIT_FAILURE;
associate();
+ change_directory(directory);
for (i = 0; i < nzones; i = j) {
/*
** Find the next non-continuation zone entry.
*/
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,
}
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;
char const *component_end)
{
enum { component_len_max = 14 };
- size_t component_len = component_end - component;
+ ptrdiff_t component_len = component_end - component;
if (component_len == 0) {
if (!*name)
error (_("empty file name"));
}
if (0 < component_len && component_len <= 2
&& component[0] == '.' && component_end[-1] == '.') {
+ int len = component_len;
error(_("file name '%s' contains '%.*s' component"),
- name, (int) component_len, component);
+ name, len, component);
return false;
}
if (noise) {
return componentcheck(name, component, cp);
}
+/* Create symlink contents suitable for symlinking FROM to TO, as a
+ freshly allocated string. FROM should be a relative file name, and
+ is relative to the global variable DIRECTORY. TO can be either
+ relative or absolute. */
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 = emalloc(dir_len + needs_slash + strlen(base) + 1);
- result[dir_len] = '/';
- strcpy(result + dir_len + needs_slash, base);
- return memcpy(result, dir, dir_len);
+relname(char const *from, char const *to)
+{
+ size_t i, taillen, dotdotetcsize;
+ size_t dir_len = 0, dotdots = 0, linksize = SIZE_MAX;
+ char const *f = from;
+ char *result = NULL;
+ if (*to == '/') {
+ /* Make F absolute too. */
+ size_t len = strlen(directory);
+ bool needslash = len && directory[len - 1] != '/';
+ linksize = len + needslash + strlen(from) + 1;
+ f = result = emalloc(linksize);
+ strcpy(result, directory);
+ result[len] = '/';
+ strcpy(result + len + needslash, from);
+ }
+ for (i = 0; f[i] && f[i] == to[i]; i++)
+ if (f[i] == '/')
+ dir_len = i + 1;
+ for (; f[i]; i++)
+ dotdots += f[i] == '/' && f[i - 1] != '/';
+ taillen = i - dir_len;
+ dotdotetcsize = 3 * dotdots + taillen + 1;
+ if (dotdotetcsize <= linksize) {
+ if (!result)
+ result = emalloc(dotdotetcsize);
+ for (i = 0; i < dotdots; i++)
+ memcpy(result + 3 * i, "../", 3);
+ memmove(result + 3 * dotdots, f + dir_len, taillen + 1);
}
+ return result;
}
static void
-dolink(char const *fromfield, char const *tofield)
+dolink(char const *fromfield, char const *tofield, bool staysymlink)
{
- register char * fromname;
- register char * toname;
register 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) {
+ bool absolute = *fromfield == '/';
+ char *linkalloc = absolute ? NULL : relname(fromfield, tofield);
+ char const *contents = absolute ? fromfield : linkalloc;
+ int symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
+ if (symlink_errno == ENOENT && !todirs_made) {
+ mkdirs(tofield, true);
+ symlink_errno = symlink(contents, 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 = emalloc(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(linkalloc);
+ 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
-static zic_t const min_time = MINVAL (zic_t, TIME_T_BITS_IN_FILE);
-static zic_t const max_time = MAXVAL (zic_t, TIME_T_BITS_IN_FILE);
+static zic_t const min_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
+static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
/* Estimated time of the Big Bang, in seconds since the POSIX epoch.
rounded downward to the negation of a power of two that is
? 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;
}
{
register struct zone * zp;
register struct rule * rp;
- register int base, out;
- register int i, j;
+ register ptrdiff_t i, j, base, out;
if (nrules != 0) {
qsort(rules, nrules, sizeof *rules, rcomp);
register const struct lookup * lp;
register int nfields;
register bool wantcont;
- register int num;
+ register lineno num;
char buf[BUFSIZ];
if (strcmp(name, "-") == 0) {
lp = byword(fields[0], line_codes);
if (lp == NULL)
error(_("input line of unknown type"));
- else switch ((int) (lp->l_value)) {
+ else switch (lp->l_value) {
case LC_RULE:
inrule(fields, nfields);
wantcont = false;
}
free(fields);
}
- close_file(fp, filename);
+ close_file(fp, NULL, filename);
if (wantcont)
error(_("expected continuation line not found"));
}
static bool
inzone(char **fields, int nfields)
{
- register int i;
+ register ptrdiff_t i;
if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS) {
error(_("wrong number of fields on Zone line"));
for (i = 0; i < nzones; ++i)
if (zones[i].z_name != NULL &&
strcmp(zones[i].z_name, fields[ZF_NAME]) == 0) {
- error(
-_("duplicate zone name %s (file \"%s\", line %d)"),
+ error(_("duplicate zone name %s"
+ " (file \"%s\", line %"PRIdLINENO")"),
fields[ZF_NAME],
zones[i].z_filename,
zones[i].z_linenum);
{
register const char * cp;
register const struct lookup * lp;
- register int i, j;
+ register zic_t i, j;
zic_t year;
int month, day;
zic_t dayoff, tod;
cp = loyearp;
lp = byword(cp, begin_years);
rp->r_lowasnum = lp == NULL;
- if (!rp->r_lowasnum) switch ((int) lp->l_value) {
+ if (!rp->r_lowasnum) switch (lp->l_value) {
case YR_MINIMUM:
rp->r_loyear = ZIC_MIN;
break;
cp = hiyearp;
lp = byword(cp, end_years);
rp->r_hiwasnum = lp == NULL;
- if (!rp->r_hiwasnum) switch ((int) lp->l_value) {
+ if (!rp->r_hiwasnum) switch (lp->l_value) {
case YR_MINIMUM:
rp->r_hiyear = ZIC_MIN;
break;
writezone(const char *const name, const char *const string, char version)
{
register FILE * fp;
- register int i, j;
+ register ptrdiff_t i, j;
register int leapcnt32, leapi32;
- register int timecnt32, timei32;
+ register ptrdiff_t timecnt32, timei32;
register 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;
+ ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071;
zic_t *ats = emalloc(size_product(nats, sizeof *ats + 1));
void *typesptr = ats + nats;
unsigned char *types = typesptr;
** Optimize.
*/
{
- int fromi;
- int toi;
+ ptrdiff_t fromi, toi;
toi = 0;
fromi = 0;
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;
}
- if (noise && timecnt > 1200)
+
+ if (noise && timecnt > 1200) {
+ if (timecnt > TZ_MAX_TIMES)
+ warning(_("reference clients mishandle"
+ " more than %d transition times"),
+ TZ_MAX_TIMES);
+ else
warning(_("pre-2014 clients may mishandle"
" more than 1200 transition times"));
+ }
/*
** Transfer.
*/
--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) {
- register int thistimei, thistimecnt;
- register int thisleapi, thisleapcnt;
- register int thistimelim, thisleaplim;
+ register ptrdiff_t thistimei, thistimecnt, thistimelim;
+ register int thisleapi, thisleapcnt, thisleaplim;
int writetype[TZ_MAX_TYPES];
int typemap[TZ_MAX_TYPES];
register int thistypecnt;
char thischars[TZ_MAX_CHARS];
- char thischarcnt;
+ int thischarcnt;
+ bool toomanytimes;
int indmap[TZ_MAX_CHARS];
if (pass == 1) {
thistimei = timei32;
thistimecnt = timecnt32;
+ toomanytimes = thistimecnt >> 31 >> 1 != 0;
thisleapi = leapi32;
thisleapcnt = leapcnt32;
} else {
thistimei = 0;
thistimecnt = timecnt;
+ toomanytimes = thistimecnt >> 31 >> 31 >> 2 != 0;
thisleapi = 0;
thisleapcnt = leapcnt;
}
+ if (toomanytimes)
+ error(_("too many transition times"));
thistimelim = thistimei + thistimecnt;
thisleaplim = thisleapi + thisleapcnt;
for (i = 0; i < typecnt; ++i)
if (strcmp(&thischars[j], thisabbr) == 0)
break;
if (j == thischarcnt) {
- strcpy(&thischars[(int) thischarcnt],
- thisabbr);
+ strcpy(&thischars[thischarcnt], thisabbr);
thischarcnt += strlen(thisabbr) + 1;
}
indmap[abbrinds[i]] = j;
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 *
enum { YEAR_BY_YEAR_ZONE = 1 };
static int
-stringzone(char *result, const struct zone *const zpfirst, const int zonecount)
+stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
{
register const struct zone * zp;
register struct rule * rp;
register struct rule * stdrp;
register struct rule * dstrp;
- register int i;
+ register ptrdiff_t i;
register const char * abbrvar;
register int compat = 0;
register int c;
}
static void
-outzone(const struct zone *zpfirst, int zonecount)
+outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
{
register const struct zone * zp;
register struct rule * rp;
- register int i, j;
+ register ptrdiff_t i, j;
register bool usestart, useuntil;
register zic_t starttime, untiltime;
register zic_t gmtoff;
register int compat;
register bool do_extend;
register char version;
+ ptrdiff_t lastatmax = -1;
max_abbr_len = 2 + max_format_len + max_abbrvar_len;
max_envvar_len = 2 * max_abbr_len + 5 * 9;
rp->r_temp = rpytime(rp, year);
}
for ( ; ; ) {
- register int k;
+ register ptrdiff_t k;
register zic_t jtime, ktime;
register zic_t offset;
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);
}
}
starttime = tadd(starttime, -gmtoff);
}
}
+ if (0 <= lastatmax)
+ attypes[lastatmax].dontmerge = true;
if (do_extend) {
/*
** If we're extending the explicitly listed observations
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);
}
attypes = growalloc(attypes, sizeof *attypes, timecnt, &timecnt_alloc);
attypes[timecnt].at = starttime;
+ attypes[timecnt].dontmerge = false;
attypes[timecnt].type = type;
++timecnt;
}
}
}
+static char *
+shellquote(char *b, char const *s)
+{
+ *b++ = '\'';
+ while (*s) {
+ if (*s == '\'')
+ *b++ = '\'', *b++ = '\\', *b++ = '\'';
+ *b++ = *s++;
+ }
+ *b++ = '\'';
+ return b;
+}
+
static bool
-yearistype(int year, const char *type)
+yearistype(zic_t year, const char *type)
{
- static char * buf;
- int result;
+ char *buf;
+ char *b;
+ int result;
if (type == NULL || *type == '\0')
return true;
- buf = erealloc(buf, 132 + strlen(yitcommand) + strlen(type));
- sprintf(buf, "%s %d %s", yitcommand, year, type);
+ buf = emalloc(1 + 4 * strlen(yitcommand) + 2
+ + INT_STRLEN_MAXIMUM(zic_t) + 2 + 4 * strlen(type) + 2);
+ b = shellquote(buf, yitcommand);
+ *b++ = ' ';
+ b += sprintf(b, "%"PRIdZIC, year);
+ *b++ = ' ';
+ b = shellquote(b, type);
+ *b = '\0';
result = system(buf);
- if (WIFEXITED(result)) switch (WEXITSTATUS(result)) {
- case 0:
- return true;
- case 1:
- return false;
+ if (WIFEXITED(result)) {
+ int status = WEXITSTATUS(result);
+ if (status <= 1) {
+ free(buf);
+ return status == 0;
+ }
}
error(_("Wild result from command execution"));
fprintf(stderr, _("%s: command was '%s', result was %d\n"),
progname, buf, result);
- for ( ; ; )
- exit(EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
/* Is A a space character in the C locale? */
if (*dp != '\0')
++dp;
else {
- error(_(
- "Odd number of quotation marks"
- ));
- exit(1);
+ error(_("Odd number of quotation marks"));
+ exit(EXIT_FAILURE);
}
} while (*cp && *cp != '#' && !is_space(*cp));
if (is_space(*cp))
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)
{
register char * name;
register 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;
}
CV +1455-02331 Atlantic/Cape_Verde
CW,AW,BQ,SX +1211-06900 America/Curacao
CX -1025+10543 Indian/Christmas
-CY +3510+03322 Asia/Nicosia
+CY +3510+03322 Asia/Nicosia Cyprus (most areas)
+CY +3507+03357 Asia/Famagusta Northern Cyprus
CZ,SK +5005+01426 Europe/Prague
DE +5230+01322 Europe/Berlin Germany (most areas)
DK +5540+01235 Europe/Copenhagen
MD +4700+02850 Europe/Chisinau
MH +0709+17112 Pacific/Majuro Marshall Islands (most areas)
MH +0905+16720 Pacific/Kwajalein Kwajalein
-MM +1647+09610 Asia/Rangoon
+MM +1647+09610 Asia/Yangon
MN +4755+10653 Asia/Ulaanbaatar Mongolia (most areas)
MN +4801+09139 Asia/Hovd Bayan-Ölgii, Govi-Altai, Hovd, Uvs, Zavkhan
MN +4804+11430 Asia/Choibalsan Dornod, Sükhbaatar