diff options
author | Stuart Bishop <stuart.bishop@canonical.com> | 2016-12-06 13:43:25 +0700 |
---|---|---|
committer | Stuart Bishop <stuart.bishop@canonical.com> | 2016-12-06 13:43:25 +0700 |
commit | 1ce6a27c1ee27fc358ed5cc34b88ae36435cc9be (patch) | |
tree | 278cbf9efea34f68cff139d0f3c361b5cc19df7c /tz | |
parent | aea262738d341cff78131934155ff9c1f84a5ac7 (diff) | |
parent | 2ef682280dd0ca515f4070aa386e00f5b4117829 (diff) | |
download | pytz-git-1ce6a27c1ee27fc358ed5cc34b88ae36435cc9be.tar.gz |
IANA 2016j
Diffstat (limited to 'tz')
-rw-r--r-- | tz/CONTRIBUTING | 6 | ||||
-rw-r--r-- | tz/Makefile | 103 | ||||
-rw-r--r-- | tz/NEWS | 160 | ||||
-rw-r--r-- | tz/README | 25 | ||||
-rw-r--r-- | tz/Theory | 97 | ||||
-rw-r--r-- | tz/africa | 2 | ||||
-rw-r--r-- | tz/antarctica | 7 | ||||
-rw-r--r-- | tz/asia | 192 | ||||
-rw-r--r-- | tz/australasia | 26 | ||||
-rw-r--r-- | tz/europe | 213 | ||||
-rw-r--r-- | tz/iso3166.tab | 2 | ||||
-rw-r--r-- | tz/localtime.c | 28 | ||||
-rw-r--r-- | tz/northamerica | 28 | ||||
-rw-r--r-- | tz/private.h | 52 | ||||
-rw-r--r-- | tz/strftime.c | 24 | ||||
-rw-r--r-- | tz/tz-art.htm | 8 | ||||
-rw-r--r-- | tz/tz-link.htm | 169 | ||||
-rw-r--r-- | tz/zdump.c | 4 | ||||
-rw-r--r-- | tz/zic.c | 335 | ||||
-rw-r--r-- | tz/zone.tab | 13 | ||||
-rw-r--r-- | tz/zone1970.tab | 15 |
21 files changed, 1026 insertions, 483 deletions
diff --git a/tz/CONTRIBUTING b/tz/CONTRIBUTING index e40102e..22addd2 100644 --- a/tz/CONTRIBUTING +++ b/tz/CONTRIBUTING @@ -18,10 +18,10 @@ data should contain commentary citing reliable sources as justification. Please submit changes against either the latest release in -<ftp://ftp.iana.org/tz/> or the master branch of the experimental -Git repository. If you use Git the following workflow may be helpful: +<ftp://ftp.iana.org/tz/> or the master branch of the development +repository. If you use Git the following workflow may be helpful: - * Copy the experimental repository. + * Copy the development repository. git clone https://github.com/eggert/tz.git cd tz diff --git a/tz/Makefile b/tz/Makefile index 79b4cdb..1b714a8 100644 --- a/tz/Makefile +++ b/tz/Makefile @@ -101,7 +101,6 @@ PACKRATDATA= 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. @@ -109,9 +108,10 @@ LDLIBS= # -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 @@ -129,6 +129,10 @@ LDLIBS= # -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 @@ -356,14 +360,14 @@ HEADERS= tzfile.h private.h NONLIBSRCS= zic.c zdump.c NEWUCBSRCS= date.c strftime.c SOURCES= $(HEADERS) $(LIBSRCS) $(NONLIBSRCS) $(NEWUCBSRCS) \ - tzselect.ksh version workman.sh + tzselect.ksh workman.sh MANS= newctime.3 newstrftime.3 newtzset.3 time2posix.3 \ tzfile.5 tzselect.8 zic.8 zdump.8 MANTXTS= newctime.3.txt newstrftime.3.txt newtzset.3.txt \ 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 \ @@ -434,16 +438,20 @@ INSTALL: ALL install date.1 cp -f date.1 $(DESTDIR)$(MANDIR)/man1/. version: $(VERSION_DEPS) - { V=$$(git describe --match '[0-9][0-9][0-9][0-9][a-z]*' \ - --abbrev=7 --dirty) || \ + { (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" >$@ + printf '%s\n' "$$V" >$@.out + mv $@.out $@ version.h: version - (echo 'static char const PKGVERSION[]="($(PACKAGE)) ";' && \ - printf 'static char const TZVERSION[]="%s";\n' \ - "$$(cat version)" && \ - echo 'static char const REPORT_BUGS_TO[]="$(BUGEMAIL)";') >$@ + 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) @@ -456,7 +464,8 @@ yearistype: yearistype.sh 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. @@ -514,12 +523,14 @@ $(TZS_NEW): $(TDATA) zdump zic $(zic) -d tzs.dir $(TDATA) $(AWK) '/^Link/{print $$1 "\t" $$2 "\t" $$3}' \ $(TDATA) | LC_ALL=C sort >$@.out - zones=$$($(AWK) -v wd="$$(pwd)" \ + wd=`pwd` && \ + zones=`$(AWK) -v wd="$$wd" \ '/^Zone/{print wd "/tzs.dir/" $$2}' $(TDATA) \ - | LC_ALL=C sort) && \ + | LC_ALL=C sort` && \ ./zdump -i -c $(TZS_YEAR) $$zones >>$@.out - sed 's,^TZ=".*tzs\.dir/,TZ=",' $@.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 @@ -531,22 +542,24 @@ force_tzs: $(TZS_NEW) cp $(TZS_NEW) $(TZS) libtz.a: $(LIBOBJS) - $(AR) ru $@ $(LIBOBJS) + rm -f $@ + $(AR) -rc $@ $(LIBOBJS) $(RANLIB) $@ date: $(DATEOBJS) $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(DATEOBJS) $(LDLIBS) tzselect: tzselect.ksh version - sed \ + 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='"$$(cat version)"'|' \ - <$@.ksh >$@ - 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_tzs check_web @@ -554,14 +567,16 @@ check: check_character_set check_white_space check_links check_sorted \ 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]; } @@ -619,7 +634,8 @@ zdump.8.txt: zdump.8 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. @@ -630,7 +646,8 @@ $(MANTXTS): workman.sh # 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 \ @@ -647,8 +664,8 @@ set-timestamps.out: $(ENCHILADA) touch -cmr `ls -t $$file workman.sh | sed 1q` $$file.txt || \ exit; \ done - touch -cmr $$(ls -t $(TZS_DEPS) | sed 1q) $(TZS) - touch -cmr $$(ls -t $(VERSION_DEPS) | sed 1q) version + touch -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. @@ -672,11 +689,12 @@ check_time_t_alternatives: else \ quiet_option=''; \ fi && \ + wd=`pwd` && \ zones=`$(AWK) '/^[^#]/ { print $$3 }' <zone1970.tab` && \ for type in $(TIME_T_ALTERNATIVES); do \ mkdir -p time_t.dir/$$type && \ $(MAKE) clean_misc && \ - $(MAKE) TOPDIR=$$(pwd)/time_t.dir/$$type \ + $(MAKE) TOPDIR="$$wd/time_t.dir/$$type" \ CFLAGS='$(CFLAGS) -Dtime_tz='"'$$type'" \ REDO='$(REDO)' \ install && \ @@ -700,33 +718,38 @@ check_time_t_alternatives: done rm -fr time_t.dir -tarballs signatures: version - $(MAKE) VERSION="$$(cat version)" $@_version +tarballs traditional_tarballs signatures traditional_signatures: version + VERSION=`cat version` && \ + $(MAKE) VERSION="$$VERSION" $@_version -tarballs_version: tzcode$(VERSION).tar.gz tzdata$(VERSION).tar.gz \ - tzdb-$(VERSION).tar.lz +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) > $@ + 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) + touch -cmr `ls -t tzdb-$(VERSION)/* | sed 1q` tzdb-$(VERSION) LC_ALL=C && export LC_ALL && \ - tar $(TARFLAGS) -cf - tzdb-$(VERSION) | lzip -9 > $@ - -signatures_version: tzcode$(VERSION).tar.gz.asc tzdata$(VERSION).tar.gz.asc \ - tzdb-$(VERSION).tar.lz.asc + tar $(TARFLAGS) -cf - tzdb-$(VERSION) | lzip -9 >$@.out + mv $@.out $@ tzcode$(VERSION).tar.gz.asc: tzcode$(VERSION).tar.gz gpg --armor --detach-sign $? @@ -1,5 +1,163 @@ News for the tz database +Release 2016j - 2016-11-22 23:17:13 -0800 + + Briefly: Saratov, Russia moves from +03 to +04 on 2016-12-04. + + Changes to future time stamps + + Saratov, Russia switches from +03 to +04 on 2016-12-04 at 02:00. + This hives off a new zone Europe/Saratov from Europe/Volgograd. + (Thanks to Yuri Konotopov and Stepan Golosunov.) + + Changes to past time stamps + + The new zone Asia/Atyrau for Atyraū Region, Kazakhstan, is like + Asia/Aqtau except it switched from +04/+05 to +05/+06 in spring + 1999, not fall 1994. (Thanks to Stepan Golosunov.) + + Changes to past time zone abbreviations + + Asia/Gaza and Asia/Hebron now use "EEST", not "EET", to denote + summer time before 1948. The old use of "EET" was a typo. + + Changes to code + + zic no longer mishandles file systems that lack hard links, fixing + bugs introduced in 2016g. (Problems reported by Tom Lane.) + Also, when the destination already contains symbolic links, zic + should now work better on systems where the 'link' system call + does not follow symbolic links. + + Changes to documentation and commentary + + tz-link.htm now documents the relationship between release version + numbers and development-repository commit tags. (Suggested by + Paul Koning.) + + The 'Theory' file now documents UT. + + iso3166.tab now accents "Curaçao", and commentary now mentions + the names "Cabo Verde" and "Czechia". (Thanks to Jiří Boháč.) + + +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 @@ -95,7 +253,7 @@ Release 2016g - 2016-09-13 08:56:38 -0700 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, + Tagged releases use 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'. @@ -10,24 +10,9 @@ locations around the globe. It is updated periodically to reflect changes made by political bodies to time zone boundaries, UTC offsets, and daylight-saving rules. -Here is a recipe for acquiring, building, installing, and testing the -tz distribution on a GNU/Linux or similar host. - -To acquire the distribution, run the following shell commands: - - mkdir tz - cd tz - wget --retr-symlinks 'ftp://ftp.iana.org/tz/tz*-latest.tar.gz' - gzip -dc tzcode-latest.tar.gz | tar -xf - - gzip -dc tzdata-latest.tar.gz | tar -xf - - -Alternatively, the following shell commands acquire the same -distribution, with extra data useful for regression testing: - - wget --retr-symlinks 'ftp://ftp.iana.org/tz/tzdb-latest.tar.lz' - lzip -dc tzdb-latest.tar.lz | tar -xf - - -Be sure to read the comments in "Makefile" and make any changes needed +See <https://www.iana.org/time-zones/repository/tz-link.html> or the +file tz-link.htm for how to acquire the code and data. Once acquired, +read the comments in the file '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, substituting your desired installation directory for "$HOME/tzdir": @@ -60,10 +45,6 @@ Thanks in particular to Arthur David Olson, the project's founder and first maintainer, to whom the time zone community owes the greatest debt of all. None of them are responsible for remaining errors. -Look in <ftp://ftp.iana.org/tz/releases/> for updated versions of these files. - -Please send comments or information to tz@iana.org. - ----- This file is in the public domain, so clarified as of 2009-05-17 by @@ -8,6 +8,7 @@ Theory and pragmatics of the tz code and data Time zone abbreviations Accuracy of the tz database Time and date functions + Interface stability Calendrical issues Time and time zones on Mars @@ -342,12 +343,24 @@ Errors in the tz database arise from many sources: non-hour-based system at night. * Early clocks were less reliable, and data entries do not represent - this unreliability. - - * As for leap seconds, civil time was not based on atomic time before - 1972, and we don't know the history of earth's rotation accurately - enough to map SI seconds to historical solar time to more than - about one-hour accuracy. See: Morrison LV, Stephenson FR. + clock error. + + * The tz database assumes Universal Time (UT) as an origin, even + though UT is not standardized for older time stamps. In the tz + database commentary, UT denotes a family of time standards that + includes Coordinated Universal Time (UTC) along with other variants + such as UT1 and GMT, with days starting at midnight. Although UT + equals UTC for modern time stamps, UTC was not defined until 1960, + so commentary uses the more-general abbreviation UT for time stamps + that might predate 1960. Since UT, UT1, etc. disagree slightly, + and since pre-1972 UTC seconds varied in length, interpretation of + older time stamps can be problematic when subsecond accuracy is + needed. + + * Civil time was not based on atomic time before 1972, and we don't + know the history of earth's rotation accurately enough to map SI + seconds to historical solar time to more than about one-hour + accuracy. See: Morrison LV, Stephenson FR. Historical values of the Earth's clock error Delta T and the calculation of eclipses. J Hist Astron. 2004;35:327-36 <http://adsabs.harvard.edu/full/2004JHA....35..327M>; @@ -445,6 +458,10 @@ POSIX has the following properties and limitations. 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 - @@ -454,6 +471,11 @@ POSIX has the following properties and limitations. 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 @@ -494,20 +516,23 @@ These are the extensions that have been made to the POSIX functions: "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 @@ -526,14 +551,15 @@ These are the extensions that have been made to the POSIX functions: 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 @@ -551,6 +577,8 @@ Points of interest to folks with other systems: * 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 @@ -568,6 +596,39 @@ more powerful time conversion functions can be standardized, so much the 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. + + * The version number of the code and data, as the first line of + the text file 'version' in each release. + +Interface changes in a release attempt to preserve compatibility with +recent releases. 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. The tz-link.htm file describes how +releases are tagged and distributed. + +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, @@ -119,7 +119,7 @@ Zone Africa/Algiers 0:12:12 - LMT 1891 Mar 15 0:01 # Cameroon # See Africa/Lagos. -# Cape Verde +# Cape Verde / Cabo Verde # # Shanks gives 1907 for the transition to CVT. # Perhaps the 1911-05-26 Portuguese decree diff --git a/tz/antarctica b/tz/antarctica index 0995835..6da1aef 100644 --- a/tz/antarctica +++ b/tz/antarctica @@ -64,13 +64,18 @@ # 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 - +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 + 8:00 - +08 2016 Oct 22 + 11:00 - +11 Zone Antarctica/Davis 0 - -00 1957 Jan 13 7:00 - +07 1964 Nov 0 - -00 1969 Feb @@ -771,9 +771,19 @@ Zone Asia/Macau 7:34:20 - LMT 1912 Jan 1 ############################################################################### # 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 - @@ -788,7 +798,10 @@ Rule Cyprus 1981 1998 - Mar lastSun 0:00 1:00 S Zone Asia/Nicosia 2:13:28 - LMT 1921 Nov 14 2:00 Cyprus EE%sT 1998 Sep 2:00 EUAsia EE%sT -# IATA SSIM (1998-09) has Cyprus using EU rules for the first time. +Zone Asia/Famagusta 2:15:48 - LMT 1921 Nov 14 + 2:00 Cyprus EE%sT 1998 Sep + 2:00 EUAsia EE%sT 2016 Sep 8 + 3:00 - +03 # Classically, Cyprus belongs to Asia; e.g. see Herodotus, Histories, I.72. # However, for various reasons many users expect to find it under Europe. @@ -1570,12 +1583,12 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # was "blended" with the Central zone. Therefore, Kazakhstan now has # two time zones, and difference between them is one hour. The zone # closer to UTC is the former Western zone (probably still called the -# same), encompassing four provinces in the west: Aqtobe, Atyrau, -# Mangghystau, and West Kazakhstan. The other zone encompasses +# same), encompassing four provinces in the west: Aqtöbe, Atyraū, +# Mangghystaū, and West Kazakhstan. The other zone encompasses # everything else.... I guess that would make Kazakhstan time zones # de jure UTC+5 and UTC+6 respectively. -# From Stepan Golosunov (2016-03-27) ([*] means see later comments below): +# From Stepan Golosunov (2016-03-27): # Review of the linked documents from http://adilet.zan.kz/ # produced the following data for post-1991 Kazakhstan: # @@ -1621,7 +1634,7 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # # This implies that on 1991-03-31 Asia/Oral remained on +04/+05 while # the rest of Kazakhstan switched from +06/+07 to +05/06 or from +05/06 -# to +04/+05. It's unclear how Kzyl-Orda oblast moved into the fifth +# to +04/+05. It's unclear how Qyzylorda oblast moved into the fifth # time belt. (By switching from +04/+05 to +05/+06 on 1991-09-29?) ... # # 1. Act of the Cabinet of Ministers of the Republic of Kazakhstan @@ -1634,25 +1647,25 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # on the whole territory of Kazakhstan 1 hour forward on 1992-01-19 at # 2:00, specified DST rules. It acknowledged that Kazakhstan was # located in the fourth and the fifth time belts and specified the -# border between them to be located east of Kustanay and Aktyubinsk -# oblasts (notably including Turgai and Kzyl-Orda oblasts into the fifth +# border between them to be located east of Qostanay and Aktyubinsk +# oblasts (notably including Turgai and Qyzylorda oblasts into the fifth # time belt). # # This means switch on 1992-01-19 at 2:00 from +04/+05 to +05/+06 for -# Asia/Aqtau, Asia/Aqtobe, Asia/Oral, Atyrau and Kustanay oblasts; from -# +05/+06 to +06/+07 for Asia/Almaty and Asia/Qyzylorda (and Arkalyk) [*].... +# Asia/Aqtau, Asia/Aqtobe, Asia/Oral, Atyraū and Qostanay oblasts; from +# +05/+06 to +06/+07 for Asia/Almaty and Asia/Qyzylorda (and Arkalyk).... # # 2. Act of the Cabinet of Ministers of the Republic of Kazakhstan # from 1992-03-27 No. 284 # http://adilet.zan.kz/rus/docs/P920000284_ -# cancels extra hour ("decree time") for Uralsk and Kzyl-Orda oblasts +# cancels extra hour ("decree time") for Uralsk and Qyzylorda oblasts # since the last Sunday of March 1992, while keeping them in the fourth # and the fifth time belts respectively. # # 3. Order of the Prime Minister of the Republic of Kazakhstan # from 1994-09-23 No. 384 # http://adilet.zan.kz/rus/docs/R940000384_ -# cancels the extra hour ("decree time") on the territory of Mangystau +# cancels the extra hour ("decree time") on the territory of Mangghystaū # oblast since the last Sunday of September 1994 (saying that time on # the territory would correspond to the third time belt as a # result).... @@ -1666,14 +1679,11 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # 5. Act of the Government of the Republic of Kazakhstan # from 1999-03-26 No. 305 # http://adilet.zan.kz/rus/docs/P990000305_ -# cancels the extra hour ("decree time") for Atyrau oblast since the +# cancels the extra hour ("decree time") for Atyraū oblast since the # last Sunday of March 1999 while retaining the oblast in the fourth # time belt. # -# This means change from +05/+06 to +04/+05. -# -# There is no zone for Atyrau currently (listed under Asia/Aqtau in -# zone1970.tab).[*] +# This means change from +05/+06 to +04/+05.... # # 6. Act of the Government of the Republic of Kazakhstan # from 2000-11-23 No. 1749 @@ -1683,10 +1693,10 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # The only changes I noticed are in definition of the border between the # fourth and the fifth time belts. They account for changes in spelling # and administrative division (splitting of Turgai oblast in 1997 -# probably changed time in territories incorporated into Kostanay oblast -# (including Arkalyk) from +06/+07 to +05/+06) and move Kyzylorda oblast +# probably changed time in territories incorporated into Qostanay oblast +# (including Arkalyk) from +06/+07 to +05/+06) and move Qyzylorda oblast # from being in the fifth time belt and not using decree time into the -# fourth time belt (no change in practice).[*] +# fourth time belt (no change in practice). # # 7. Act of the Government of the Republic of Kazakhstan # from 2003-12-29 No. 1342 @@ -1696,7 +1706,7 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # 8. Act of the Government of the Republic of Kazakhstan # from 2004-07-20 No. 775 # http://adilet.zan.kz/rus/archive/docs/P040000775_/20.07.2004 -# modified the 2000-11-23 act to move Kostanay and Kyzylorda oblasts into +# modified the 2000-11-23 act to move Qostanay and Qyzylorda oblasts into # the fifth time belt and add Aktobe oblast to the list of regions not # using extra hour ("decree time"), leaving Kazakhstan with only 2 time # zones (+04/+05 and +06/+07). The changes were to be implemented @@ -1708,14 +1718,14 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # http://adilet.zan.kz/rus/docs/P040001059_ # modified the 2000-11-23 act to remove exceptions from the "decree time" # (leaving Kazakhstan in +05/+06 and +06/+07 zones), amended the -# 2004-07-20 act to implement changes for Atyrau, West Kazakhstan, -# Kostanay, Kyzylorda and Mangystau oblasts by not moving clocks -# during the 2014 transition to "winter" time. +# 2004-07-20 act to implement changes for Atyraū, West Kazakhstan, +# Qostanay, Qyzylorda and Mangghystaū oblasts by not moving clocks +# during the 2004 transition to "winter" time. # -# This means transition from +04/+05 to +05/+06 for Atyrau oblast (no +# This means transition from +04/+05 to +05/+06 for Atyraū oblast (no # zone currently), Asia/Oral, Asia/Aqtau and transition from +05/+06 to -# +06/+07 for Kostanay oblast (Kostanay and Arkalyk, no zones currently) -# and Asia/Qyzylorda on 2004-10-31 at 3:00....[*] +# +06/+07 for Qostanay oblast (Qostanay and Arkalyk, no zones currently) +# and Asia/Qyzylorda on 2004-10-31 at 3:00.... # # 10. Act of the Government of the Republic of Kazakhstan # from 2005-03-15 No. 231 @@ -1731,14 +1741,9 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # Kazakh 1992-01-13 act appears to provide the same rules and 1992-03-27 # act was to be enacted on the last Sunday of March 1992. -# From Paul Eggert (2016-04-15): -# The tables below should reflect Stepan Golosunov's remarks above, -# except for the items marked "[*]" which I haven't gotten to yet. -# It looks like we will need new zones Asia/Atyrau and Asia/Qostanay -# to handle changes from 1992 through 2004 that we did not previously -# know about. +# From Paul Eggert (2016-11-07): +# The tables below reflect Golosunov's remarks, with exceptions as noted. -# # Zone NAME GMTOFF RULES FORMAT [UNTIL] # # Almaty (formerly Alma-Ata), representing most locations in Kazakhstan @@ -1751,6 +1756,8 @@ Zone Asia/Almaty 5:07:48 - LMT 1924 May 2 # or Alma-Ata 6:00 RussiaAsia +06/+07 2004 Oct 31 2:00s 6:00 - +06 # Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-KZY) +# This currently includes Qostanay (aka Kostanay, Kustanay) (KZ-KUS); +# see comments below. Zone Asia/Qyzylorda 4:21:52 - LMT 1924 May 2 4:00 - +04 1930 Jun 21 5:00 - +05 1981 Apr 1 @@ -1762,7 +1769,21 @@ Zone Asia/Qyzylorda 4:21:52 - LMT 1924 May 2 6:00 RussiaAsia +06/+07 1992 Mar 29 2:00s 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s 6:00 - +06 -# Aqtobe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT) +# The following zone is like Asia/Qyzylorda except for being one +# hour earlier from 1991-09-29 to 1992-03-29. The 1991/2 rules for +# Qostenay are unclear partly because of the 1997 Turgai +# reorganization, so this zone is commented out for now. +#Zone Asia/Qostanay 4:14:20 - LMT 1924 May 2 +# 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 1991 Mar 31 2:00s +# 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s +# 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s +# 6:00 - +06 +# +# Aqtöbe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT) Zone Asia/Aqtobe 3:48:40 - LMT 1924 May 2 4:00 - +04 1930 Jun 21 5:00 - +05 1981 Apr 1 @@ -1772,14 +1793,11 @@ Zone Asia/Aqtobe 3:48:40 - LMT 1924 May 2 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s 5:00 - +05 -# Qostanay (KZ-KUS) - -# Mangghystau (KZ-MAN) +# Mangghystaū (KZ-MAN) # Aqtau was not founded until 1963, but it represents an inhabited region, # so include time stamps before 1963. Zone Asia/Aqtau 3:21:04 - LMT 1924 May 2 4:00 - +04 1930 Jun 21 - 5:00 - +05 1963 5:00 - +05 1981 Oct 1 6:00 - +06 1982 Apr 1 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s @@ -1787,7 +1805,17 @@ Zone Asia/Aqtau 3:21:04 - LMT 1924 May 2 5:00 RussiaAsia +05/+06 1994 Sep 25 2:00s 4:00 RussiaAsia +04/+05 2004 Oct 31 2:00s 5:00 - +05 - +# Atyraū (KZ-ATY) is like Mangghystaū except it switched from +# +04/+05 to +05/+06 in spring 1999, not fall 1994. +Zone Asia/Atyrau 3:27:44 - LMT 1924 May 2 + 4:00 - +04 1930 Jun 21 + 5:00 - +05 1981 Oct 1 + 6:00 - +06 1982 Apr 1 + 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s + 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s + 5:00 RussiaAsia +05/+06 1999 Mar 28 2:00s + 4:00 RussiaAsia +04/+05 2004 Oct 31 2:00s + 5:00 - +05 # West Kazakhstan (KZ-ZAP) # From Paul Eggert (2016-03-18): # The 1989 transition is from USSR act No. 227 (1989-03-14). @@ -2544,11 +2572,6 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # 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 @@ -2558,7 +2581,21 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # # 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 @@ -2587,13 +2624,14 @@ Rule Palestine 2011 only - Sep 30 0:00 0 - 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 - 2:00 Zion EET 1948 May 15 + 2:00 Zion EET/EEST 1948 May 15 2:00 EgyptAsia EE%sT 1967 Jun 5 2:00 Zion I%sT 1996 2:00 Jordan EE%sT 1999 @@ -2606,7 +2644,7 @@ Zone Asia/Gaza 2:17:52 - LMT 1900 Oct 2:00 Palestine EE%sT Zone Asia/Hebron 2:20:23 - LMT 1900 Oct - 2:00 Zion EET 1948 May 15 + 2:00 Zion EET/EEST 1948 May 15 2:00 EgyptAsia EE%sT 1967 Jun 5 2:00 Zion I%sT 1996 2:00 Jordan EE%sT 1999 @@ -2739,45 +2777,31 @@ Zone Asia/Singapore 6:55:25 - LMT 1901 Jan 1 # 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 diff --git a/tz/australasia b/tz/australasia index f49df1d..0bca53e 100644 --- a/tz/australasia +++ b/tz/australasia @@ -350,7 +350,13 @@ Zone Indian/Cocos 6:27:40 - LMT 1900 # 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 @@ -696,11 +702,13 @@ Rule Tonga 1999 only - Oct 7 2:00s 1:00 S Rule Tonga 2000 only - Mar 19 2:00s 0 - Rule Tonga 2000 2001 - Nov Sun>=1 2:00 1:00 S Rule Tonga 2001 2002 - Jan lastSun 2:00 0 - +Rule Tonga 2016 max - Nov Sun>=1 2:00 1:00 S +Rule Tonga 2017 max - Jan Sun>=15 3:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Pacific/Tongatapu 12:19:20 - LMT 1901 - 12:20 - TOT 1941 # Tonga Time - 13:00 - TOT 1999 - 13:00 Tonga TO%sT + 12:20 - +1220 1941 + 13:00 - +13 1999 + 13:00 Tonga +13/+14 # Tuvalu # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -1706,9 +1714,17 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # of January the standard time in the Kingdom shall be moved backward by one # hour to 1:00am. -# From Pulu 'Anau (2002-11-05): +# From Pulu ʻAnau (2002-11-05): # The law was for 3 years, supposedly to get renewed. It wasn't. +# From Pulu ʻAnau (2016-10-27): +# http://mic.gov.to/news-today/press-releases/6375-daylight-saving-set-to-run-from-6-november-2016-to-15-january-2017 +# Cannot find anyone who knows the rules, has seen the duration or has seen +# the cabinet decision, but it appears we are following Fiji's rule set. +# +# From Tim Parenti (2016-10-26): +# Assume Tonga will observe DST from the first Sunday in November at 02:00 +# through the third Sunday in January at 03:00, like Fiji, for now. # Wake @@ -901,7 +901,7 @@ Zone Europe/Sofia 1:33:16 - LMT 1880 # Cyprus # Please see the 'asia' file for Asia/Nicosia. -# Czech Republic +# Czech Republic / Czechia # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Czech 1945 only - Apr 8 2:00s 1:00 S Rule Czech 1945 only - Nov 18 2:00s 0 - @@ -1500,73 +1500,84 @@ Zone Atlantic/Reykjavik -1:28 - LMT 1908 # 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 0:00s 1:00 S -Rule Italy 1916 only - Oct 1 0:00s 0 - -Rule Italy 1917 only - Apr 1 0:00s 1:00 S -Rule Italy 1917 only - Sep 30 0:00s 0 - -Rule Italy 1918 only - Mar 10 0:00s 1:00 S -Rule Italy 1918 1919 - Oct Sun>=1 0:00s 0 - -Rule Italy 1919 only - Mar 2 0:00s 1:00 S -Rule Italy 1920 only - Mar 21 0:00s 1:00 S -Rule Italy 1920 only - Sep 19 0:00s 0 - -Rule Italy 1940 only - Jun 15 0:00s 1:00 S -Rule Italy 1944 only - Sep 17 0:00s 0 - -Rule Italy 1945 only - Apr 2 2:00 1:00 S -Rule Italy 1945 only - Sep 15 0:00s 0 - -Rule Italy 1946 only - Mar 17 2:00s 1:00 S -Rule Italy 1946 only - Oct 6 2:00s 0 - -Rule Italy 1947 only - Mar 16 0:00s 1:00 S -Rule Italy 1947 only - Oct 5 0:00s 0 - -Rule Italy 1948 only - Feb 29 2:00s 1:00 S -Rule Italy 1948 only - Oct 3 2:00s 0 - -Rule Italy 1966 1968 - May Sun>=22 0:00 1:00 S -Rule Italy 1966 1969 - Sep Sun>=22 0:00 0 - -Rule Italy 1969 only - Jun 1 0:00 1:00 S -Rule Italy 1970 only - May 31 0:00 1:00 S -Rule Italy 1970 only - Sep lastSun 0:00 0 - -Rule Italy 1971 1972 - May Sun>=22 0:00 1:00 S -Rule Italy 1971 only - Sep lastSun 1:00 0 - -Rule Italy 1972 only - Oct 1 0:00 0 - -Rule Italy 1973 only - Jun 3 0:00 1:00 S -Rule Italy 1973 1974 - Sep lastSun 0:00 0 - -Rule Italy 1974 only - May 26 0:00 1:00 S -Rule Italy 1975 only - Jun 1 0:00s 1:00 S -Rule Italy 1975 1977 - Sep lastSun 0:00s 0 - -Rule Italy 1976 only - May 30 0:00s 1:00 S -Rule Italy 1977 1979 - May Sun>=22 0:00s 1:00 S -Rule Italy 1978 only - Oct 1 0:00s 0 - -Rule Italy 1979 only - Sep 30 0:00s 0 - +Rule Italy 1916 only - Jun 3 24:00 1:00 S +Rule Italy 1916 1917 - Sep 30 24:00 0 - +Rule Italy 1917 only - Mar 31 24:00 1:00 S +Rule Italy 1918 only - Mar 9 24:00 1:00 S +Rule Italy 1918 only - Oct 6 24:00 0 - +Rule Italy 1919 only - Mar 1 24:00 1:00 S +Rule Italy 1919 only - Oct 4 24:00 0 - +Rule Italy 1920 only - Mar 20 24:00 1:00 S +Rule Italy 1920 only - Sep 18 24:00 0 - +Rule Italy 1940 only - Jun 14 24:00 1:00 S +Rule Italy 1942 only - Nov 2 2:00s 0 - +Rule Italy 1943 only - Mar 29 2:00s 1:00 S +Rule Italy 1943 only - Oct 4 2:00s 0 - +Rule Italy 1944 only - Apr 2 2:00s 1:00 S +Rule Italy 1944 only - Sep 17 2:00s 0 - +Rule Italy 1945 only - Apr 2 2:00 1:00 S +Rule Italy 1945 only - Sep 15 1:00 0 - +Rule Italy 1946 only - Mar 17 2:00s 1:00 S +Rule Italy 1946 only - Oct 6 2:00s 0 - +Rule Italy 1947 only - Mar 16 0:00s 1:00 S +Rule Italy 1947 only - Oct 5 0:00s 0 - +Rule Italy 1948 only - Feb 29 2:00s 1:00 S +Rule Italy 1948 only - Oct 3 2:00s 0 - +Rule Italy 1966 1968 - May Sun>=22 0:00s 1:00 S +Rule Italy 1966 only - Sep 24 24:00 0 - +Rule Italy 1967 1969 - Sep Sun>=22 0:00s 0 - +Rule Italy 1969 only - Jun 1 0:00s 1:00 S +Rule Italy 1970 only - May 31 0:00s 1:00 S +Rule Italy 1970 only - Sep lastSun 0:00s 0 - +Rule Italy 1971 1972 - May Sun>=22 0:00s 1:00 S +Rule Italy 1971 only - Sep lastSun 0:00s 0 - +Rule Italy 1972 only - Oct 1 0:00s 0 - +Rule Italy 1973 only - Jun 3 0:00s 1:00 S +Rule Italy 1973 1974 - Sep lastSun 0:00s 0 - +Rule Italy 1974 only - May 26 0:00s 1:00 S +Rule Italy 1975 only - Jun 1 0:00s 1:00 S +Rule Italy 1975 1977 - Sep lastSun 0:00s 0 - +Rule Italy 1976 only - May 30 0:00s 1:00 S +Rule Italy 1977 1979 - May Sun>=22 0:00s 1:00 S +Rule Italy 1978 only - Oct 1 0:00s 0 - +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 @@ -1765,6 +1776,10 @@ Zone Europe/Luxembourg 0:24:36 - LMT 1904 Jun # See Europe/Belgrade. # Malta +# +# From Paul Eggert (2016-10-21): +# Assume 1900-1972 was like Rome, overriding Shanks. +# # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Malta 1973 only - Mar 31 0:00s 1:00 S Rule Malta 1973 only - Sep 29 0:00s 0 - @@ -1775,8 +1790,6 @@ Rule Malta 1975 1980 - Sep Sun>=15 2:00 0 - 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 @@ -1908,7 +1921,7 @@ Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15 # 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 @@ -2588,10 +2601,9 @@ Zone Europe/Astrakhan 3:12:12 - LMT 1924 May 3:00 - +03 2016 Mar 27 2:00s 4:00 - +04 -# From Paul Eggert (2016-03-18): +# From Paul Eggert (2016-11-11): # Europe/Volgograd covers: # 34 RU-VGG Volgograd Oblast -# 64 RU-SAR Saratov Oblast # The 1988 transition is from USSR act No. 5 (1988-01-04). Zone Europe/Volgograd 2:57:40 - LMT 1920 Jan 3 @@ -2604,6 +2616,27 @@ Zone Europe/Volgograd 2:57:40 - LMT 1920 Jan 3 4:00 - +04 2014 Oct 26 2:00s 3:00 - +03 +# From Paul Eggert (2016-11-11): +# Europe/Saratov covers: +# 64 RU-SAR Saratov Oblast + +# From Yuri Konotopov (2016-11-11): +# Dec 4, 2016 02:00 UTC+3.... Saratov Region's local time will be ... UTC+4. +# From Stepan Golosunov (2016-11-11): +# ... Byalokoz listed Saratov on 03:04:18. +# From Stepan Golosunov (2016-11-22): +# http://publication.pravo.gov.ru/Document/View/0001201611220031 + +Zone Europe/Saratov 3:04:18 - LMT 1919 Jul 1 0:00u + 3:00 - +03 1930 Jun 21 + 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 2016 Dec 4 2:00s + 4:00 - +04 + # From Paul Eggert (2016-03-18): # Europe/Kirov covers: # 43 RU-KIR Kirov Oblast @@ -3427,22 +3460,24 @@ Zone Europe/Zurich 0:34:08 - LMT 1853 Jul 16 # See above comment. # 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 @@ -3551,10 +3586,10 @@ Rule Turkey 1983 only - Jul 31 0:00 1:00 S Rule Turkey 1983 only - Oct 2 0:00 0 - Rule Turkey 1985 only - Apr 20 0:00 1:00 S Rule Turkey 1985 only - Sep 28 0:00 0 - -Rule Turkey 1986 1990 - Mar lastSun 2:00s 1:00 S -Rule Turkey 1986 1990 - Sep lastSun 2:00s 0 - -Rule Turkey 1991 2006 - Mar lastSun 1:00s 1:00 S -Rule Turkey 1991 1995 - Sep lastSun 1:00s 0 - +Rule Turkey 1986 1993 - Mar lastSun 1:00s 1:00 S +Rule Turkey 1986 1995 - Sep lastSun 1:00s 0 - +Rule Turkey 1994 only - Mar 20 1:00s 1:00 S +Rule Turkey 1995 2006 - Mar lastSun 1:00s 1:00 S Rule Turkey 1996 2006 - Oct lastSun 1:00s 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/Istanbul 1:55:52 - LMT 1880 diff --git a/tz/iso3166.tab b/tz/iso3166.tab index 7a8df2c..0c79cab 100644 --- a/tz/iso3166.tab +++ b/tz/iso3166.tab @@ -75,7 +75,7 @@ CO Colombia CR Costa Rica CU Cuba CV Cape Verde -CW Curacao +CW Curaçao CX Christmas Island CY Cyprus CZ Czech Republic diff --git a/tz/localtime.c b/tz/localtime.c index 6c00c45..385b6bb 100644 --- a/tz/localtime.c +++ b/tz/localtime.c @@ -2254,15 +2254,39 @@ posix2time(time_t t) #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; diff --git a/tz/northamerica b/tz/northamerica index 0bafb00..e1ed9e4 100644 --- a/tz/northamerica +++ b/tz/northamerica @@ -24,8 +24,32 @@ # was the result of his proposals at the Convention of Railroad Trunk Lines # in New York City (1869-10). His 1870 proposal was based on Washington, DC, # but in 1872-05 he moved the proposed origin to Greenwich. -# His proposal was adopted by the railroads on 1883-11-18 at 12:00, -# and the most of the country soon followed suit. + +# From Paul Eggert (2016-09-21): +# Dowd's proposal left many details unresolved, such as where to draw +# lines between time zones. The key individual who made time zones +# work in the US was William Frederick Allen - railway engineer, +# managing editor of the Travelers' Guide, and secretary of the +# General Time Convention, a railway standardization group. Allen +# spent months in dialogs with scientific and railway leaders, +# developed a workable plan to institute time zones, and presented it +# to the General Time Convention on 1883-04-11, saying that his plan +# meant "local time would be practically abolished" - a plus for +# railway scheduling. By the next convention on 1883-10-11 nearly all +# railroads had agreed and it took effect on 1883-11-18 at 12:00. +# That Sunday was called the "day of two noons", as the eastern parts +# of the new zones observed noon twice. Allen witnessed the +# transition in New York City, writing: +# +# I heard the bells of St. Paul's strike on the old time. Four +# minutes later, obedient to the electrical signal from the Naval +# Observatory ... the time-ball made its rapid descent, the chimes +# of old Trinity rang twelve measured strokes, and local time was +# abandoned, probably forever. +# +# Most of the US soon followed suit. See: +# Bartky IR. The adoption of standard time. Technol Cult 1989 Jan;30(1):25-56. +# http://dx.doi.org/10.2307/3105430 # From Paul Eggert (2005-04-16): # That 1883 transition occurred at 12:00 new time, not at 12:00 old time. diff --git a/tz/private.h b/tz/private.h index daad297..0bd1d00 100644 --- a/tz/private.h +++ b/tz/private.h @@ -78,9 +78,9 @@ /* 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 /* @@ -161,15 +161,15 @@ /* ** 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 @@ -209,14 +209,18 @@ typedef long int_fast64_t; # 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; @@ -316,6 +320,13 @@ typedef unsigned long uintmax_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. @@ -323,7 +334,7 @@ typedef unsigned long uintmax_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 @@ -508,9 +519,28 @@ time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE; #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 /* diff --git a/tz/strftime.c b/tz/strftime.c index 151b2e9..984ead5 100644 --- a/tz/strftime.c +++ b/tz/strftime.c @@ -496,15 +496,14 @@ label: */ 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 @@ -524,19 +523,21 @@ label: ** 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; @@ -547,6 +548,7 @@ label: (diff % MINSPERHOUR); pt = _conv(diff, "%04d", pt, ptlim); } +#endif continue; case '+': pt = _fmt(Locale->date_fmt, t, pt, ptlim, diff --git a/tz/tz-art.htm b/tz/tz-art.htm index 0a2b427..f310919 100644 --- a/tz/tz-art.htm +++ b/tz/tz-art.htm @@ -438,13 +438,19 @@ Supernaw.</td></tr> 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 "<a href='http://what-if.xkcd.com/26/'>Leap Seconds</a>" (2012-12-31). </li> <li> +Pig kills time in <a +href="http://www.gocomics.com/pearlsbeforeswine/2016/11/06"><em>Pearls +Before Swine</em> (2016-11-06)</a>. +</li> +<li> The syndicated comic strip <em>Dilbert</em> featured an <a href='http://dilbert.com/strip/1998-03-14'>example of time zone humor</a> on 1998-03-14. diff --git a/tz/tz-link.htm b/tz/tz-link.htm index 8964490..49fde11 100644 --- a/tz/tz-link.htm +++ b/tz/tz-link.htm @@ -10,7 +10,7 @@ content="Sources for time zone and daylight saving time data"> <meta name="DC.Creator" content="Eggert, Paul"> <meta name="DC.Contributor" content="Olson, Arthur David"> -<meta name="DC.Date" content="2016-09-09"> +<meta name="DC.Date" content="2016-11-09"> <meta name="DC.Description" content="Sources of information about time zones and daylight saving time"> <meta name="DC.Identifier" @@ -27,7 +27,7 @@ histories and planned futures are often recorded only fitfully. Here 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 @@ -120,7 +120,7 @@ gzip -dc tzdata-latest.tar.gz | tar -xf - <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' +<pre style="margin-left: 2em"><code>wget <a href="ftp://ftp.iana.org/tz/tzdb-latest.tar.lz">ftp://ftp.iana.org/tz/tzdb-latest.tar.lz</a> <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 @@ -136,31 +136,35 @@ 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). +Since version 2016h, each release has contained a text file named +"<samp>version</samp>" whose first (and currently only) line is the version. The releases can also be obtained from the <a href="http://www.iana.org/time-zones">Time Zone Database website</a> of the <a href="http://www.iana.org">Internet Assigned Numbers -Authority (IANA)</a>. -An <a href="https://github.com/eggert/tz">unofficial development -repository</a> of the code and data is available -in <a href="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. +Authority (IANA)</a>.</p> +<p>Alternatively, a development repository of code and data can be +retrieved from <a href="https://github.com">GitHub</a> via the shell +command:</p> +<pre style="margin-left: 2em"><code><a href="https://git-scm.com">git</a> clone <a href="https://github.com/eggert/tz">https://github.com/eggert/tz</a> +</code></pre> +<p> +Since version 2012e, each release has been tagged in development repositories. +Untagged commits are less well tested and probably contain +more errors.</p> <p> -After extracting a distribution's files, see its +After obtaining the code and data files, see the <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> @@ -194,7 +198,7 @@ For further information about updates, please see <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 @@ -212,7 +216,8 @@ href="https://blog.jonudell.net/2009/10/23/a-literary-appreciation-of-the-olsonz 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> @@ -242,16 +247,20 @@ calculates the current time difference between locations.</li> 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="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).</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) @@ -267,7 +276,7 @@ title="Extensible Markup Language">XML</abbr></a> format, and a variant uses <a href="http://www.json.org"><abbr 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> @@ -298,13 +307,13 @@ Database Parser</a> is a 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> @@ -340,7 +349,7 @@ available under the <a href="https://www.gnu.org/copyleft/lesser.html"><abbr>GNU</abbr> Lesser General Public License (<abbr title="Lesser General Public License">LGPL</abbr>)</a>.</li> -<li><abbr>ICU</abbr> (mentioned above) contains compilers and +<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 @@ -384,13 +393,13 @@ library that compiles <code><abbr>tz</abbr></code> source into a time 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="https://www.gnu.org/software/libc/"><abbr>GNU</abbr> C @@ -419,7 +428,7 @@ It is freely available under the <abbr>LGPL</abbr>.</li> <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> @@ -439,7 +448,7 @@ package contains <a href="https://www.haskell.org">Haskell</a> code that 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 @@ -462,11 +471,11 @@ clock (intclock)</a> is a clock that displays multiple time zones on 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, @@ -496,7 +505,7 @@ 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 @@ -513,7 +522,8 @@ guessed many <abbr>UT</abbr> offsets and transitions. The atlases cite no 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> @@ -525,7 +535,7 @@ 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 @@ -552,20 +562,74 @@ much is time wrong around the world?</a> maps the difference between 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 @@ -589,7 +653,7 @@ for land and territorial waters only). A captain can change ship's 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://physics.nist.gov/time">A Walk through Time</a> @@ -609,7 +673,7 @@ time zone boundary.</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 @@ -644,13 +708,17 @@ of Legal Time in Germany</a>.</dd> <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> @@ -662,7 +730,7 @@ 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> @@ -672,14 +740,14 @@ href="https://www.polyomino.org.uk/british-time/">History of 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 @@ -687,7 +755,7 @@ Science of Timekeeping</a> is a thorough introduction 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 @@ -752,9 +820,9 @@ might be redefined 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", @@ -777,9 +845,8 @@ interchange – Representation of dates and times</a>.</li> <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> @@ -826,7 +893,7 @@ any future changes to the rules. One should never set 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> @@ -45,7 +45,7 @@ # define HAVE_STDINT_H \ (199901 <= __STDC_VERSION__ \ || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \ - || __CYGWIN__) + || __CYGWIN__ || INTMAX_MAX) #endif #if HAVE_STDINT_H # include "stdint.h" @@ -1139,7 +1139,7 @@ istrftime(char *buf, size_t size, char const *time_fmt, } break; } - if (! (0 <= formatted_len && formatted_len < s)) + if (s <= formatted_len) return false; b += formatted_len, s -= formatted_len; f = p + 1; @@ -8,7 +8,9 @@ #include "locale.h" #include "tzfile.h" +#include <fcntl.h> #include <stdarg.h> +#include <stddef.h> #define ZIC_VERSION_PRE_2013 '2' #define ZIC_VERSION '3' @@ -16,6 +18,7 @@ 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 @@ -38,9 +41,18 @@ typedef int_fast64_t zic_t; #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 */ @@ -63,7 +75,7 @@ struct rule { 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 */ }; @@ -77,7 +89,7 @@ struct rule { struct zone { const char * z_filename; - int z_linenum; + lineno z_linenum; const char * z_name; zic_t z_gmtoff; @@ -88,7 +100,7 @@ struct zone { zic_t z_stdoff; struct rule * z_rules; - int z_nrules; + ptrdiff_t z_nrules; struct rule z_untilrule; zic_t z_untiltime; @@ -106,10 +118,14 @@ extern int optind; # define link(from, to) (errno = ENOTSUP, -1) #endif #if ! HAVE_SYMLINK -# define lstat(name, st) stat(name, st) +# define readlink(file, buf, size) (errno = ENOTSUP, -1) # define symlink(from, to) (errno = ENOTSUP, -1) # define S_ISLNK(m) 0 #endif +#ifndef AT_SYMLINK_FOLLOW +# define linkat(fromdir, from, todir, to, flag) \ + (itssymlink(from) ? (errno = ENOTSUP, -1) : link(from, to)) +#endif static void addtt(zic_t starttime, int type); static int addtype(zic_t, char const *, bool, bool, bool); @@ -127,20 +143,21 @@ static void inrule(char ** fields, int nfields); static bool inzcont(char ** fields, int nfields); static bool inzone(char ** fields, int nfields); static bool inzsub(char **, int, bool); -static int itsdir(const char * name); +static bool itsdir(char const *); +static bool itssymlink(char const *); static bool is_alpha(char a); static char lowerit(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 }; @@ -160,17 +177,17 @@ static int leapcnt; 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; /* @@ -255,23 +272,23 @@ 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; @@ -425,16 +442,16 @@ ecpyalloc (char const *str) } 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)); } } @@ -444,8 +461,7 @@ growalloc(void *ptr, size_t itemsize, int nitems, int *nitems_alloc) */ 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; @@ -454,7 +470,7 @@ eats(const char *const name, const int num, const char *const rname, } static void -eat(const char *const name, const int num) +eat(char const *name, lineno num) { eats(name, num, NULL, -1); } @@ -468,10 +484,10 @@ verror(const char *const string, va_list args) ** 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"); } @@ -554,9 +570,8 @@ static const char * yitcommand; 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)); @@ -574,12 +589,12 @@ main(int argc, char **argv) _("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, 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) @@ -655,8 +670,8 @@ _("%s: More than one -L option specified\n"), 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(); @@ -699,7 +714,7 @@ componentcheck(char const *name, char const *component, 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")); @@ -714,8 +729,9 @@ componentcheck(char const *name, char const *component, } 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) { @@ -764,10 +780,56 @@ namecheck(const char *name) 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 *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 (; to[i]; i++) + dotdots += to[i] == '/' && to[i - 1] != '/'; + taillen = strlen(f + 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; +} + +/* Hard link FROM to TO, following any symbolic links. + Return 0 if successful, an error number otherwise. */ +static int +hardlinkerr(char const *from, char const *to) +{ + int r = linkat(AT_FDCWD, from, AT_FDCWD, to, AT_SYMLINK_FOLLOW); + return r == 0 ? 0 : errno; +} + static void dolink(char const *fromfield, char const *tofield, bool staysymlink) { - register int fromisdir; bool todirs_made = false; int link_errno; @@ -775,15 +837,13 @@ dolink(char const *fromfield, char const *tofield, bool staysymlink) ** We get to be careful here since ** there's a fair chance of root running us. */ - fromisdir = itsdir(fromfield); - if (fromisdir) { - char const *e = strerror(fromisdir < 0 ? errno : EPERM); + if (itsdir(fromfield)) { fprintf(stderr, _("%s: link from %s/%s failed: %s\n"), - progname, directory, fromfield, e); + progname, directory, fromfield, strerror(EPERM)); exit(EXIT_FAILURE); } if (staysymlink) - staysymlink = itsdir(tofield) == 2; + staysymlink = itssymlink(tofield); if (remove(tofield) == 0) todirs_made = true; else if (errno != ENOENT) { @@ -792,38 +852,22 @@ dolink(char const *fromfield, char const *tofield, bool staysymlink) progname, directory, tofield, e); exit(EXIT_FAILURE); } - link_errno = (staysymlink ? ENOTSUP - : link(fromfield, tofield) == 0 ? 0 : errno); + link_errno = staysymlink ? ENOTSUP : hardlinkerr(fromfield, tofield); if (link_errno == ENOENT && !todirs_made) { mkdirs(tofield, true); todirs_made = true; - link_errno = link(fromfield, tofield) == 0 ? 0 : errno; + link_errno = hardlinkerr(fromfield, tofield); } if (link_errno != 0) { - const char *s = fromfield; - const char *t; - char *p; - size_t dotdots = 0; - char *symlinkcontents; - int symlink_errno; - - do - t = s; - while ((s = strchr(s, '/')) - && strncmp(fromfield, tofield, ++s - fromfield) == 0); - - for (s = tofield + (t - fromfield); *s; s++) - dotdots += *s == '/'; - symlinkcontents = emalloc(3 * dotdots + strlen(t) + 1); - for (p = symlinkcontents; dotdots-- != 0; p += 3) - memcpy(p, "../", 3); - strcpy(p, t); - symlink_errno = symlink(symlinkcontents, tofield) == 0 ? 0 : errno; + 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(symlinkcontents, tofield) == 0 ? 0 : errno; + symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno; } - free(symlinkcontents); + free(linkalloc); if (symlink_errno == 0) { if (link_errno != ENOTSUP) warning(_("symbolic link used because hard link failed: %s"), @@ -861,8 +905,8 @@ dolink(char const *fromfield, char const *tofield, bool staysymlink) #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 @@ -902,28 +946,35 @@ static const zic_t early_time = (WORK_AROUND_GNOME_BUG_730332 ? BIG_BANG : MINVAL(zic_t, TIME_T_BITS_IN_FILE)); -/* Return 1 if NAME is a directory, 2 if a symbolic link, 0 if - something else, -1 (setting errno) if trouble. */ -static int +/* Return true if NAME is a directory. */ +static bool itsdir(char const *name) { struct stat st; - int res = lstat(name, &st); - if (res == 0) { + int res = stat(name, &st); #ifdef S_ISDIR - return S_ISDIR(st.st_mode) ? 1 : S_ISLNK(st.st_mode) ? 2 : 0; -#else + if (res == 0) + return S_ISDIR(st.st_mode) != 0; +#endif + if (res == 0 || errno == EOVERFLOW) { 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; + dir = stat(nameslashdot, &st) == 0 || errno == EOVERFLOW; free(nameslashdot); return dir; -#endif } - return -1; + return false; +} + +/* Return true if NAME is a symbolic link. */ +static bool +itssymlink(char const *name) +{ + char c; + return 0 <= readlink(name, &c, 1); } /* @@ -946,8 +997,7 @@ associate(void) { 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); @@ -1025,7 +1075,7 @@ infile(const char *name) register const struct lookup * lp; register int nfields; register bool wantcont; - register int num; + register lineno num; char buf[BUFSIZ]; if (strcmp(name, "-") == 0) { @@ -1066,7 +1116,7 @@ infile(const char *name) 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; @@ -1178,7 +1228,7 @@ inrule(char **fields, int nfields) 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")); @@ -1199,8 +1249,8 @@ _("\"Zone %s\" line and -p option are mutually exclusive"), 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); @@ -1312,7 +1362,7 @@ inleap(char **fields, int nfields) { 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; @@ -1484,7 +1534,7 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp, 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; @@ -1503,7 +1553,7 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp, 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; @@ -1641,16 +1691,16 @@ static void 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; 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; @@ -1664,8 +1714,7 @@ writezone(const char *const name, const char *const string, char version) ** Optimize. */ { - int fromi; - int toi; + ptrdiff_t fromi, toi; toi = 0; fromi = 0; @@ -1687,9 +1736,16 @@ writezone(const char *const name, const char *const string, char version) } 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. */ @@ -1774,27 +1830,31 @@ writezone(const char *const name, const char *const string, char version) } } 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) @@ -1881,8 +1941,7 @@ writezone(const char *const name, const char *const string, char version) 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; @@ -2166,13 +2225,13 @@ rule_cmp(struct rule const *a, struct rule const *b) 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; @@ -2285,11 +2344,11 @@ stringzone(char *result, const struct zone *const zpfirst, const int zonecount) } 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; @@ -2308,7 +2367,7 @@ outzone(const struct zone *zpfirst, int zonecount) register int compat; register bool do_extend; register char version; - int lastatmax = -1; + ptrdiff_t lastatmax = -1; max_abbr_len = 2 + max_format_len + max_abbrvar_len; max_envvar_len = 2 * max_abbr_len + 5 * 9; @@ -2452,7 +2511,7 @@ outzone(const struct zone *zpfirst, int zonecount) rp->r_temp = rpytime(rp, year); } for ( ; ; ) { - register int k; + register ptrdiff_t k; register zic_t jtime, ktime; register zic_t offset; @@ -2721,28 +2780,48 @@ adjleap(void) } } +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? */ @@ -2870,10 +2949,8 @@ getfields(register char *cp) 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)) @@ -3038,7 +3115,8 @@ mp = _("time zone abbreviation differs from POSIX standard"); /* 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. */ + do it for ARGNAME too. Exit with failure if there is trouble. + Do not consider an existing non-directory to be trouble. */ static void mkdirs(char const *argname, bool ancestors) { @@ -3066,8 +3144,11 @@ mkdirs(char const *argname, bool ancestors) ** is checked anyway if the mkdir fails. */ if (mkdir(name, MKDIR_UMASK) != 0) { + /* For speed, skip itsdir if errno == EEXIST. Since + mkdirs is called only after open fails with ENOENT + on a subfile, EEXIST implies itsdir here. */ int err = errno; - if (err != EEXIST && itsdir(name) < 0) { + if (err != EEXIST && !itsdir(name)) { error(_("%s: Can't create directory %s: %s"), progname, name, strerror(err)); exit(EXIT_FAILURE); diff --git a/tz/zone.tab b/tz/zone.tab index cf774b5..f3ff0b6 100644 --- a/tz/zone.tab +++ b/tz/zone.tab @@ -152,7 +152,8 @@ CU +2308-08222 America/Havana CV +1455-02331 Atlantic/Cape_Verde CW +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 +5005+01426 Europe/Prague DE +5230+01322 Europe/Berlin Germany (most areas) DE +4742+00841 Europe/Busingen Busingen @@ -238,7 +239,8 @@ KY +1918-08123 America/Cayman KZ +4315+07657 Asia/Almaty Kazakhstan (most areas) KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda KZ +5017+05710 Asia/Aqtobe Aqtobe/Aktobe -KZ +4431+05016 Asia/Aqtau Atyrau/Atirau/Gur'yev, Mangghystau/Mankistau +KZ +4431+05016 Asia/Aqtau Mangghystau/Mankistau +KZ +4707+05156 Asia/Atyrau Atyrau/Atirau/Gur'yev KZ +5113+05121 Asia/Oral West Kazakhstan LA +1758+10236 Asia/Vientiane LB +3353+03530 Asia/Beirut @@ -329,14 +331,15 @@ RS +4450+02030 Europe/Belgrade RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad RU +554521+0373704 Europe/Moscow MSK+00 - Moscow area RU +4457+03406 Europe/Simferopol MSK+00 - Crimea -RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd, Saratov +RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd RU +5836+04939 Europe/Kirov MSK+00 - Kirov RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan -RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia +RU +5134+04602 Europe/Saratov MSK+01 - Saratov RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk +RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia RU +5651+06036 Asia/Yekaterinburg MSK+02 - Urals RU +5500+07324 Asia/Omsk MSK+03 - Omsk -RU +5502+08255 Asia/Novosibirsk MSK+03 - Novosibirsk +RU +5502+08255 Asia/Novosibirsk MSK+04 - Novosibirsk RU +5322+08345 Asia/Barnaul MSK+04 - Altai RU +5630+08458 Asia/Tomsk MSK+04 - Tomsk RU +5345+08707 Asia/Novokuznetsk MSK+04 - Kemerovo diff --git a/tz/zone1970.tab b/tz/zone1970.tab index b7372cf..dc50f6d 100644 --- a/tz/zone1970.tab +++ b/tz/zone1970.tab @@ -144,7 +144,8 @@ CU +2308-08222 America/Havana 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 @@ -209,8 +210,9 @@ KP +3901+12545 Asia/Pyongyang KR +3733+12658 Asia/Seoul KZ +4315+07657 Asia/Almaty Kazakhstan (most areas) KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda -KZ +5017+05710 Asia/Aqtobe Aqtobe/Aktobe -KZ +4431+05016 Asia/Aqtau Atyrau/Atirau/Gur'yev, Mangghystau/Mankistau +KZ +5017+05710 Asia/Aqtobe Aqtöbe/Aktobe +KZ +4431+05016 Asia/Aqtau Mangghystaū/Mankistau +KZ +4707+05156 Asia/Atyrau Atyraū/Atirau/Gur'yev KZ +5113+05121 Asia/Oral West Kazakhstan LB +3353+03530 Asia/Beirut LK +0656+07951 Asia/Colombo @@ -286,14 +288,15 @@ RS,BA,HR,ME,MK,SI +4450+02030 Europe/Belgrade RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad RU +554521+0373704 Europe/Moscow MSK+00 - Moscow area RU +4457+03406 Europe/Simferopol MSK+00 - Crimea -RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd, Saratov +RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd RU +5836+04939 Europe/Kirov MSK+00 - Kirov RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan -RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia +RU +5134+04602 Europe/Saratov MSK+01 - Saratov RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk +RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia RU +5651+06036 Asia/Yekaterinburg MSK+02 - Urals RU +5500+07324 Asia/Omsk MSK+03 - Omsk -RU +5502+08255 Asia/Novosibirsk MSK+03 - Novosibirsk +RU +5502+08255 Asia/Novosibirsk MSK+04 - Novosibirsk RU +5322+08345 Asia/Barnaul MSK+04 - Altai RU +5630+08458 Asia/Tomsk MSK+04 - Tomsk RU +5345+08707 Asia/Novokuznetsk MSK+04 - Kemerovo |