summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Bishop <stuart@stuartbishop.net>2022-08-12 09:36:24 +1000
committerStuart Bishop <stuart@stuartbishop.net>2022-08-12 09:36:24 +1000
commit301a880b1dd96605a98374576b0e210994a69f2d (patch)
treebf28f9116b188da1d70cb05b6e502ccdd39b9005
parent9e15fadcb930d6781591d14a0fb20e1135bde9c0 (diff)
downloadpytz-git-301a880b1dd96605a98374576b0e210994a69f2d.tar.gz
Squashed 'tz/' changes from 95ecc37d2..32a4af56f
b61a7acb4 Release 2022b 39dc54c76 Use more-official URL for Chile change cc9d7b92f Fix typo in previous commit. 711b46f8f Chile's DST is delayed by a week in September 2022 12be3e4ce Omit pacificnew from tailored vanguard tarballs 9b665ce9a Put 'leapseconds' etc. into tailored tarballs 35fa37fbb Finish duplicate-since-1970 moves 0b925f6d8 Move nine more zones to ‘backzone’ 0f9ac4ff2 Improve zishrink after PACKRATLIST 3be5b73fe Add PACKRATLIST build-time option 406d29f4a Remove hack to work around circa-2006 zic issue 4000ea353 Simplify subseconds for Asia/Jakarta 4b78b8bb3 Don’t generate subseconds in vanguard form ff6ead112 Add a couple of #STDOFF comments 6b32cae26 Simplify subsecond precision handling 26e522baa Check that ziguard substitutions revert de89db718 Omit tiny 1906 change in Vietnam 4d39a0ee9 Apply subsecond precision to Amsterdam Mean Time 4f8ac112b Vanguard form now uses subsecond precision 4c7a2921c Omit tiny 1880 change in Dublin 4feb18cd4 * theory.html: Source data can do subseconds. 9cd5f5339 * europe (Atlantic/Madeira): Fix typo in vanguard section. bffc26e90 * leapseconds.awk: no longer executable 42eda0722 Fix location of recently added posix_packrat line. bd548f646 Remove obsolescent posix_packrat target 13a0921ac New ‘make’ target tailored_tarballs 52f8d925f * zic.8: Don’t pagebreak just after "EXTENDED EXAMPLE". e4374a954 Fix minor glitches in .txt output 83a2b918a * tz-link.html: Link to the unsmear library. dfe016bc5 No leap second on 2022-12-31 a249a0c64 Use %z in vanguard form 0deba9f3e * europe: Fix a few more "Kiev"s in comments. 729c2d34d Refactor ziguard.awk e0d136f49 * europe, backzone: Correct and move Liechtenstein comment. 634b9361d * backward: Add backward-compatibility comment. dd0a679c9 * NEWS: Mention LOCALTIME change. 172d43570 Change LOCALTIME default back to Factory 50df7d69f gmtime etc. now say "UTC", not "GMT" bf8aa9414 Remove ancient asctime.c cruft 3da46e2af Avoid C macros when this is easy 4551a1ae6 Remove macros duplicated from private.h a4095bda6 Improve #if indenting 918e10e89 * zic.8: fix minus typo eaa6bf832 Add -R option to zic a9bb98690 Chile's 1946/7 DST started early 0b094598d April Fool note 7ffb999b1 Chile’s 1946/7 time was DST 37c27ce43 Iran 1977 fallback was 10-20 not 09-23 93b40c75a Upgrade GCC_DEBUG_FLAGS to GCC 12 ce8774c37 Document that zic -r doesn’t necessarily shrink 5e7de49c3 Fix bug with zic -r cutoff before 1st transition 1fa2731ce Refactor by using max and min macros 0e8f0b06a strftime %s no longer worries about mktime failure 6f2e9b693 Stricter mktime -1 heuristic in strftime d8655c6ae * asia: Commentary corrections from Michael Deckers. 52061c178 Correct Iran transitions in 1977 and 1978 ec42353f5 Fix bug uncovered by recent change to Iran history 6af4cda4f Refactor outzone 538c64e13 Iran DST changes in late 1970s 3d605c53f Iran switched to standard time in 1935 4742526b7 Prefer specified time for vestigial variables 9fa1a5395 * NEWS: Mention other Ukrainian locations. 8b6a387b1 Go back to 2021e Morocco rearguard workaround fd03aae45 Add </p> to end element. 726ef41a5 Clarify old-version doc 1fd3bd4c2 Check that FORMAT has / only with rules e18c7ac28 * zic.8: Say that STDOFF lacks suffix letters. 221bf5fe3 Simplify Asia/Dushanbe 6c018546a Remove already-obsolete link 66b18d983 Iran will stop DST in 2023 6f96f5590 Follow Shanks for Crimea 1994/1996 b5d501457 Simplify Europe/Simferopol a012287a6 Avoid “traditional” and “popular” e13e9c531 Rename Europe/Kiev to Europe/Kyiv 1f023d598 Cite 2022 Magallanes decree ac377a1f0 Simplify field memory allocation in zic 65f616d2e zic now checks input bytes more carefully ce5b21b84 Omit or paraphrase some quotes b6a8aeca9 Improve Morocco 2087 rearguard workaround a0f887648 Fix Dawson Creek latitude (thanks to Michael Ewert). 64c5d196f Fix spelling and grammar in commentary 32a9a151e Fix some typos in NEWS, africa and australasia. git-subtree-dir: tz git-subtree-split: 32a4af56f4afa83720840dc4e325636428283b84
-rw-r--r--Makefile160
-rw-r--r--NEWS117
-rw-r--r--africa48
-rw-r--r--antarctica30
-rw-r--r--asctime.c28
-rw-r--r--asia338
-rw-r--r--australasia107
-rw-r--r--backward18
-rw-r--r--backzone514
-rw-r--r--calendars4
-rw-r--r--date.c23
-rw-r--r--etcetera8
-rw-r--r--europe474
-rw-r--r--leap-seconds.list8
-rw-r--r--[-rwxr-xr-x]leapseconds.awk0
-rw-r--r--localtime.c111
-rw-r--r--northamerica21
-rw-r--r--private.h131
-rw-r--r--southamerica59
-rw-r--r--strftime.c34
-rw-r--r--theory.html14
-rw-r--r--tz-how-to.html29
-rw-r--r--tz-link.html7
-rw-r--r--tzfile.h14
-rw-r--r--tzselect.816
-rw-r--r--zdump.c14
-rw-r--r--zic.857
-rw-r--r--zic.c476
-rw-r--r--ziguard.awk236
-rw-r--r--zishrink.awk62
-rw-r--r--zone.tab4
-rw-r--r--zone1970.tab51
32 files changed, 1938 insertions, 1275 deletions
diff --git a/Makefile b/Makefile
index a9a989e..88240ad 100644
--- a/Makefile
+++ b/Makefile
@@ -33,7 +33,7 @@ DATAFORM= main
# make zonenames
# to get a list of the values you can use for LOCALTIME.
-LOCALTIME= GMT
+LOCALTIME= Factory
# The POSIXRULES macro controls interpretation of nonstandard and obsolete
# POSIX-like TZ settings like TZ='EET-2EEST' that lack DST transition rules.
@@ -176,12 +176,19 @@ TZDATA_TEXT= leapseconds tzdata.zi
BACKWARD= backward
-# If you want out-of-scope and often-wrong data from the file 'backzone', use
+# If you want out-of-scope and often-wrong data from the file 'backzone',
+# but only for entries listed in the backward-compatibility file zone.tab, use
# PACKRATDATA= backzone
+# PACKRATLIST= zone.tab
+# If you want all the 'backzone' data, use
+# PACKRATDATA= backzone
+# PACKRATLIST=
# To omit this data, use
# PACKRATDATA=
+# PACKRATLIST=
PACKRATDATA=
+PACKRATLIST=
# The name of a locale using the UTF-8 encoding, used during self-tests.
# The tests are skipped if the name does not appear to work on this system.
@@ -264,7 +271,7 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
$(GCC_INSTRUMENT) \
-Wall -Wextra \
-Walloc-size-larger-than=100000 -Warray-bounds=2 \
- -Wbad-function-cast -Wcast-align=strict -Wdate-time \
+ -Wbad-function-cast -Wbidi-chars=any,ucn -Wcast-align=strict -Wdate-time \
-Wdeclaration-after-statement -Wdouble-promotion \
-Wduplicated-branches -Wduplicated-cond \
-Wformat=2 -Wformat-overflow=2 -Wformat-signedness -Wformat-truncation \
@@ -278,7 +285,7 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
-Wsuggest-attribute=const -Wsuggest-attribute=format \
-Wsuggest-attribute=malloc \
-Wsuggest-attribute=noreturn -Wsuggest-attribute=pure \
- -Wtrampolines -Wundef -Wuninitialized -Wunused-macros \
+ -Wtrampolines -Wundef -Wuninitialized -Wunused-macros -Wuse-after-free=3 \
-Wvariadic-macros -Wvla -Wwrite-strings \
-Wno-address -Wno-format-nonliteral -Wno-sign-compare \
-Wno-type-limits -Wno-unused-parameter
@@ -448,6 +455,9 @@ UNUSUAL_OK_IPA = u̯
# useful in commentary.
UNUSUAL_OK_CHARSET= $(UNUSUAL_OK_LATIN_1)$(UNUSUAL_OK_IPA)
+# Put this in a bracket expression to match spaces.
+s = [:space:]
+
# OK_CHAR matches any character allowed in the distributed files.
# This is the same as SAFE_CHAR, except that UNUSUAL_OK_CHARSET and
# multibyte letters are also allowed so that commentary can contain a
@@ -521,8 +531,9 @@ TDATA= $(YDATA) $(NDATA) $(BACKWARD)
ZONETABLES= zone1970.tab zone.tab
TABDATA= iso3166.tab $(TZDATA_TEXT) $(ZONETABLES)
LEAP_DEPS= leapseconds.awk leap-seconds.list
-TZDATA_ZI_DEPS= ziguard.awk zishrink.awk version $(TDATA) $(PACKRATDATA)
-DSTDATA_ZI_DEPS= ziguard.awk $(TDATA) $(PACKRATDATA)
+TZDATA_ZI_DEPS= ziguard.awk zishrink.awk version $(TDATA) \
+ $(PACKRATDATA) $(PACKRATLIST)
+DSTDATA_ZI_DEPS= ziguard.awk $(TDATA) $(PACKRATDATA) $(PACKRATLIST)
DATA= $(TDATA_TO_CHECK) backzone iso3166.tab leap-seconds.list \
leapseconds $(ZONETABLES)
AWK_SCRIPTS= checklinks.awk checktab.awk leapseconds.awk \
@@ -534,8 +545,9 @@ TZS= to$(TZS_YEAR).tzs
TZS_NEW= to$(TZS_YEAR)new.tzs
TZS_DEPS= $(YDATA) asctime.c localtime.c \
private.h tzfile.h zdump.c zic.c
+TZDATA_DIST = $(COMMON) $(DATA) $(MISC)
# EIGHT_YARDS is just a yard short of the whole ENCHILADA.
-EIGHT_YARDS = $(COMMON) $(DOCS) $(SOURCES) $(DATA) $(MISC) tzdata.zi
+EIGHT_YARDS = $(TZDATA_DIST) $(DOCS) $(SOURCES) tzdata.zi
ENCHILADA = $(EIGHT_YARDS) $(TZS)
# Consult these files when deciding whether to rebuild the 'version' file.
@@ -608,13 +620,17 @@ version: $(VERSION_DEPS)
printf '%s\n' "$$V" >$@.out
mv $@.out $@
-# These files can be tailored by setting BACKWARD and PACKRATDATA.
+# These files can be tailored by setting BACKWARD, PACKRATDATA, PACKRATLIST.
vanguard.zi main.zi rearguard.zi: $(DSTDATA_ZI_DEPS)
- $(AWK) -v DATAFORM=`expr $@ : '\(.*\).zi'` -f ziguard.awk \
+ $(AWK) \
+ -v DATAFORM=`expr $@ : '\(.*\).zi'` \
+ -v PACKRATDATA='$(PACKRATDATA)' \
+ -v PACKRATLIST='$(PACKRATLIST)' \
+ -f ziguard.awk \
$(TDATA) $(PACKRATDATA) >$@.out
mv $@.out $@
# This file has a version comment that attempts to capture any tailoring
-# via BACKWARD, DATAFORM, PACKRATDATA, and REDO.
+# via BACKWARD, DATAFORM, PACKRATDATA, PACKRATLIST, and REDO.
tzdata.zi: $(DATAFORM).zi version zishrink.awk
version=`sed 1q version` && \
LC_ALL=C $(AWK) \
@@ -652,6 +668,7 @@ INSTALLARGS = \
DESTDIR='$(DESTDIR)' \
LEAPSECONDS='$(LEAPSECONDS)' \
PACKRATDATA='$(PACKRATDATA)' \
+ PACKRATLIST='$(PACKRATLIST)' \
TZDEFAULT='$(TZDEFAULT)' \
TZDIR='$(TZDIR)' \
ZIC='$(ZIC)'
@@ -690,11 +707,6 @@ posix_right: posix_only
$(MAKE) $(INSTALLARGS) TZDIR='$(TZDIR)-posix' posix_only
$(MAKE) $(INSTALLARGS) TZDIR='$(TZDIR)-leaps' right_only
-# This obsolescent rule is present for backwards compatibility with
-# tz releases 2014g through 2015g. It should go away eventually.
-posix_packrat: $(INSTALL_DATA_DEPS)
- $(MAKE) $(INSTALLARGS) PACKRATDATA=backzone posix_only
-
zones: $(REDO)
# dummy.zd is not a real file; it is mentioned here only so that the
@@ -755,8 +767,8 @@ tzselect: tzselect.ksh version
mv $@.out $@
check: check_character_set check_white_space check_links \
- check_name_lengths check_sorted \
- check_tables check_web check_zishrink check_tzs
+ check_name_lengths check_slashed_abbrs check_sorted \
+ check_tables check_web check_ziguard check_zishrink check_tzs
check_character_set: $(ENCHILADA)
test ! '$(UTF8_LOCALE)' || \
@@ -780,19 +792,28 @@ check_white_space: $(ENCHILADA)
patfmt=' \t|[\f\r\v]' && pat=`printf "$$patfmt\\n"` && \
! grep -En "$$pat" \
$$(ls $(ENCHILADA) | grep -Fvx leap-seconds.list)
- ! grep -n '[[:space:]]$$' \
+ ! grep -n '[$s]$$' \
$$(ls $(ENCHILADA) | grep -Fvx leap-seconds.list)
touch $@
-PRECEDES_FILE_NAME = ^(Zone|Link[[:space:]]+[^[:space:]]+)[[:space:]]+
-FILE_NAME_COMPONENT_TOO_LONG = \
- $(PRECEDES_FILE_NAME)[^[:space:]]*[^/[:space:]]{15}
+PRECEDES_FILE_NAME = ^(Zone|Link[$s]+[^$s]+)[$s]+
+FILE_NAME_COMPONENT_TOO_LONG = $(PRECEDES_FILE_NAME)[^$s]*[^/$s]{15}
check_name_lengths: $(TDATA_TO_CHECK) backzone
! grep -En '$(FILE_NAME_COMPONENT_TOO_LONG)' \
$(TDATA_TO_CHECK) backzone
touch $@
+PRECEDES_STDOFF = ^(Zone[$s]+[^$s]+)?[$s]+
+STDOFF = [-+]?[0-9:.]+
+RULELESS_SAVE = (-|$(STDOFF)[sd]?)
+RULELESS_SLASHED_ABBRS = \
+ $(PRECEDES_STDOFF)$(STDOFF)[$s]+$(RULELESS_SAVE)[$s]+[^$s]*/
+
+check_slashed_abbrs: $(TDATA_TO_CHECK)
+ ! grep -En '$(RULELESS_SLASHED_ABBRS)' $(TDATA_TO_CHECK)
+ touch $@
+
CHECK_CC_LIST = { n = split($$1,a,/,/); for (i=2; i<=n; i++) print a[1], a[i]; }
check_sorted: backward backzone iso3166.tab zone.tab zone1970.tab
@@ -832,11 +853,19 @@ check_theory.html check_tz-art.html check_tz-how-to.html check_tz-link.html:
test ! -s $@.out || { cat $@.out; exit 1; }
mv $@.out $@
+check_ziguard: rearguard.zi vanguard.zi ziguard.awk
+ $(AWK) -v DATAFORM=rearguard -f ziguard.awk vanguard.zi | \
+ diff -u rearguard.zi -
+ $(AWK) -v DATAFORM=vanguard -f ziguard.awk rearguard.zi | \
+ diff -u vanguard.zi -
+ touch $@
+
# Check that zishrink.awk does not alter the data, and that ziguard.awk
# preserves main-format data.
check_zishrink: check_zishrink_posix check_zishrink_right
check_zishrink_posix check_zishrink_right: \
- zic leapseconds $(PACKRATDATA) $(TDATA) $(DATAFORM).zi tzdata.zi
+ zic leapseconds $(PACKRATDATA) $(PACKRATLIST) \
+ $(TDATA) $(DATAFORM).zi tzdata.zi
rm -fr $@.dir $@-t.dir $@-shrunk.dir
mkdir $@.dir $@-t.dir $@-shrunk.dir
case $@ in \
@@ -845,8 +874,8 @@ check_zishrink_posix check_zishrink_right: \
esac && \
$(ZIC) $$leap -d $@.dir $(DATAFORM).zi && \
$(ZIC) $$leap -d $@-shrunk.dir tzdata.zi && \
- case $(DATAFORM) in \
- main) \
+ case $(DATAFORM),$(PACKRATLIST) in \
+ main,) \
$(ZIC) $$leap -d $@-t.dir $(TDATA) && \
$(AWK) '/^Rule/' $(TDATA) | \
$(ZIC) $$leap -d $@-t.dir - $(PACKRATDATA) && \
@@ -967,6 +996,10 @@ check_public: $(VERSION_DEPS)
rm public.dir/main.zi
cd public.dir && $(MAKE) PACKRATDATA=backzone main.zi
public.dir/zic -d public.dir/zoneinfo main.zi
+ rm public.dir/main.zi
+ cd public.dir && \
+ $(MAKE) PACKRATDATA=backzone PACKRATLIST=zone.tab main.zi
+ public.dir/zic -d public.dir/zoneinfo main.zi
:
rm -fr public.dir
touch $@
@@ -1027,9 +1060,9 @@ REARGUARD_ASC = \
ALL_ASC = $(TRADITIONAL_ASC) $(REARGUARD_ASC) \
tzdb-$(VERSION).tar.lz.asc
-tarballs rearguard_tarballs traditional_tarballs \
+tarballs rearguard_tarballs tailored_tarballs traditional_tarballs \
signatures rearguard_signatures traditional_signatures: \
- version set-timestamps.out rearguard.zi
+ version set-timestamps.out rearguard.zi vanguard.zi
VERSION=`cat version` && \
$(MAKE) AWK='$(AWK)' VERSION="$$VERSION" $@_version
@@ -1042,6 +1075,8 @@ rearguard_tarballs_version: \
tzdata$(VERSION)-rearguard.tar.gz
traditional_tarballs_version: \
tzcode$(VERSION).tar.gz tzdata$(VERSION).tar.gz
+tailored_tarballs_version: \
+ tzdata$(VERSION)-tailored.tar.gz
signatures_version: $(ALL_ASC)
rearguard_signatures_version: $(REARGUARD_ASC)
traditional_signatures_version: $(TRADITIONAL_ASC)
@@ -1055,34 +1090,76 @@ tzcode$(VERSION).tar.gz: set-timestamps.out
tzdata$(VERSION).tar.gz: set-timestamps.out
LC_ALL=C && export LC_ALL && \
- tar $(TARFLAGS) -cf - $(COMMON) $(DATA) $(MISC) | \
+ tar $(TARFLAGS) -cf - $(TZDATA_DIST) | \
gzip $(GZIPFLAGS) >$@.out
mv $@.out $@
+# Create empty files with a reproducible timestamp.
+CREATE_EMPTY = TZ=UTC0 touch -mt 202010122253.00
+
+# The obsolescent *rearguard* targets and related macros are present
+# for backwards compatibility with tz releases 2018e through 2022a.
+# They should go away eventually. To build rearguard tarballs you
+# can instead use 'make DATAFORM=rearguard tailored_tarballs'.
tzdata$(VERSION)-rearguard.tar.gz: rearguard.zi set-timestamps.out
- rm -fr tzdata$(VERSION)-rearguard.dir
- mkdir tzdata$(VERSION)-rearguard.dir
- ln $(COMMON) $(DATA) $(MISC) tzdata$(VERSION)-rearguard.dir
- cd tzdata$(VERSION)-rearguard.dir && \
- rm -f $(TDATA) $(PACKRATDATA) version
+ rm -fr $@.dir
+ mkdir $@.dir
+ ln $(TZDATA_DIST) $@.dir
+ cd $@.dir && rm -f $(TDATA) $(PACKRATDATA) version
for f in $(TDATA) $(PACKRATDATA); do \
- rearf=tzdata$(VERSION)-rearguard.dir/$$f; \
+ rearf=$@.dir/$$f; \
$(AWK) -v DATAFORM=rearguard -f ziguard.awk $$f >$$rearf && \
$(SET_TIMESTAMP_DEP) $$rearf ziguard.awk $$f || exit; \
done
- sed '1s/$$/-rearguard/' \
- <version >tzdata$(VERSION)-rearguard.dir/version
+ sed '1s/$$/-rearguard/' <version >$@.dir/version
: The dummy pacificnew pacifies TZUpdater 2.3.1 and earlier.
- TZ=UTC0 touch -mt 202010122253.00 \
- tzdata$(VERSION)-rearguard.dir/pacificnew
- touch -cmr version tzdata$(VERSION)-rearguard.dir/version
+ $(CREATE_EMPTY) $@.dir/pacificnew
+ touch -cmr version $@.dir/version
LC_ALL=C && export LC_ALL && \
- (cd tzdata$(VERSION)-rearguard.dir && \
+ (cd $@.dir && \
tar $(TARFLAGS) -cf - \
- $(COMMON) $(DATA) $(MISC) pacificnew | \
+ $(TZDATA_DIST) pacificnew | \
gzip $(GZIPFLAGS)) >$@.out
mv $@.out $@
+# Create a tailored tarball suitable for TZUpdater and compatible tools.
+# For example, 'make DATAFORM=vanguard tailored_tarballs' makes a tarball
+# useful for testing whether TZUpdater supports vanguard form.
+# The generated tarball is not byte-for-byte equivalent to a hand-tailored
+# traditional tarball, as data entries are put into 'etcetera' even if they
+# came from some other source file. However, the effect should be the same
+# for ordinary use, which reads all the source files.
+tzdata$(VERSION)-tailored.tar.gz: set-timestamps.out
+ rm -fr $@.dir
+ mkdir $@.dir
+ : The dummy pacificnew pacifies TZUpdater 2.3.1 and earlier.
+ cd $@.dir && \
+ $(CREATE_EMPTY) $(PRIMARY_YDATA) $(NDATA) backward \
+ `test $(DATAFORM) = vanguard || echo pacificnew`
+ (grep '^#' tzdata.zi && echo && cat $(DATAFORM).zi) \
+ >$@.dir/etcetera
+ touch -cmr tzdata.zi $@.dir/etcetera
+ sed -n \
+ -e '/^# *version *\(.*\)/h' \
+ -e '/^# *ddeps */H' \
+ -e '$$!d' \
+ -e 'g' \
+ -e 's/^# *version *//' \
+ -e 's/\n# *ddeps */-/' \
+ -e 's/ /-/g' \
+ -e 'p' \
+ <tzdata.zi >$@.dir/version
+ touch -cmr version $@.dir/version
+ links= && \
+ for file in $(TZDATA_DIST); do \
+ test -f $@.dir/$$file || links="$$links $$file"; \
+ done && \
+ ln $$links $@.dir
+ LC_ALL=C && export LC_ALL && \
+ (cd $@.dir && \
+ tar $(TARFLAGS) -cf - * | gzip $(GZIPFLAGS)) >$@.out
+ mv $@.out $@
+
tzdb-$(VERSION).tar.lz: set-timestamps.out set-tzs-timestamp.out
rm -fr tzdb-$(VERSION)
mkdir tzdb-$(VERSION)
@@ -1134,13 +1211,14 @@ zic.o: private.h tzfile.h version.h
.PHONY: check_web check_zishrink
.PHONY: clean clean_misc dummy.zd force_tzs
.PHONY: install install_data maintainer-clean names
-.PHONY: posix_only posix_packrat posix_right public
+.PHONY: posix_only posix_right public
.PHONY: rearguard_signatures rearguard_signatures_version
.PHONY: rearguard_tarballs rearguard_tarballs_version
.PHONY: right_only right_posix signatures signatures_version
.PHONY: tarballs tarballs_version
.PHONY: traditional_signatures traditional_signatures_version
.PHONY: traditional_tarballs traditional_tarballs_version
+.PHONY: tailored_tarballs tailored_tarballs_version
.PHONY: typecheck
.PHONY: zonenames zones
.PHONY: $(ZDS)
diff --git a/NEWS b/NEWS
index ae44be2..6a0d5c5 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,116 @@
News for the tz database
+Release 2022b - 2022-08-10 15:38:32 -0700
+
+ Briefly:
+ Chile's DST is delayed by a week in September 2022.
+ Iran no longer observes DST after 2022.
+ Rename Europe/Kiev to Europe/Kyiv.
+ New zic -R option
+ Vanguard form now uses %z.
+ Finish moving duplicate-since-1970 zones to 'backzone'.
+ New build option PACKRATLIST
+ New tailored_tarballs target, replacing rearguard_tarballs
+
+ Changes to future timestamps
+
+ Chile's 2022 DST start is delayed from September 4 to September 11.
+ (Thanks to Juan Correa.)
+
+ Iran plans to stop observing DST permanently, after it falls back
+ on 2022-09-21. (Thanks to Ali Mirjamali.)
+
+ Changes to past timestamps
+
+ Finish moving to 'backzone' the location-based zones whose
+ timestamps since 1970 are duplicates; adjust links accordingly.
+ This change ordinarily affects only pre-1970 timestamps, and with
+ the new PACKRATLIST option it does not affect any timestamps.
+ In this round the affected zones are Antarctica/Vostok,
+ Asia/Brunei, Asia/Kuala_Lumpur, Atlantic/Reykjavik,
+ Europe/Amsterdam, Europe/Copenhagen, Europe/Luxembourg,
+ Europe/Monaco, Europe/Oslo, Europe/Stockholm, Indian/Christmas,
+ Indian/Cocos, Indian/Kerguelen, Indian/Mahe, Indian/Reunion,
+ Pacific/Chuuk, Pacific/Funafuti, Pacific/Majuro, Pacific/Pohnpei,
+ Pacific/Wake and Pacific/Wallis, and the affected links are
+ Arctic/Longyearbyen, Atlantic/Jan_Mayen, Iceland, Pacific/Ponape,
+ Pacific/Truk, and Pacific/Yap.
+
+ From fall 1994 through fall 1995, Shanks wrote that Crimea's
+ DST transitions were at 02:00 standard time, not at 00:00.
+ (Thanks to Michael Deckers.)
+
+ Iran adopted standard time in 1935, not 1946. In 1977 it observed
+ DST from 03-21 23:00 to 10-20 24:00; its 1978 transitions were on
+ 03-24 and 08-05, not 03-20 and 10-20; and its spring 1979
+ transition was on 05-27, not 03-21.
+ (Thanks to Roozbeh Pournader and Francis Santoni.)
+
+ Chile's observance of -04 from 1946-08-29 through 1947-03-31 was
+ considered DST, not standard time. Santiago and environs had moved
+ their clocks back to rejoin the rest of mainland Chile; put this
+ change at the end of 1946-08-28. (Thanks to Michael Deckers.)
+
+ Some old, small clock transitions have been removed, as people at
+ the time did not change their clocks. This affects Asia/Hong_Kong
+ in 1904, Asia/Ho_Chi_Minh in 1906, and Europe/Dublin in 1880.
+
+ Changes to zone name
+
+ Rename Europe/Kiev to Europe/Kyiv, as "Kyiv" is more common in
+ English now. Spelling of other names in Ukraine has not yet
+ demonstrably changed in common English practice so for now these
+ names retain old spellings, as in other countries (e.g.,
+ Europe/Prague not "Praha", and Europe/Sofia not "Sofiya").
+
+ Changes to code
+
+ zic has a new option '-R @N' to output explicit transitions < N.
+ (Need suggested by Almaz Mingaleev.)
+
+ 'zic -r @N' no longer outputs bad data when N < first transition.
+ (Problem introduced in 2021d and reported by Peter Krefting.)
+
+ zic now checks its input for NUL bytes and unterminated lines, and
+ now supports input line lengths up to 2048 (not 512) bytes.
+
+ gmtime and related code now use the abbreviation "UTC" not "GMT".
+ POSIX is being revised to require this.
+
+ When tzset and related functions set vestigial static variables
+ like tzname, they now prefer specified timestamps to unspecified ones.
+ (Problem reported by Almaz Mingaleev.)
+
+ zic no longer complains "can't determine time zone abbreviation to
+ use just after until time" when a transition to a new standard
+ time occurs simultanously with the first DST fallback transition.
+
+ Changes to build procedure
+
+ Source data in vanguard form now uses the %z notation, introduced
+ in release 2015f. For example, for America/Sao_Paulo vanguard
+ form contains the zone continuation line "-3:00 Brazil %z", which
+ is simpler and more reliable than the line "-3:00 Brazil -03/-02"
+ used in main and rearguard forms. The plan is for the main form
+ to use %z eventually; in the meantime maintainers of zi parsers
+ are encouraged to test the parsers on vanguard.zi.
+
+ The Makefile has a new PACKRATLIST option to select a subset of
+ 'backzone'. For example, 'make PACKRATDATA=backzone
+ PACKRATLIST=zone.tab' now generates TZif files identical to those
+ of the global-tz project.
+
+ The Makefile has a new tailored_tarballs target for generating
+ special-purpose tarballs. It generalizes and replaces the
+ rearguard_tarballs target and related targets and macros, which
+ are now obsolescent.
+
+ 'make install' now defaults LOCALTIME to Factory not GMT,
+ which means the default abbreviation is now "-00" not "GMT".
+
+ Remove the posix_packrat target, marked obsolescent in 2016a.
+
+
Release 2022a - 2022-03-15 23:02:01 -0700
Briefly:
@@ -161,7 +272,7 @@ Release 2021b - 2021-09-24 16:23:00 -0700
Rename Pacific/Enderbury to Pacific/Kanton. When we added
Enderbury in 1993, we did not know that it is uninhabited and that
Kanton (population two dozen) is the only inhabited location in
- that timezone. The old name is now a backward-compatility link.
+ that timezone. The old name is now a backward-compatibility link.
Changes to past timestamps
@@ -1315,7 +1426,7 @@ Release 2018b - 2018-01-17 23:24:48 -0800
Changes to build procedure
The distribution now contains the file 'pacificnew' again.
- This file was inadvertantly omitted in the 2018a distribution.
+ This file was inadvertently omitted in the 2018a distribution.
(Problem reported by Matias Fonzo.)
@@ -4387,7 +4498,7 @@ Release 2007a - 2007-01-08 12:28:29 -0500
changes by Paul Eggert
- Derick Rethan's Asmara change
+ Derick Rethans's Asmara change
Oscar van Vlijmen's Easter Island local mean time change
diff --git a/africa b/africa
index 4bf491e..7cbd6b0 100644
--- a/africa
+++ b/africa
@@ -159,6 +159,7 @@ Link Africa/Abidjan Africa/Freetown # Sierra Leone
Link Africa/Abidjan Africa/Lome # Togo
Link Africa/Abidjan Africa/Nouakchott # Mauritania
Link Africa/Abidjan Africa/Ouagadougou # Burkina Faso
+Link Africa/Abidjan Atlantic/Reykjavik # Iceland
Link Africa/Abidjan Atlantic/St_Helena # St Helena
# Djibouti
@@ -169,7 +170,7 @@ Link Africa/Abidjan Atlantic/St_Helena # St Helena
# Egypt
# Milne says Cairo used 2:05:08.9, the local mean time of the Abbasizeh
-# observatory; round to nearest. Milne also says that the official time for
+# observatory. Milne also says that the official time for
# Egypt was mean noon at the Great Pyramid, 2:04:30.5, but apparently this
# did not apply to Cairo, Alexandria, or Port Said.
@@ -354,6 +355,7 @@ Rule Egypt 2014 only - Jul 31 24:00 1:00 S
Rule Egypt 2014 only - Sep lastThu 24:00 0 -
# Zone NAME STDOFF RULES FORMAT [UNTIL]
+ #STDOFF 2:05:08.9
Zone Africa/Cairo 2:05:09 - LMT 1900 Oct
2:00 Egypt EE%sT
@@ -407,7 +409,7 @@ Zone Africa/Bissau -1:02:20 - LMT 1912 Jan 1 1:00u
# At midnight on 30 June 1928 the clocks throughout Kenya was put forward
# half an hour by the Alteration of Time Ordinance, 1928.
# https://gazettes.africa/archive/ke/1928/ke-government-gazette-dated-1928-05-11-no-28.pdf
-# [Ordinance No. 11 of 1928, The Offical Gazette, 1928-06-26, p 813]
+# [Ordinance No. 11 of 1928, The Official Gazette, 1928-06-26, p 813]
# https://books.google.com/books?id=2S0S6os32ZUC&pg=PA813
#
# The 1928 ordinance was repealed by the Alteration of Time (repeal) Ordinance,
@@ -1310,21 +1312,9 @@ Link Africa/Lagos Africa/Niamey # Niger
Link Africa/Lagos Africa/Porto-Novo # Benin
# Réunion
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Indian/Reunion 3:41:52 - LMT 1911 Jun # Saint-Denis
- 4:00 - +04
-#
-# Scattered Islands (Îles Éparses) administered from Réunion are as follows.
-# The following information about them is taken from
-# Îles Éparses (<http://www.outre-mer.gouv.fr/domtom/ile.htm>, 1997-07-22,
-# in French; no longer available as of 1999-08-17).
-# We have no info about their time zone histories.
+# See Asia/Dubai.
#
-# Bassas da India - uninhabited
-# Europa Island - inhabited from 1905 to 1910 by two families
-# Glorioso Is - inhabited until at least 1958
-# Juan de Nova - uninhabited
-# Tromelin - inhabited until at least 1958
+# The Crozet Islands also observe Réunion time; see the 'antarctica' file.
# Rwanda
# See Africa/Maputo.
@@ -1356,9 +1346,10 @@ Zone Indian/Reunion 3:41:52 - LMT 1911 Jun # Saint-Denis
# From Michael Deckers (2018-12-30):
# https://www.legis-palop.org/download.jsp?idFile=102818
# ... [The legal time of the country, which coincides with universal
-# coordinated time, will be restituted at 2 o'clock on day 1 of January, 2019.]
+# coordinated time, will be reinstituted at 2 o'clock on day 1 of January, 2019.]
Zone Africa/Sao_Tome 0:26:56 - LMT 1884
+ #STDOFF -0:36:44.68
-0:36:45 - LMT 1912 Jan 1 00:00u # Lisbon MT
0:00 - GMT 2018 Jan 1 01:00
1:00 - WAT 2019 Jan 1 02:00
@@ -1368,28 +1359,7 @@ Zone Africa/Sao_Tome 0:26:56 - LMT 1884
# See Africa/Abidjan.
# Seychelles
-
-# From P Chan (2020-11-27):
-# Standard Time was adopted on 1907-01-01.
-#
-# Standard Time Ordinance (Chapter 237)
-# The Laws of Seychelles in Force on the 31st December, 1971, Vol. 6, p 571
-# https://books.google.com/books?id=efE-AQAAIAAJ&pg=PA571
-#
-# From Tim Parenti (2020-12-05):
-# A footnote on https://books.google.com/books?id=DYdDAQAAMAAJ&pg=PA1689
-# confirms that Ordinance No. 9 of 1906 "was brought into force on the 1st
-# January, 1907."
-
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Indian/Mahe 3:41:48 - LMT 1907 Jan 1 # Victoria
- 4:00 - +04
-# From Paul Eggert (2001-05-30):
-# Aldabra, Farquhar, and Desroches, originally dependencies of the
-# Seychelles, were transferred to the British Indian Ocean Territory
-# in 1965 and returned to Seychelles control in 1976. We don't know
-# whether this affected their time zone, so omit this for now.
-# Possibly the islands were uninhabited.
+# See Asia/Dubai.
# Sierra Leone
# See Africa/Abidjan.
diff --git a/antarctica b/antarctica
index 70a5422..dbdf209 100644
--- a/antarctica
+++ b/antarctica
@@ -157,9 +157,7 @@ Zone Antarctica/Mawson 0 - -00 1954 Feb 13
# St Paul Island - near Amsterdam, uninhabited
# fishing stations operated variously 1819/1931
#
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Indian/Kerguelen 0 - -00 1950 # Port-aux-Français
- 5:00 - +05
+# Kerguelen - see Indian/Maldives.
#
# year-round base in the main continent
# Dumont d'Urville - see Pacific/Port_Moresby.
@@ -242,31 +240,7 @@ Zone Antarctica/Troll 0 - -00 2005 Feb 12
# year-round from 1960/61 to 1992
# Vostok, since 1957-12-16, temporarily closed 1994-02/1994-11
-# From Craig Mundell (1994-12-15):
-# http://quest.arc.nasa.gov/antarctica/QA/computers/Directions,Time,ZIP
-# Vostok, which is one of the Russian stations, is set on the same
-# time as Moscow, Russia.
-#
-# From Lee Hotz (2001-03-08):
-# I queried the folks at Columbia who spent the summer at Vostok and this is
-# what they had to say about time there:
-# "in the US Camp (East Camp) we have been on New Zealand (McMurdo)
-# time, which is 12 hours ahead of GMT. The Russian Station Vostok was
-# 6 hours behind that (although only 2 miles away, i.e. 6 hours ahead
-# of GMT). This is a time zone I think two hours east of Moscow. The
-# natural time zone is in between the two: 8 hours ahead of GMT."
-#
-# From Paul Eggert (2001-05-04):
-# This seems to be hopelessly confusing, so I asked Lee Hotz about it
-# in person. He said that some Antarctic locations set their local
-# time so that noon is the warmest part of the day, and that this
-# changes during the year and does not necessarily correspond to mean
-# solar noon. So the Vostok time might have been whatever the clocks
-# happened to be during their visit. So we still don't really know what time
-# it is at Vostok. But we'll guess +06.
-#
-Zone Antarctica/Vostok 0 - -00 1957 Dec 16
- 6:00 - +06
+# See Asia/Urumqi.
# S Africa - year-round bases
# Marion Island, -4653+03752
diff --git a/asctime.c b/asctime.c
index 56c54b3..f0159f8 100644
--- a/asctime.c
+++ b/asctime.c
@@ -17,12 +17,6 @@
#include <stdio.h>
/*
-** Some systems only handle "%.2d"; others only handle "%02d";
-** "%02.2d" makes (most) everybody happy.
-** At least some versions of gcc warn about the %02.2d;
-** we conditionalize below to avoid the warning.
-*/
-/*
** All years associated with 32-bit time_t values are exactly four digits long;
** some years associated with 64-bit time_t values are not.
** Vintage programs are coded for years that are always four digits long
@@ -34,24 +28,16 @@
** The ISO C and POSIX standards prohibit padding the year,
** but many implementations pad anyway; most likely the standards are buggy.
*/
-#ifdef __GNUC__
-#define ASCTIME_FMT "%s %s%3d %2.2d:%2.2d:%2.2d %-4s\n"
-#else /* !defined __GNUC__ */
-#define ASCTIME_FMT "%s %s%3d %02.2d:%02.2d:%02.2d %-4s\n"
-#endif /* !defined __GNUC__ */
+static char const ASCTIME_FMT[] = "%s %s%3d %.2d:%.2d:%.2d %-4s\n";
/*
** For years that are more than four digits we put extra spaces before the year
** so that code trying to overwrite the newline won't end up overwriting
** a digit within a year and truncating the year (operating on the assumption
** that no output is better than wrong output).
*/
-#ifdef __GNUC__
-#define ASCTIME_FMT_B "%s %s%3d %2.2d:%2.2d:%2.2d %s\n"
-#else /* !defined __GNUC__ */
-#define ASCTIME_FMT_B "%s %s%3d %02.2d:%02.2d:%02.2d %s\n"
-#endif /* !defined __GNUC__ */
+static char const ASCTIME_FMT_B[] = "%s %s%3d %.2d:%.2d:%.2d %s\n";
-#define STD_ASCTIME_BUF_SIZE 26
+enum { STD_ASCTIME_BUF_SIZE = 26 };
/*
** Big enough for something such as
** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
@@ -59,12 +45,10 @@
** seven explicit spaces, two explicit colons, a newline,
** and a trailing NUL byte).
** The values above are for systems where an int is 32 bits and are provided
-** as an example; the define below calculates the maximum for the system at
+** as an example; the size expression below is a bound for the system at
** hand.
*/
-#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1)
-
-static char buf_asctime[MAX_ASCTIME_BUF_SIZE];
+static char buf_asctime[2*3 + 5*INT_STRLEN_MAXIMUM(int) + 7 + 2 + 1 + 1];
char *
asctime_r(register const struct tm *timeptr, char *buf)
@@ -79,7 +63,7 @@ asctime_r(register const struct tm *timeptr, char *buf)
register const char * wn;
register const char * mn;
char year[INT_STRLEN_MAXIMUM(int) + 2];
- char result[MAX_ASCTIME_BUF_SIZE];
+ char result[sizeof buf_asctime];
if (timeptr == NULL) {
errno = EINVAL;
diff --git a/asia b/asia
index 049b35c..def9b20 100644
--- a/asia
+++ b/asia
@@ -255,10 +255,7 @@ Zone Indian/Chagos 4:49:40 - LMT 1907
6:00 - +06
# Brunei
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Asia/Brunei 7:39:40 - LMT 1926 Mar # Bandar Seri Begawan
- 7:30 - +0730 1933
- 8:00 - +08
+# See Asia/Kuching.
# Burma / Myanmar
@@ -276,6 +273,7 @@ Zone Asia/Yangon 6:24:47 - LMT 1880 # or Rangoon
6:30 - +0630 1942 May
9:00 - +09 1945 May 3
6:30 - +0630
+Link Asia/Yangon Indian/Cocos
# Cambodia
# See Asia/Bangkok.
@@ -344,12 +342,9 @@ Rule Shang 1919 only - Sep 30 24:00 0 S
# in the city at the time for people who use different time standard to adjust
# their clock to their preferred time.
#
-# a. For the 1940 May 31 spring forward, the essay claim that it was
-# coordinared between the international settlement authority and the French
-# concession authority and have gathered support from Hong Kong and Xiamen,
-# that it would spring forward an hour from May 31 "midnight", and the essay
-# claim "Hong Kong government implemented the spring forward in the same time
-# on the same date as Shanghai".
+# a. For the 1940 May 31 spring forward, the essay [says] ... "Hong
+# Kong government implemented the spring forward in the same time on
+# the same date as Shanghai".
#
# b. For the 1940 fall back, it was said that they initially intended to do
# so on September 30 00:59 at night, however they postponed it to October 12
@@ -545,7 +540,7 @@ Rule PRC 1987 1991 - Apr Sun>=11 2:00 1:00 D
# Zhongyuan Time ("Central plain Time") UT +08
# Now part of Asia/Shanghai.
# most of China
-# Milne gives 8:05:43.2 for Xujiahui Observatory time; round to nearest.
+# Milne gives 8:05:43.2 for Xujiahui Observatory time....
# Guo says Shanghai switched to UT +08 "from the end of the 19th century".
#
# Long-shu Time (probably as Long and Shu were two names of the area) UT +07
@@ -664,6 +659,7 @@ Rule PRC 1987 1991 - Apr Sun>=11 2:00 1:00 D
# Zone NAME STDOFF RULES FORMAT [UNTIL]
# Beijing time, used throughout China; represented by Shanghai.
+ #STDOFF 8:05:43.2
Zone Asia/Shanghai 8:05:43 - LMT 1901
8:00 Shang C%sT 1949 May 28
8:00 PRC C%sT
@@ -671,11 +667,12 @@ Zone Asia/Shanghai 8:05:43 - LMT 1901
# / Wulumuqi. (Please use Asia/Shanghai if you prefer Beijing time.)
Zone Asia/Urumqi 5:50:20 - LMT 1928
6:00 - +06
+Link Asia/Urumqi Antarctica/Vostok
# Hong Kong
-# Milne gives 7:36:41.7; round this.
+# Milne gives 7:36:41.7.
# From Lee Yiu Chung (2009-10-24):
# I found there are some mistakes for the...DST rule for Hong
@@ -859,7 +856,8 @@ Rule HK 1973 only - Dec 30 3:30 1:00 S
Rule HK 1979 only - May 13 3:30 1:00 S
Rule HK 1979 only - Oct 21 3:30 0 -
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Asia/Hong_Kong 7:36:42 - LMT 1904 Oct 30 0:36:42
+ #STDOFF 7:36:41.7
+Zone Asia/Hong_Kong 7:36:42 - LMT 1904 Oct 29 17:00u
8:00 - HKT 1941 Jun 15 3:00
8:00 1:00 HKST 1941 Oct 1 4:00
8:00 0:30 HKWT 1941 Dec 25
@@ -1334,7 +1332,7 @@ Zone Asia/Kolkata 5:53:28 - LMT 1854 Jun 28 # Kolkata
#
# From Paul Eggert (2014-09-06):
# The 1876 Report of the Secretary of the [US] Navy, p 306 says that Batavia
-# civil time was 7:07:12.5; round to even for Jakarta.
+# civil time was 7:07:12.5.
#
# From Gwillim Law (2001-05-28), overriding Shanks & Pottenger:
# http://www.sumatera-inc.com/go_to_invest/about_indonesia.asp#standtime
@@ -1370,10 +1368,11 @@ Zone Asia/Kolkata 5:53:28 - LMT 1854 Jun 28 # Kolkata
#
# Zone NAME STDOFF RULES FORMAT [UNTIL]
# Java, Sumatra
+ #STDOFF 7:07:12.5
Zone Asia/Jakarta 7:07:12 - LMT 1867 Aug 10
# Shanks & Pottenger say the next transition was at 1924 Jan 1 0:13,
# but this must be a typo.
- 7:07:12 - BMT 1923 Dec 31 23:47:12 # Batavia
+ 7:07:12 - BMT 1923 Dec 31 16:40u # Batavia
7:20 - +0720 1932 Nov
7:30 - +0730 1942 Mar 23
9:00 - +09 1945 Sep 23
@@ -1405,6 +1404,111 @@ Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov
# Iran
+# From Roozbeh Pournader (2022-05-30):
+# Here's an order from the Cabinet to the rest of the government to switch to
+# Tehran time, which is mentioned to be already at +03:30:
+# https://qavanin.ir/Law/TreeText/180138
+# Just in case that goes away, I also saved a copy at archive.org:
+# https://web.archive.org/web/20220530111940/https://qavanin.ir/Law/TreeText/180138
+# Here's my translation:
+#
+# "Circular on Matching the Hours of Governmental and Official Circles
+# in Provinces
+# Approved 1314/03/22 [=1935-06-13]
+# According to the ruling of the Honorable Cabinet, it is ordered that from
+# now on in all internal provinces of the country, governmental and official
+# circles set their time to match Tehran time (three hours and half before
+# Greenwich)....
+#
+# I still haven't found out when Tehran itself switched to +03:30....
+#
+# From Paul Eggert (2022-06-05):
+# Although the above says Tehran was at +03:30 before 1935-06-13, we don't
+# know when it switched to +03:30. For now, use 1935-06-13 as the switch date.
+# Although most likely wrong, we have no better info.
+
+# From Roozbeh Pournader (2022-06-01):
+# This is from Kayhan newspaper, one of the major Iranian newspapers, from
+# March 20, 1978, page 2:
+#
+# "Pull the clocks 60 minutes forward
+# As we informed before, from the fourth day of the month Farvardin of the
+# new year [=1978-03-24], clocks will be pulled forward, and people's daily
+# work and life program will start one hour earlier than the current program.
+# On the 1st day of the month Farvardin of this year [=1977-03-21], they had
+# pulled the clocks forward by one hour, but in the month of Mehr
+# [=1977-09-23], the clocks were pulled back by 30 minutes.
+# In this way, from the 4th day of the month Farvardin, clocks will be ahead
+# of the previous years by one hour and a half.
+# According to the new program, during the night of 4th of Farvardin, when
+# the midnight, meaning 24 o'clock is announced, the hands of the clock must
+# be pulled forward by one hour and thus consider midnight 1 o'clock in the
+# forenoon."
+#
+# This implies that in September 1977, when the daylight savings time was
+# done with, Iran didn't go back to +03:30, but immediately to +04:00.
+#
+#
+# This is from the major Iranian newspaper Ettela'at, dated [1978-08-03]...,
+# page 32. It looks like they decided to get the clocks back to +4:00
+# just in time for Ramadan that year:
+#
+# "Tomorrow Night, Pull the Clocks Back by One Hour
+# At 1 o'clock in the forenoon of Saturday 14 Mordad [=1978-08-05], the
+# clocks will be pulled one hour back and instead of 1 o'clock in the
+# forenoon, Radio Iran will announce 24 o'clock.
+# This decision was made in the Cabinet of Ministers meeting of 25 Tir
+# [=1978-07-16], [...]
+# At the beginning of the year 2537 [=March 1978: Iran was using a different
+# year number for a few years then, based on the Coronation of Cyrus the
+# Great], the country's official time was pulled forward by one hour and now
+# the official time is one hour and a half ahead compared to last year,
+# because in Farvardin of last year [=March 1977], the official time was
+# pulled forward one hour and this continued until the second half of last
+# year [=September 1977] until in the second half of last year the official
+# time was pulled back half an hour and that half hour still remains."
+#
+# This matches the time of the true noon published in the newspapers, as they
+# clearly go from +05:00 to +04:00 after that date (which happened during a
+# long weekend in Iran).
+
+# From Roozbeh Pournader (2022-05-31):
+# [Movahedi S. Cultural preconceptions of time: Can we use operational time
+# to meddle in God's Time? Comp Stud Soc Hist. 1985;27(3):385-400]
+# https://www.jstor.org/stable/178704
+# Here's the quotes from the paper:
+# 1. '"Iran's official time keeper moved the clock one hour forward as from
+# March 22, 1977 (Farvardin 2, 2536) to make maximum use of daylight and save
+# in energy consumption. Thus Iran joined such other countries as Britain in
+# observing what is known as 'daylight saving.' The proposal was originally
+# put forward by the Ministry of Energy, in no way having any influence on
+# observing religious ceremonies. Moving time one hour forward in summer
+# means that at 11:00 o'clock on March 21, the official time was set as
+# midnight March 22. Then September 24 will actually begin one hour later
+# than the end of September 23 [...]." Iran's time base thus continued to be
+# Greenwich Mean Time plus three and one-half hours (plus four and one-half
+# hours in summer).'
+#
+# The article sources this from Iran Almanac and Book of Facts, 1977, Tehran:
+# Echo of Iran, which is on Google Books at
+# https://www.google.com/books/edition/Iran_Almanac_and_Book_of_Facts/9ybVAAAAMAAJ.
+# (I confirmed it by searching for snippets.)
+#
+# 2. "After the fall of the shah, the revolutionary government returned to
+# daylight-saving time (DST) on 26 May 1979."
+#
+# This seems to have been announced just one day in advance, on 25 May 1979.
+#
+# The change in 1977 clearly seems to be the first daylight savings effort in
+# Iran. But the article doesn't mention what happened in 1978 (which was
+# still during the shah's government), or how things continued in 1979
+# onwards (which was during the Islamic Republic).
+
+# From Francis Santoni (2022-06-01):
+# for Iran and 1977 the effective change is only 20 october
+# (UIT No. 143 17.XI.1977) and not 23 september (UIT No. 141 13.IX.1977).
+# UIT is the Operational Bulletin of International Telecommunication Union.
+
# From Roozbeh Pournader (2003-03-15):
# This is an English translation of what I just found (originally in Persian).
# The Gregorian dates in brackets are mine:
@@ -1439,65 +1543,12 @@ Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov
# leap year calculation involved. There has never been any serious
# plan to change that law....
#
-# From Paul Eggert (2018-11-30):
-# Go with Shanks & Pottenger before Sept. 1991, and with Pournader thereafter.
-# I used the following code in GNU Emacs 26.1 to generate the "Rule Iran"
-# lines from 2008 through 2087. Emacs 26.1 uses Ed Reingold's
-# cal-persia implementation of Birashk's approximation, which in the
-# 2008-2087 range disagrees with the astronomical Persian calendar
-# for Persian years 1404 (Gregorian 2025) and 1437 (Gregorian 2058), so
-# the following code special-cases those years. See Table 15.1, page 264, of:
-# Edward M. Reingold and Nachum Dershowitz, Calendrical Calculations:
-# The Ultimate Edition, Cambridge University Press (2018).
-# https://www.cambridge.org/fr/academic/subjects/computer-science/computing-general-interest/calendrical-calculations-ultimate-edition-4th-edition
-# Page 258, footnote 2, of this book says there is some dispute over what will
-# happen in 2091 (and some other years after that), so this code
-# stops in 2087, as 2088 and 2089 agree with the "max" rule below.
-# (cl-loop
-# initially (require 'cal-persia)
-# with first-persian-year = 1387
-# with last-persian-year = 1466
-# ;; Exceptional years in the above range,
-# ;; from Reingold & Dershowitz Table 15.1, page 264:
-# with exceptional-persian-years = '(1404 1437)
-# with range-start = nil
-# for persian-year from first-persian-year to last-persian-year
-# do
-# (let*
-# ((exceptional-year-offset
-# (if (member persian-year exceptional-persian-years) 1 0))
-# (beg-dst-absolute
-# (+ (calendar-persian-to-absolute (list 1 1 persian-year))
-# exceptional-year-offset))
-# (end-dst-absolute
-# (+ (calendar-persian-to-absolute (list 6 30 persian-year))
-# exceptional-year-offset))
-# (next-year-beg-dst-absolute
-# (+ (calendar-persian-to-absolute (list 1 1 (1+ persian-year)))
-# (if (member (1+ persian-year) exceptional-persian-years) 1 0)))
-# (beg-dst (calendar-gregorian-from-absolute beg-dst-absolute))
-# (end-dst (calendar-gregorian-from-absolute end-dst-absolute))
-# (next-year-beg-dst (calendar-gregorian-from-absolute
-# next-year-beg-dst-absolute))
-# (year (calendar-extract-year beg-dst))
-# (range-end (if range-start year "only")))
-# (setq range-start (or range-start year))
-# (when (or (/= (calendar-extract-day beg-dst)
-# (calendar-extract-day next-year-beg-dst))
-# (= persian-year last-persian-year))
-# (insert
-# (format
-# "Rule\tIran\t%d\t%s\t-\t%s\t%2d\t24:00\t1:00\t-\n"
-# range-start range-end
-# (calendar-month-name (calendar-extract-month beg-dst) t)
-# (calendar-extract-day beg-dst)))
-# (insert
-# (format
-# "Rule\tIran\t%d\t%s\t-\t%s\t%2d\t24:00\t0\t-\n"
-# range-start range-end
-# (calendar-month-name (calendar-extract-month end-dst) t)
-# (calendar-extract-day end-dst)))
-# (setq range-start nil))))
+# From Paul Eggert (2022-06-30):
+# Go with Pournader for 1935 through spring 1979, and for timestamps
+# after August 1991; go with with Shanks & Pottenger for other timestamps.
+# Go with Santoni's citation of the UIT for fall 1977, as 20 October 1977
+# is 28 Mehr 1356, consistent with the "Mehr" in Pournader's source.
+# Assume that the UIT's "1930" is UTC, i.e., 24:00 local time.
#
# From Oscar van Vlijmen (2005-03-30), writing about future
# discrepancies between cal-persia and the Iranian calendar:
@@ -1531,10 +1582,23 @@ Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov
# be changed back to its previous state on the 24 hours of the
# thirtieth day of Shahrivar.
#
+# From Ali Mirjamali (2022-05-10):
+# Official IR News Agency announcement: irna.ir/xjJ3TT
+# ...
+# Highlights: DST will be cancelled for the next Iranian year 1402
+# (i.e 2023-March-21) and forthcoming years.
+#
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
-Rule Iran 1978 1980 - Mar 20 24:00 1:00 -
-Rule Iran 1978 only - Oct 20 24:00 0 -
+# Work around a bug in zic 2022a and earlier.
+Rule Iran 1910 only - Jan 1 00:00 0 -
+#
+Rule Iran 1977 only - Mar 21 23:00 1:00 -
+Rule Iran 1977 only - Oct 20 24:00 0 -
+Rule Iran 1978 only - Mar 24 24:00 1:00 -
+Rule Iran 1978 only - Aug 5 01:00 0 -
+Rule Iran 1979 only - May 26 24:00 1:00 -
Rule Iran 1979 only - Sep 18 24:00 0 -
+Rule Iran 1980 only - Mar 20 24:00 1:00 -
Rule Iran 1980 only - Sep 22 24:00 0 -
Rule Iran 1991 only - May 2 24:00 1:00 -
Rule Iran 1992 1995 - Mar 21 24:00 1:00 -
@@ -1565,85 +1629,13 @@ Rule Iran 2017 2019 - Mar 21 24:00 1:00 -
Rule Iran 2017 2019 - Sep 21 24:00 0 -
Rule Iran 2020 only - Mar 20 24:00 1:00 -
Rule Iran 2020 only - Sep 20 24:00 0 -
-Rule Iran 2021 2023 - Mar 21 24:00 1:00 -
-Rule Iran 2021 2023 - Sep 21 24:00 0 -
-Rule Iran 2024 only - Mar 20 24:00 1:00 -
-Rule Iran 2024 only - Sep 20 24:00 0 -
-Rule Iran 2025 2027 - Mar 21 24:00 1:00 -
-Rule Iran 2025 2027 - Sep 21 24:00 0 -
-Rule Iran 2028 2029 - Mar 20 24:00 1:00 -
-Rule Iran 2028 2029 - Sep 20 24:00 0 -
-Rule Iran 2030 2031 - Mar 21 24:00 1:00 -
-Rule Iran 2030 2031 - Sep 21 24:00 0 -
-Rule Iran 2032 2033 - Mar 20 24:00 1:00 -
-Rule Iran 2032 2033 - Sep 20 24:00 0 -
-Rule Iran 2034 2035 - Mar 21 24:00 1:00 -
-Rule Iran 2034 2035 - Sep 21 24:00 0 -
-Rule Iran 2036 2037 - Mar 20 24:00 1:00 -
-Rule Iran 2036 2037 - Sep 20 24:00 0 -
-Rule Iran 2038 2039 - Mar 21 24:00 1:00 -
-Rule Iran 2038 2039 - Sep 21 24:00 0 -
-Rule Iran 2040 2041 - Mar 20 24:00 1:00 -
-Rule Iran 2040 2041 - Sep 20 24:00 0 -
-Rule Iran 2042 2043 - Mar 21 24:00 1:00 -
-Rule Iran 2042 2043 - Sep 21 24:00 0 -
-Rule Iran 2044 2045 - Mar 20 24:00 1:00 -
-Rule Iran 2044 2045 - Sep 20 24:00 0 -
-Rule Iran 2046 2047 - Mar 21 24:00 1:00 -
-Rule Iran 2046 2047 - Sep 21 24:00 0 -
-Rule Iran 2048 2049 - Mar 20 24:00 1:00 -
-Rule Iran 2048 2049 - Sep 20 24:00 0 -
-Rule Iran 2050 2051 - Mar 21 24:00 1:00 -
-Rule Iran 2050 2051 - Sep 21 24:00 0 -
-Rule Iran 2052 2053 - Mar 20 24:00 1:00 -
-Rule Iran 2052 2053 - Sep 20 24:00 0 -
-Rule Iran 2054 2055 - Mar 21 24:00 1:00 -
-Rule Iran 2054 2055 - Sep 21 24:00 0 -
-Rule Iran 2056 2057 - Mar 20 24:00 1:00 -
-Rule Iran 2056 2057 - Sep 20 24:00 0 -
-Rule Iran 2058 2059 - Mar 21 24:00 1:00 -
-Rule Iran 2058 2059 - Sep 21 24:00 0 -
-Rule Iran 2060 2062 - Mar 20 24:00 1:00 -
-Rule Iran 2060 2062 - Sep 20 24:00 0 -
-Rule Iran 2063 only - Mar 21 24:00 1:00 -
-Rule Iran 2063 only - Sep 21 24:00 0 -
-Rule Iran 2064 2066 - Mar 20 24:00 1:00 -
-Rule Iran 2064 2066 - Sep 20 24:00 0 -
-Rule Iran 2067 only - Mar 21 24:00 1:00 -
-Rule Iran 2067 only - Sep 21 24:00 0 -
-Rule Iran 2068 2070 - Mar 20 24:00 1:00 -
-Rule Iran 2068 2070 - Sep 20 24:00 0 -
-Rule Iran 2071 only - Mar 21 24:00 1:00 -
-Rule Iran 2071 only - Sep 21 24:00 0 -
-Rule Iran 2072 2074 - Mar 20 24:00 1:00 -
-Rule Iran 2072 2074 - Sep 20 24:00 0 -
-Rule Iran 2075 only - Mar 21 24:00 1:00 -
-Rule Iran 2075 only - Sep 21 24:00 0 -
-Rule Iran 2076 2078 - Mar 20 24:00 1:00 -
-Rule Iran 2076 2078 - Sep 20 24:00 0 -
-Rule Iran 2079 only - Mar 21 24:00 1:00 -
-Rule Iran 2079 only - Sep 21 24:00 0 -
-Rule Iran 2080 2082 - Mar 20 24:00 1:00 -
-Rule Iran 2080 2082 - Sep 20 24:00 0 -
-Rule Iran 2083 only - Mar 21 24:00 1:00 -
-Rule Iran 2083 only - Sep 21 24:00 0 -
-Rule Iran 2084 2086 - Mar 20 24:00 1:00 -
-Rule Iran 2084 2086 - Sep 20 24:00 0 -
-Rule Iran 2087 only - Mar 21 24:00 1:00 -
-Rule Iran 2087 only - Sep 21 24:00 0 -
-#
-# The following rules are approximations starting in the year 2088.
-# These are the best post-2088 approximations available, given the
-# restrictions of a single rule using ordinary Gregorian dates.
-# At some point this table will need to be extended, though quite
-# possibly Iran will change the rules first.
-Rule Iran 2088 max - Mar 20 24:00 1:00 -
-Rule Iran 2088 max - Sep 20 24:00 0 -
+Rule Iran 2021 2022 - Mar 21 24:00 1:00 -
+Rule Iran 2021 2022 - Sep 21 24:00 0 -
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Tehran 3:25:44 - LMT 1916
- 3:25:44 - TMT 1946 # Tehran Mean Time
- 3:30 - +0330 1977 Nov
+ 3:25:44 - TMT 1935 Jun 13 # Tehran Mean Time
+ 3:30 Iran +0330/+0430 1977 Oct 20 24:00
4:00 Iran +04/+05 1979
3:30 Iran +0330/+0430
@@ -2465,9 +2457,9 @@ Zone Asia/Amman 2:23:44 - LMT 1931
# the third time belt (before 1930 this means +03).
# From Alexander Konzurovski (2018-12-20):
-# Qyzyolrda Region (Asia/Qyzylorda) is changing its time zone from
-# UTC+6 to UTC+5 effective December 21st, 2018. The legal document is
-# located here: http://adilet.zan.kz/rus/docs/P1800000817 (russian language).
+# (Asia/Qyzylorda) is changing its time zone from UTC+6 to UTC+5
+# effective December 21st, 2018....
+# http://adilet.zan.kz/rus/docs/P1800000817 (russian language).
# Zone NAME STDOFF RULES FORMAT [UNTIL]
#
@@ -2744,20 +2736,8 @@ Zone Asia/Beirut 2:22:00 - LMT 1880
Rule NBorneo 1935 1941 - Sep 14 0:00 0:20 -
Rule NBorneo 1935 1941 - Dec 14 0:00 0 -
#
-# peninsular Malaysia
-# taken from Mok Ly Yng (2003-10-30)
-# https://web.archive.org/web/20190822231045/http://www.math.nus.edu.sg/~mathelmr/teaching/timezone.html
-# This agrees with Singapore since 1905-06-01.
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Asia/Kuala_Lumpur 6:46:46 - LMT 1901 Jan 1
- 6:55:25 - SMT 1905 Jun 1 # Singapore M.T.
- 7:00 - +07 1933 Jan 1
- 7:00 0:20 +0720 1936 Jan 1
- 7:20 - +0720 1941 Sep 1
- 7:30 - +0730 1942 Feb 16
- 9:00 - +09 1945 Sep 12
- 7:30 - +0730 1982 Jan 1
- 8:00 - +08
+# For peninsular Malaysia see Asia/Singapore.
+#
# Sabah & Sarawak
# From Paul Eggert (2014-08-12):
# The data entries here are mostly from Shanks & Pottenger, but the 1942, 1945
@@ -2768,12 +2748,14 @@ Zone Asia/Kuching 7:21:20 - LMT 1926 Mar
8:00 NBorneo +08/+0820 1942 Feb 16
9:00 - +09 1945 Sep 12
8:00 - +08
+Link Asia/Kuching Asia/Brunei
# Maldives
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Indian/Maldives 4:54:00 - LMT 1880 # Malé
4:54:00 - MMT 1960 # Malé Mean Time
5:00 - +05
+Link Indian/Maldives Indian/Kerguelen
# Mongolia
@@ -3608,6 +3590,7 @@ Zone Asia/Singapore 6:55:25 - LMT 1901 Jan 1
9:00 - +09 1945 Sep 12
7:30 - +0730 1982 Jan 1
8:00 - +08
+Link Asia/Singapore Asia/Kuala_Lumpur
# Spratly Is
# no information
@@ -3842,7 +3825,7 @@ Zone Asia/Damascus 2:25:12 - LMT 1920 # Dimashq
Zone Asia/Dushanbe 4:35:12 - LMT 1924 May 2
5:00 - +05 1930 Jun 21
6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s
- 5:00 1:00 +05/+06 1991 Sep 9 2:00s
+ 5:00 1:00 +06 1991 Sep 9 2:00s
5:00 - +05
# Thailand
@@ -3852,6 +3835,7 @@ Zone Asia/Bangkok 6:42:04 - LMT 1880
7:00 - +07
Link Asia/Bangkok Asia/Phnom_Penh # Cambodia
Link Asia/Bangkok Asia/Vientiane # Laos
+Link Asia/Bangkok Indian/Christmas
# Turkmenistan
# From Shanks & Pottenger.
@@ -3867,6 +3851,8 @@ Zone Asia/Ashgabat 3:53:32 - LMT 1924 May 2 # or Ashkhabad
Zone Asia/Dubai 3:41:12 - LMT 1920
4:00 - +04
Link Asia/Dubai Asia/Muscat # Oman
+Link Asia/Dubai Indian/Mahe
+Link Asia/Dubai Indian/Reunion
# Uzbekistan
# Byalokoz 1919 says Uzbekistan was 4:27:53.
@@ -3878,7 +3864,8 @@ Zone Asia/Samarkand 4:27:53 - LMT 1924 May 2
6:00 - +06 1982 Apr 1
5:00 RussiaAsia +05/+06 1992
5:00 - +05
-# Milne says Tashkent was 4:37:10.8; round to nearest.
+# Milne says Tashkent was 4:37:10.8.
+ #STDOFF 4:37:10.8
Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2
5:00 - +05 1930 Jun 21
6:00 RussiaAsia +06/+07 1991 Mar 31 2:00
@@ -3897,7 +3884,7 @@ Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2
# The English-language name of Vietnam's most populous city is "Ho Chi Minh
# City"; use Ho_Chi_Minh below to avoid a name of more than 14 characters.
-# From Paul Eggert (2014-10-21) after a heads-up from Trần Ngọc Quân:
+# From Paul Eggert (2022-07-27) after a 2014 heads-up from Trần Ngọc Quân:
# Trần Tiến Bình's authoritative book "Lịch Việt Nam: thế kỷ XX-XXI (1901-2100)"
# (Nhà xuất bản Văn Hoá - Thông Tin, Hanoi, 2005), pp 49-50,
# is quoted verbatim in:
@@ -3909,8 +3896,8 @@ Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2
# The 1906 transition was effective July 1 and standardized Indochina to
# Phù Liễn Observatory, legally 104° 17' 17" east of Paris.
# It's unclear whether this meant legal Paris Mean Time (00:09:21) or
-# the Paris Meridian (2° 20' 14.03" E); the former yields 07:06:30.1333...
-# and the latter 07:06:29.333... so either way it rounds to 07:06:30,
+# the Paris Meridian; for now guess the former and round the exact
+# 07:06:30.1333... to 07:06:30.13 as the legal spec used 66 2/3 ms precision.
# which is used below even though the modern-day Phù Liễn Observatory
# is closer to 07:06:31. Abbreviate Phù Liễn Mean Time as PLMT.
#
@@ -3937,7 +3924,8 @@ Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2
# NXB Thuận Hoá, Huế, 1995.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Asia/Ho_Chi_Minh 7:06:40 - LMT 1906 Jul 1
+ #STDOFF 7:06:30.13
+Zone Asia/Ho_Chi_Minh 7:06:30 - LMT 1906 Jul 1
7:06:30 - PLMT 1911 May 1 # Phù Liễn MT
7:00 - +07 1942 Dec 31 23:00
8:00 - +08 1945 Mar 14 23:00
diff --git a/australasia b/australasia
index 77c2c69..d6d1171 100644
--- a/australasia
+++ b/australasia
@@ -252,16 +252,10 @@ Zone Antarctica/Macquarie 0 - -00 1899 Nov
10:00 AT AE%sT
# Christmas
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Indian/Christmas 7:02:52 - LMT 1895 Feb
- 7:00 - +07
+# See Asia/Bangkok.
# Cocos (Keeling) Is
-# These islands were ruled by the Ross family from about 1830 to 1978.
-# We don't know when standard time was introduced; for now, we guess 1900.
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Indian/Cocos 6:27:40 - LMT 1900
- 6:30 - +0630
+# See Asia/Yangon.
# Fiji
@@ -478,6 +472,11 @@ Link Pacific/Guam Pacific/Saipan # N Mariana Is
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Tarawa 11:32:04 - LMT 1901 # Bairiki
12:00 - +12
+Link Pacific/Tarawa Pacific/Funafuti
+Link Pacific/Tarawa Pacific/Majuro
+Link Pacific/Tarawa Pacific/Wake
+Link Pacific/Tarawa Pacific/Wallis
+
Zone Pacific/Kanton 0 - -00 1937 Aug 31
-12:00 - -12 1979 Oct
-11:00 - -11 1994 Dec 31
@@ -491,15 +490,8 @@ Zone Pacific/Kiritimati -10:29:20 - LMT 1901
# See Pacific/Guam.
# Marshall Is
+# See Pacific/Tarawa for most locations.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Pacific/Majuro 11:24:48 - LMT 1901
- 11:00 - +11 1914 Oct
- 9:00 - +09 1919 Feb 1
- 11:00 - +11 1937
- 10:00 - +10 1941 Apr 1
- 9:00 - +09 1944 Jan 30
- 11:00 - +11 1969 Oct
- 12:00 - +12
Zone Pacific/Kwajalein 11:09:20 - LMT 1901
11:00 - +11 1937
10:00 - +10 1941 Apr 1
@@ -509,22 +501,9 @@ Zone Pacific/Kwajalein 11:09:20 - LMT 1901
12:00 - +12
# Micronesia
+# For Chuuk and Yap see Pacific/Port_Moresby.
+# For Pohnpei see Pacific/Guadalcanal.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Pacific/Chuuk -13:52:52 - LMT 1844 Dec 31
- 10:07:08 - LMT 1901
- 10:00 - +10 1914 Oct
- 9:00 - +09 1919 Feb 1
- 10:00 - +10 1941 Apr 1
- 9:00 - +09 1945 Aug
- 10:00 - +10
-Zone Pacific/Pohnpei -13:27:08 - LMT 1844 Dec 31 # Kolonia
- 10:32:52 - LMT 1901
- 11:00 - +11 1914 Oct
- 9:00 - +09 1919 Feb 1
- 11:00 - +11 1937
- 10:00 - +10 1941 Apr 1
- 9:00 - +09 1945 Aug
- 11:00 - +11
Zone Pacific/Kosrae -13:08:04 - LMT 1844 Dec 31
10:51:56 - LMT 1901
11:00 - +11 1914 Oct
@@ -594,12 +573,12 @@ Rule Chatham 2008 max - Apr Sun>=1 2:45s 0 -
Zone Pacific/Auckland 11:39:04 - LMT 1868 Nov 2
11:30 NZ NZ%sT 1946 Jan 1
12:00 NZ NZ%sT
+Link Pacific/Auckland Antarctica/McMurdo
+
Zone Pacific/Chatham 12:13:48 - LMT 1868 Nov 2
12:15 - +1215 1946 Jan 1
12:45 Chatham +1245/+1345
-Link Pacific/Auckland Antarctica/McMurdo
-
# Auckland Is
# uninhabited; Māori and Moriori, colonial settlers, pastoralists, sealers,
# and scientific personnel have wintered
@@ -658,7 +637,7 @@ Zone Pacific/Rarotonga 13:20:56 - LMT 1899 Dec 26 # Avarua
# Niue
-# See Pacific/Raratonga comments for 1952 transition.
+# See Pacific/Rarotonga comments for 1952 transition.
#
# From Tim Parenti (2021-09-13):
# Consecutive contemporaneous editions of The Air Almanac listed -11:20 for
@@ -694,6 +673,7 @@ Zone Pacific/Port_Moresby 9:48:40 - LMT 1880
9:48:32 - PMMT 1895 # Port Moresby Mean Time
10:00 - +10
Link Pacific/Port_Moresby Antarctica/DumontDUrville
+Link Pacific/Port_Moresby Pacific/Chuuk
#
# From Paul Eggert (2014-10-13):
# Base the Bougainville entry on the Arawa-Kieta region, which appears to have
@@ -821,6 +801,7 @@ Zone Pacific/Apia 12:33:04 - LMT 1892 Jul 5
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Guadalcanal 10:39:48 - LMT 1912 Oct # Honiara
11:00 - +11
+Link Pacific/Guadalcanal Pacific/Pohnpei
# Tokelau
#
@@ -861,9 +842,7 @@ Zone Pacific/Tongatapu 12:19:12 - LMT 1945 Sep 10
13:00 Tonga +13/+14
# Tuvalu
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Pacific/Funafuti 11:56:52 - LMT 1901
- 12:00 - +12
+# See Pacific/Tarawa.
# US minor outlying islands
@@ -922,9 +901,7 @@ Zone Pacific/Funafuti 11:56:52 - LMT 1901
# uninhabited since World War II; was probably like Pacific/Kiritimati
# Wake
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Pacific/Wake 11:06:28 - LMT 1901
- 12:00 - +12
+# See Pacific/Tarawa.
# Vanuatu
@@ -963,9 +940,7 @@ Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila
11:00 Vanuatu +11/+12
# Wallis and Futuna
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Pacific/Wallis 12:15:20 - LMT 1901
- 12:00 - +12
+# See Pacific/Tarawa.
###############################################################################
@@ -1283,6 +1258,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
# to have the extra hour of sunshine removed from their area." See:
# Daylight saving coming to WA in 2019. Guardian Express. 2018-04-01.
# https://www.communitynews.com.au/guardian-express/news/exclusive-daylight-savings-coming-wa-summer-2018/
+# [The article ends with "Today's date is April 1."]
# Queensland
@@ -1826,16 +1802,12 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
# "In Marshall Islands, Friday is followed by Sunday", NY Times. 1993-08-22.
# https://www.nytimes.com/1993/08/22/world/in-marshall-islands-friday-is-followed-by-sunday.html
-# From Phake Nick (2018-10-27):
-# <https://wiki.suikawiki.org/n/南洋群島の標準時> ... pointed out that
-# currently tzdata say Pacific/Kwajalein switched from GMT+11 to GMT-12 in
-# 1969 October without explanation, however an 1993 article from NYT say it
-# synchorized its day with US mainland about 40 years ago and thus the switch
-# should occur at around 1950s instead.
-#
-# From Paul Eggert (2018-11-18):
-# The NYT (actually, AP) article is vague and possibly wrong about this.
-# The article says the earlier switch was "40 years ago when the United States
+# From Paul Eggert (2022-03-31):
+# Phake Nick (2018-10-27) noted <https://wiki.suikawiki.org/n/南洋群島の標準時>'s
+# citation of a 1993 AP article published in the New York Times saying
+# Kwajalein synchronized its day with the US mainland about 40 years earlier.
+# However the AP article is vague and possibly wrong about this. The article
+# says the earlier switch was "about 40 years ago when the United States
# Army established a missile test range here". However, the Kwajalein Test
# Center was established on 1960-10-01 and was run by the US Navy. It was
# transferred to the US Army on 1964-07-01. See "Seize the High Ground"
@@ -1882,13 +1854,6 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
# Like the Ladrones (see Guam commentary), assume the Spanish East Indies
# kept American time until the Philippines switched at the end of 1844.
-# Alan Eugene Davis writes (1996-03-16),
-# "I am certain, having lived there for the past decade, that 'Truk'
-# (now properly known as Chuuk) ... is in the time zone GMT+10."
-#
-# Shanks & Pottenger write that Truk switched from UT +10 to +11
-# on 1978-10-01; ignore this for now.
-
# From Paul Eggert (1999-10-29):
# The Federated States of Micronesia Visitors Board writes in
# The Federated States of Micronesia - Visitor Information (1999-01-26)
@@ -2219,7 +2184,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
# through the third Sunday in January at 03:00, like Fiji, for now.
# From David Wade (2017-10-18):
-# In August government was disolved by the King. The current prime minister
+# In August government was dissolved by the King. The current prime minister
# continued in office in care taker mode. It is easy to see that few
# decisions will be made until elections 16th November.
#
@@ -2227,26 +2192,6 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
# For now, guess that DST is discontinued. That's what the IATA is guessing.
-# Wake
-
-# From Vernice Anderson, Personal Secretary to Philip Jessup,
-# US Ambassador At Large (oral history interview, 1971-02-02):
-#
-# Saturday, the 14th [of October, 1950] - ... The time was all the
-# more confusing at that point, because we had crossed the
-# International Date Line, thus getting two Sundays. Furthermore, we
-# discovered that Wake Island had two hours of daylight saving time
-# making calculation of time in Washington difficult if not almost
-# impossible.
-#
-# https://www.trumanlibrary.org/oralhist/andrsonv.htm
-
-# From Paul Eggert (2003-03-23):
-# We have no other report of DST in Wake Island, so omit this info for now.
-
-# See also the commentary for Micronesia.
-
-
###############################################################################
# The International Date Line
diff --git a/backward b/backward
index 7685c74..e162eeb 100644
--- a/backward
+++ b/backward
@@ -4,10 +4,15 @@
# 2009-05-17 by Arthur David Olson.
# This file provides links from old or merged timezone names to current ones.
-# Many names changed in late 1993. Several of these names are
+# Many names changed in late 1993, and many merged names moved here
+# in the period from 2013 through 2022. Several of these names are
# also present in the file 'backzone', which has data important only
# for pre-1970 timestamps and so is out of scope for tzdb proper.
+# Although this file is optional and tzdb will work if you omit it by
+# building with 'make BACKWARD=', in practice downstream users
+# typically use this file for backward compatibility.
+
# Link TARGET LINK-NAME
Link Africa/Nairobi Africa/Asmera
Link Africa/Abidjan Africa/Timbuktu
@@ -48,7 +53,7 @@ Link Asia/Thimphu Asia/Thimbu
Link Asia/Makassar Asia/Ujung_Pandang
Link Asia/Ulaanbaatar Asia/Ulan_Bator
Link Atlantic/Faroe Atlantic/Faeroe
-Link Europe/Oslo Atlantic/Jan_Mayen
+Link Europe/Berlin Atlantic/Jan_Mayen
Link Australia/Sydney Australia/ACT
Link Australia/Sydney Australia/Canberra
Link Australia/Hobart Australia/Currie
@@ -83,6 +88,7 @@ Link Africa/Cairo Egypt
Link Europe/Dublin Eire
Link Etc/UTC Etc/UCT
Link Europe/London Europe/Belfast
+Link Europe/Kyiv Europe/Kiev
Link Europe/Chisinau Europe/Tiraspol
Link Europe/London GB
Link Europe/London GB-Eire
@@ -91,7 +97,7 @@ Link Etc/GMT GMT-0
Link Etc/GMT GMT0
Link Etc/GMT Greenwich
Link Asia/Hong_Kong Hongkong
-Link Atlantic/Reykjavik Iceland
+Link Africa/Abidjan Iceland
Link Asia/Tehran Iran
Link Asia/Jerusalem Israel
Link America/Jamaica Jamaica
@@ -107,10 +113,10 @@ Link America/Denver Navajo
Link Asia/Shanghai PRC
Link Pacific/Kanton Pacific/Enderbury
Link Pacific/Honolulu Pacific/Johnston
-Link Pacific/Pohnpei Pacific/Ponape
+Link Pacific/Guadalcanal Pacific/Ponape
Link Pacific/Pago_Pago Pacific/Samoa
-Link Pacific/Chuuk Pacific/Truk
-Link Pacific/Chuuk Pacific/Yap
+Link Pacific/Port_Moresby Pacific/Truk
+Link Pacific/Port_Moresby Pacific/Yap
Link Europe/Warsaw Poland
Link Europe/Lisbon Portugal
Link Asia/Taipei ROC
diff --git a/backzone b/backzone
index 879a140..e2e124f 100644
--- a/backzone
+++ b/backzone
@@ -65,6 +65,11 @@
# Zones are sorted by zone name. Each zone is preceded by the
# name of the country that the zone is in, along with any other
# commentary and rules associated with the entry.
+# If the zone overrides links in the main data, it
+# is followed by the corresponding Link lines.
+# If the zone overrides main-data links only when building with
+# PACKRATLIST=zone.tab, it is followed by a commented-out Link line
+# that starts with "#PACKRATLIST zone.tab".
#
# As explained in the zic man page, the zone columns are:
# Zone NAME STDOFF RULES FORMAT [UNTIL]
@@ -181,6 +186,7 @@ Zone Africa/Bamako -0:32:00 - LMT 1912
0:00 - GMT 1934 Feb 26
-1:00 - -01 1960 Jun 20
0:00 - GMT
+#PACKRATLIST zone.tab Link Africa/Bamako Africa/Timbuktu
# Central African Republic
Zone Africa/Bangui 1:14:20 - LMT 1912
@@ -498,6 +504,7 @@ Zone America/Atikokan -6:06:28 - LMT 1895
-6:00 1:00 CDT 1942 Feb 9 2:00s
-6:00 Canada C%sT 1945 Sep 30 2:00
-5:00 - EST
+#PACKRATLIST zone.tab Link America/Atikokan America/Coral_Harbour
# Quebec east of Natashquan
@@ -829,6 +836,35 @@ Link Antarctica/McMurdo Antarctica/South_Pole
Zone Antarctica/Syowa 0 - -00 1957 Jan 29
3:00 - +03
+# Vostok, Antarctica
+#
+# Vostok, since 1957-12-16, temporarily closed 1994-02/1994-11
+# From Craig Mundell (1994-12-15):
+# http://quest.arc.nasa.gov/antarctica/QA/computers/Directions,Time,ZIP
+# Vostok, which is one of the Russian stations, is set on the same
+# time as Moscow, Russia.
+#
+# From Lee Hotz (2001-03-08):
+# I queried the folks at Columbia who spent the summer at Vostok and this is
+# what they had to say about time there:
+# "in the US Camp (East Camp) we have been on New Zealand (McMurdo)
+# time, which is 12 hours ahead of GMT. The Russian Station Vostok was
+# 6 hours behind that (although only 2 miles away, i.e. 6 hours ahead
+# of GMT). This is a time zone I think two hours east of Moscow. The
+# natural time zone is in between the two: 8 hours ahead of GMT."
+#
+# From Paul Eggert (2001-05-04):
+# This seems to be hopelessly confusing, so I asked Lee Hotz about it
+# in person. He said that some Antarctic locations set their local
+# time so that noon is the warmest part of the day, and that this
+# changes during the year and does not necessarily correspond to mean
+# solar noon. So the Vostok time might have been whatever the clocks
+# happened to be during their visit. So we still don't really know what time
+# it is at Vostok. But we'll guess +06.
+#
+Zone Antarctica/Vostok 0 - -00 1957 Dec 16
+ 6:00 - +06
+
# Yemen
# Milne says 2:59:54 was the meridian of the saluting battery at Aden,
# and that Yemen was at 1:55:56, the meridian of the Hagia Sophia.
@@ -867,6 +903,11 @@ Zone Asia/Bahrain 3:22:20 - LMT 1941 Jul 20 # Manamah
4:00 - +04 1972 Jun
3:00 - +03
+# Brunei
+Zone Asia/Brunei 7:39:40 - LMT 1926 Mar # Bandar Seri Begawan
+ 7:30 - +0730 1933
+ 8:00 - +08
+
# India
#
# From Paul Eggert (2014-09-06):
@@ -922,6 +963,20 @@ Zone Asia/Kashgar 5:03:56 - LMT 1928 # or Kashi or Kaxgar
5:00 - +05 1980 May
8:00 PRC C%sT
+# peninsular Malaysia
+# taken from Mok Ly Yng (2003-10-30)
+# https://web.archive.org/web/20190822231045/http://www.math.nus.edu.sg/~mathelmr/teaching/timezone.html
+# This agrees with Singapore since 1905-06-01.
+Zone Asia/Kuala_Lumpur 6:46:46 - LMT 1901 Jan 1
+ 6:55:25 - SMT 1905 Jun 1 # Singapore M.T.
+ 7:00 - +07 1933 Jan 1
+ 7:00 0:20 +0720 1936 Jan 1
+ 7:20 - +0720 1941 Sep 1
+ 7:30 - +0730 1942 Feb 16
+ 9:00 - +09 1945 Sep 12
+ 7:30 - +0730 1982 Jan 1
+ 8:00 - +08
+
# Kuwait
Zone Asia/Kuwait 3:11:56 - LMT 1950
3:00 - +03
@@ -995,6 +1050,64 @@ Zone Asia/Vientiane 6:50:24 - LMT 1906 Jul 1
# From Whitman:
Zone Atlantic/Jan_Mayen -1:00 - -01
+# Iceland
+#
+# From Adam David (1993-11-06):
+# The name of the timezone in Iceland for system / mail / news purposes is GMT.
+#
+# (1993-12-05):
+# This material is paraphrased from the 1988 edition of the University of
+# Iceland Almanak.
+#
+# From January 1st, 1908 the whole of Iceland was standardised at 1 hour
+# behind GMT. Previously, local mean solar time was used in different parts
+# of Iceland, the almanak had been based on Reykjavík mean solar time which
+# was 1 hour and 28 minutes behind GMT.
+#
+# "first day of winter" referred to [below] means the first day of the 26 weeks
+# of winter, according to the old icelandic calendar that dates back to the
+# time the norsemen first settled Iceland. The first day of winter is always
+# Saturday, but is not dependent on the Julian or Gregorian calendars.
+#
+# (1993-12-10):
+# I have a reference from the Oxford Icelandic-English dictionary for the
+# beginning of winter, which ties it to the ecclesiastical calendar (and thus
+# to the julian/gregorian calendar) over the period in question.
+# the winter begins on the Saturday next before St. Luke's day
+# (old style), or on St. Luke's day, if a Saturday.
+# St. Luke's day ought to be traceable from ecclesiastical sources. "old style"
+# might be a reference to the Julian calendar as opposed to Gregorian, or it
+# might mean something else (???).
+#
+# From Paul Eggert (2014-11-22):
+# The information below is taken from the 1988 Almanak; see
+# http://www.almanak.hi.is/klukkan.html
+#
+Rule Iceland 1917 1919 - Feb 19 23:00 1:00 -
+Rule Iceland 1917 only - Oct 21 1:00 0 -
+Rule Iceland 1918 1919 - Nov 16 1:00 0 -
+Rule Iceland 1921 only - Mar 19 23:00 1:00 -
+Rule Iceland 1921 only - Jun 23 1:00 0 -
+Rule Iceland 1939 only - Apr 29 23:00 1:00 -
+Rule Iceland 1939 only - Oct 29 2:00 0 -
+Rule Iceland 1940 only - Feb 25 2:00 1:00 -
+Rule Iceland 1940 1941 - Nov Sun>=2 1:00s 0 -
+Rule Iceland 1941 1942 - Mar Sun>=2 1:00s 1:00 -
+# 1943-1946 - first Sunday in March until first Sunday in winter
+Rule Iceland 1943 1946 - Mar Sun>=1 1:00s 1:00 -
+Rule Iceland 1942 1948 - Oct Sun>=22 1:00s 0 -
+# 1947-1967 - first Sunday in April until first Sunday in winter
+Rule Iceland 1947 1967 - Apr Sun>=1 1:00s 1:00 -
+# 1949 and 1967 Oct transitions delayed by 1 week
+Rule Iceland 1949 only - Oct 30 1:00s 0 -
+Rule Iceland 1950 1966 - Oct Sun>=22 1:00s 0 -
+Rule Iceland 1967 only - Oct 29 1:00s 0 -
+
+Zone Atlantic/Reykjavik -1:28 - LMT 1908
+ -1:00 Iceland -01/+00 1968 Apr 7 1:00s
+ 0:00 - GMT
+Link Atlantic/Reykjavik Iceland
+
# St Helena
Zone Atlantic/St_Helena -0:22:48 - LMT 1890 # Jamestown
-0:22:48 - JMT 1951 # Jamestown Mean Time
@@ -1006,6 +1119,82 @@ Zone Australia/Currie 9:35:28 - LMT 1895 Sep
10:00 Aus AE%sT 1968 Oct 15
10:00 AT AE%sT
+
+# Netherlands
+
+# Howse writes that the Netherlands' railways used GMT between 1892 and 1940,
+# but for other purposes the Netherlands used Amsterdam mean time.
+
+# However, Robert H. van Gent writes (2001-04-01):
+# Howse's statement is only correct up to 1909. From 1909-05-01 (00:00:00
+# Amsterdam mean time) onwards, the whole of the Netherlands (including
+# the Dutch railways) was required by law to observe Amsterdam mean time
+# (19 minutes 32.13 seconds ahead of GMT). This had already been the
+# common practice (except for the railways) for many decades but it was
+# not until 1909 when the Dutch government finally defined this by law.
+# On 1937-07-01 this was changed to 20 minutes (exactly) ahead of GMT and
+# was generally known as Dutch Time ("Nederlandse Tijd").
+#
+# (2001-04-08):
+# 1892-05-01 was the date when the Dutch railways were by law required to
+# observe GMT while the remainder of the Netherlands adhered to the common
+# practice of following Amsterdam mean time.
+#
+# (2001-04-09):
+# In 1835 the authorities of the province of North Holland requested the
+# municipal authorities of the towns and cities in the province to observe
+# Amsterdam mean time but I do not know in how many cases this request was
+# actually followed.
+#
+# From 1852 onwards the Dutch telegraph offices were by law required to
+# observe Amsterdam mean time. As the time signals from the observatory of
+# Leiden were also distributed by the telegraph system, I assume that most
+# places linked up with the telegraph (and railway) system automatically
+# adopted Amsterdam mean time.
+#
+# Although the early Dutch railway companies initially observed a variety
+# of times, most of them had adopted Amsterdam mean time by 1858 but it
+# was not until 1866 when they were all required by law to observe
+# Amsterdam mean time.
+
+# The data entries before 1945 are taken from
+# https://www.staff.science.uu.nl/~gent0113/wettijd/wettijd.htm
+
+# From Paul Eggert (2021-05-09):
+# I invented the abbreviations AMT for Amsterdam Mean Time and NST for
+# Netherlands Summer Time, used in the Netherlands from 1835 to 1937.
+
+Rule Neth 1916 only - May 1 0:00 1:00 NST # Netherlands Summer Time
+Rule Neth 1916 only - Oct 1 0:00 0 AMT # Amsterdam Mean Time
+Rule Neth 1917 only - Apr 16 2:00s 1:00 NST
+Rule Neth 1917 only - Sep 17 2:00s 0 AMT
+Rule Neth 1918 1921 - Apr Mon>=1 2:00s 1:00 NST
+Rule Neth 1918 1921 - Sep lastMon 2:00s 0 AMT
+Rule Neth 1922 only - Mar lastSun 2:00s 1:00 NST
+Rule Neth 1922 1936 - Oct Sun>=2 2:00s 0 AMT
+Rule Neth 1923 only - Jun Fri>=1 2:00s 1:00 NST
+Rule Neth 1924 only - Mar lastSun 2:00s 1:00 NST
+Rule Neth 1925 only - Jun Fri>=1 2:00s 1:00 NST
+# From 1926 through 1939 DST began 05-15, except that it was delayed by a week
+# in years when 05-15 fell in the Pentecost weekend.
+Rule Neth 1926 1931 - May 15 2:00s 1:00 NST
+Rule Neth 1932 only - May 22 2:00s 1:00 NST
+Rule Neth 1933 1936 - May 15 2:00s 1:00 NST
+Rule Neth 1937 only - May 22 2:00s 1:00 NST
+Rule Neth 1937 only - Jul 1 0:00 1:00 S
+Rule Neth 1937 1939 - Oct Sun>=2 2:00s 0 -
+Rule Neth 1938 1939 - May 15 2:00s 1:00 S
+Rule Neth 1945 only - Apr 2 2:00s 1:00 S
+Rule Neth 1945 only - Sep 16 2:00s 0 -
+ #STDOFF 0:19:32.13
+Zone Europe/Amsterdam 0:19:32 - LMT 1835
+ 0:19:32 Neth %s 1937 Jul 1
+ 0:20 Neth +0020/+0120 1940 May 16 0:00
+ 1:00 C-Eur CE%sT 1945 Apr 2 2:00
+ 1:00 Neth CE%sT 1977
+ 1:00 EU CE%sT
+
+
# Northern Ireland
Zone Europe/Belfast -0:23:40 - LMT 1880 Aug 2
-0:25:21 - DMT 1916 May 21 2:00
@@ -1017,6 +1206,60 @@ Zone Europe/Belfast -0:23:40 - LMT 1880 Aug 2
0:00 GB-Eire %s 1996
0:00 EU GMT/BST
+
+# Denmark
+
+# From Jesper Nørgaard Welen (2005-04-26):
+# the law [introducing standard time] was in effect from 1894-01-01....
+# The page https://www.retsinformation.dk/eli/lta/1893/83
+# confirms this, and states that the law was put forth 1893-03-29.
+#
+# The EU [actually, EEC and Euratom] treaty with effect from 1973:
+# https://www.retsinformation.dk/eli/lta/1972/21100
+#
+# This provoked a new law from 1974 to make possible summer time changes
+# in subsequent decrees with the law
+# https://www.retsinformation.dk/eli/lta/1974/223
+#
+# It seems however that no decree was set forward until 1980. I have
+# not found any decree, but in another related law, the effecting DST
+# changes are stated explicitly to be from 1980-04-06 at 02:00 to
+# 1980-09-28 at 02:00. If this is true, this differs slightly from
+# the EU rule in that DST runs to 02:00, not 03:00. We don't know
+# when Denmark began using the EU rule correctly, but we have only
+# confirmation of the 1980-time, so I presume it was correct in 1981:
+# The law is about the management of the extra hour, concerning
+# working hours reported and effect on obligatory-rest rules (which
+# was suspended on that night):
+# https://web.archive.org/web/20140104053304/https://www.retsinformation.dk/Forms/R0710.aspx?id=60267
+
+# From Jesper Nørgaard Welen (2005-06-11):
+# The Herning Folkeblad (1980-09-26) reported that the night between
+# Saturday and Sunday the clock is set back from three to two.
+
+# From Paul Eggert (2005-06-11):
+# Hence the "02:00" of the 1980 law refers to standard time, not
+# wall-clock time, and so the EU rules were in effect in 1980.
+
+Rule Denmark 1916 only - May 14 23:00 1:00 S
+Rule Denmark 1916 only - Sep 30 23:00 0 -
+Rule Denmark 1940 only - May 15 0:00 1:00 S
+Rule Denmark 1945 only - Apr 2 2:00s 1:00 S
+Rule Denmark 1945 only - Aug 15 2:00s 0 -
+Rule Denmark 1946 only - May 1 2:00s 1:00 S
+Rule Denmark 1946 only - Sep 1 2:00s 0 -
+Rule Denmark 1947 only - May 4 2:00s 1:00 S
+Rule Denmark 1947 only - Aug 10 2:00s 0 -
+Rule Denmark 1948 only - May 9 2:00s 1:00 S
+Rule Denmark 1948 only - Aug 8 2:00s 0 -
+#
+Zone Europe/Copenhagen 0:50:20 - LMT 1890
+ 0:50:20 - CMT 1894 Jan 1 # Copenhagen MT
+ 1:00 Denmark CE%sT 1942 Nov 2 2:00s
+ 1:00 C-Eur CE%sT 1945 Apr 2 2:00
+ 1:00 Denmark CE%sT 1980
+ 1:00 EU CE%sT
+
# Guernsey
# Data from Joseph S. Myers
# https://mm.icann.org/pipermail/tz/2013-September/019883.html
@@ -1072,6 +1315,86 @@ Zone Europe/Ljubljana 0:58:04 - LMT 1884
1:00 - CET 1982 Nov 27
1:00 EU CE%sT
+
+# Luxembourg
+
+# Whitman disagrees with most of these dates in minor ways;
+# go with Shanks & Pottenger.
+Rule Lux 1916 only - May 14 23:00 1:00 S
+Rule Lux 1916 only - Oct 1 1:00 0 -
+Rule Lux 1917 only - Apr 28 23:00 1:00 S
+Rule Lux 1917 only - Sep 17 1:00 0 -
+Rule Lux 1918 only - Apr Mon>=15 2:00s 1:00 S
+Rule Lux 1918 only - Sep Mon>=15 2:00s 0 -
+Rule Lux 1919 only - Mar 1 23:00 1:00 S
+Rule Lux 1919 only - Oct 5 3:00 0 -
+Rule Lux 1920 only - Feb 14 23:00 1:00 S
+Rule Lux 1920 only - Oct 24 2:00 0 -
+Rule Lux 1921 only - Mar 14 23:00 1:00 S
+Rule Lux 1921 only - Oct 26 2:00 0 -
+Rule Lux 1922 only - Mar 25 23:00 1:00 S
+Rule Lux 1922 only - Oct Sun>=2 1:00 0 -
+Rule Lux 1923 only - Apr 21 23:00 1:00 S
+Rule Lux 1923 only - Oct Sun>=2 2:00 0 -
+Rule Lux 1924 only - Mar 29 23:00 1:00 S
+Rule Lux 1924 1928 - Oct Sun>=2 1:00 0 -
+Rule Lux 1925 only - Apr 5 23:00 1:00 S
+Rule Lux 1926 only - Apr 17 23:00 1:00 S
+Rule Lux 1927 only - Apr 9 23:00 1:00 S
+Rule Lux 1928 only - Apr 14 23:00 1:00 S
+Rule Lux 1929 only - Apr 20 23:00 1:00 S
+
+Zone Europe/Luxembourg 0:24:36 - LMT 1904 Jun
+ 1:00 Lux CE%sT 1918 Nov 25
+ 0:00 Lux WE%sT 1929 Oct 6 2:00s
+ 0:00 Belgium WE%sT 1940 May 14 3:00
+ 1:00 C-Eur WE%sT 1944 Sep 18 3:00
+ 1:00 Belgium CE%sT 1977
+ 1:00 EU CE%sT
+
+# Monaco
+#
+# From Michael Deckers (2020-06-12):
+# In the "Journal de Monaco" of 1892-05-24, online at
+# https://journaldemonaco.gouv.mc/var/jdm/storage/original/application/b1c67c12c5af11b41ea888fb048e4fe8.pdf
+# we read: ...
+# [In virtue of a Sovereign Ordinance of the May 13 of the current [year],
+# legal time in the Principality will be set to, from the date of June 1,
+# 1892 onwards, to the meridian of Paris, as in France.]
+# In the "Journal de Monaco" of 1911-03-28, online at
+# https://journaldemonaco.gouv.mc/var/jdm/storage/original/application/de74ffb7db53d4f599059fe8f0ed482a.pdf
+# we read an ordinance of 1911-03-16: ...
+# [Legal time in the Principality will be set, from the date of promulgation
+# of the present ordinance, to legal time in France.... Consequently, legal
+# time will be retarded by 9 minutes and 21 seconds.]
+#
+Zone Europe/Monaco 0:29:32 - LMT 1892 Jun 1
+ 0:09:21 - PMT 1911 Mar 29 # Paris Mean Time
+ 0:00 France WE%sT 1945 Sep 16 3:00
+ 1:00 France CE%sT 1977
+ 1:00 EU CE%sT
+
+
+# Norway
+
+# http://met.no/met/met_lex/q_u/sommertid.html (2004-01) agrees with Shanks &
+# Pottenger.
+Rule Norway 1916 only - May 22 1:00 1:00 S
+Rule Norway 1916 only - Sep 30 0:00 0 -
+Rule Norway 1945 only - Apr 2 2:00s 1:00 S
+Rule Norway 1945 only - Oct 1 2:00s 0 -
+Rule Norway 1959 1964 - Mar Sun>=15 2:00s 1:00 S
+Rule Norway 1959 1965 - Sep Sun>=15 2:00s 0 -
+Rule Norway 1965 only - Apr 25 2:00s 1:00 S
+
+Zone Europe/Oslo 0:43:00 - LMT 1895 Jan 1
+ 1:00 Norway CE%sT 1940 Aug 10 23:00
+ 1:00 C-Eur CE%sT 1945 Apr 2 2:00
+ 1:00 Norway CE%sT 1980
+ 1:00 EU CE%sT
+Link Europe/Oslo Arctic/Longyearbyen
+#PACKRATLIST zone.tab Link Europe/Oslo Atlantic/Jan_Mayen
+
# Bosnia and Herzegovina
Zone Europe/Sarajevo 1:13:40 - LMT 1884
1:00 - CET 1941 Apr 18 23:00
@@ -1089,6 +1412,62 @@ Zone Europe/Skopje 1:25:44 - LMT 1884
1:00 EU CE%sT
+# Sweden
+
+# From Ivan Nilsson (2001-04-13), superseding Shanks & Pottenger:
+#
+# The law "Svensk författningssamling 1878, no 14" about standard time in 1879:
+# From the beginning of 1879 (that is 01-01 00:00) the time for all
+# places in the country is "the mean solar time for the meridian at
+# three degrees, or twelve minutes of time, to the west of the
+# meridian of the Observatory of Stockholm". The law is dated 1878-05-31.
+#
+# The observatory at that time had the meridian 18° 03' 30"
+# eastern longitude = 01:12:14 in time. Less 12 minutes gives the
+# national standard time as 01:00:14 ahead of GMT....
+#
+# About the beginning of CET in Sweden. The lawtext ("Svensk
+# författningssamling 1899, no 44") states, that "from the beginning
+# of 1900... ... the same as the mean solar time for the meridian at
+# the distance of one hour of time from the meridian of the English
+# observatory at Greenwich, or at 12 minutes 14 seconds to the west
+# from the meridian of the Observatory of Stockholm". The law is dated
+# 1899-06-16. In short: At 1900-01-01 00:00:00 the new standard time
+# in Sweden is 01:00:00 ahead of GMT.
+#
+# 1916: The lawtext ("Svensk författningssamling 1916, no 124") states
+# that "1916-05-15 is considered to begin one hour earlier". It is
+# pretty obvious that at 05-14 23:00 the clocks are set to 05-15 00:00....
+# Further the law says, that "1916-09-30 is considered to end one hour later".
+#
+# The laws regulating [DST] are available on the site of the Swedish
+# Parliament beginning with 1985 - the laws regulating 1980/1984 are
+# not available on the site (to my knowledge they are only available
+# in Swedish): <http://www.riksdagen.se/english/work/sfst.asp> (type
+# "sommartid" without the quotes in the field "Fritext" and then click
+# the Sök-button).
+#
+# (2001-05-13):
+#
+# I have now found a newspaper stating that at 1916-10-01 01:00
+# summertime the church-clocks etc were set back one hour to show
+# 1916-10-01 00:00 standard time. The article also reports that some
+# people thought the switch to standard time would take place already
+# at 1916-10-01 00:00 summer time, but they had to wait for another
+# hour before the event took place.
+#
+# Source: The newspaper "Dagens Nyheter", 1916-10-01, page 7 upper left.
+
+# An extra-special abbreviation style is SET for Swedish Time (svensk
+# normaltid) 1879-1899, 3° west of the Stockholm Observatory.
+
+Zone Europe/Stockholm 1:12:12 - LMT 1879 Jan 1
+ 1:00:14 - SET 1900 Jan 1 # Swedish Time
+ 1:00 - CET 1916 May 14 23:00
+ 1:00 1:00 CEST 1916 Oct 1 1:00
+ 1:00 - CET 1980
+ 1:00 EU CE%sT
+
# Moldova / Transnistria
Zone Europe/Tiraspol 1:58:32 - LMT 1880
@@ -1102,6 +1481,15 @@ Zone Europe/Tiraspol 1:58:32 - LMT 1880
3:00 Russia MSK/MSD
# Liechtenstein
+
+# From Paul Eggert (2022-07-21):
+# Shanks & Pottenger say Vaduz is like Zurich starting June 1894.
+
+# From Alois Treindl (2019-07-04):
+# I was able to access the online archive of the Vaduz paper Vaterland ...
+# I could confirm from the paper that Liechtenstein did in fact follow
+# the same DST in 1941 and 1942 as Switzerland did.
+
Zone Europe/Vaduz 0:38:04 - LMT 1894 Jun
1:00 Swiss CE%sT 1981
1:00 EU CE%sT
@@ -1120,14 +1508,87 @@ Zone Indian/Antananarivo 3:10:04 - LMT 1911 Jul
3:00 1:00 EAST 1954 May 29 23:00s
3:00 - EAT
+# Christmas
+Zone Indian/Christmas 7:02:52 - LMT 1895 Feb
+ 7:00 - +07
+
+# Cocos (Keeling) Is
+# These islands were ruled by the Ross family from about 1830 to 1978.
+# We don't know when standard time was introduced; for now, we guess 1900.
+Zone Indian/Cocos 6:27:40 - LMT 1900
+ 6:30 - +0630
+
# Comoros
Zone Indian/Comoro 2:53:04 - LMT 1911 Jul # Moroni, Gran Comoro
3:00 - EAT
+# Kerguelen
+Zone Indian/Kerguelen 0 - -00 1950 # Port-aux-Français
+ 5:00 - +05
+
+# Seychelles
+#
+# From P Chan (2020-11-27):
+# Standard Time was adopted on 1907-01-01.
+#
+# Standard Time Ordinance (Chapter 237)
+# The Laws of Seychelles in Force on the 31st December, 1971, Vol. 6, p 571
+# https://books.google.com/books?id=efE-AQAAIAAJ&pg=PA571
+#
+# From Tim Parenti (2020-12-05):
+# A footnote on https://books.google.com/books?id=DYdDAQAAMAAJ&pg=PA1689
+# confirms that Ordinance No. 9 of 1906 "was brought into force on the 1st
+# January, 1907."
+
+Zone Indian/Mahe 3:41:48 - LMT 1907 Jan 1 # Victoria
+ 4:00 - +04
+# From Paul Eggert (2001-05-30):
+# Aldabra, Farquhar, and Desroches, originally dependencies of the
+# Seychelles, were transferred to the British Indian Ocean Territory
+# in 1965 and returned to Seychelles control in 1976. We don't know
+# whether this affected their time zone, so omit this for now.
+# Possibly the islands were uninhabited.
+
+
# Mayotte
Zone Indian/Mayotte 3:00:56 - LMT 1911 Jul # Mamoutzou
3:00 - EAT
+# Réunion
+Zone Indian/Reunion 3:41:52 - LMT 1911 Jun # Saint-Denis
+ 4:00 - +04
+#
+# Scattered Islands (Îles Éparses) administered from Réunion are as follows.
+# The following information about them is taken from
+# Îles Éparses (<http://www.outre-mer.gouv.fr/domtom/ile.htm>, 1997-07-22,
+# in French; no longer available as of 1999-08-17).
+# We have no info about their time zone histories.
+#
+# Bassas da India - uninhabited
+# Europa Island - inhabited from 1905 to 1910 by two families
+# Glorioso Is - inhabited until at least 1958
+# Juan de Nova - uninhabited
+# Tromelin - inhabited until at least 1958
+
+# Micronesia
+# Also see Pacific/Pohnpei and commentary for Micronesia in 'australasia'.
+#
+# From Paul Eggert (2018-11-18):
+# Alan Eugene Davis writes (1996-03-16),
+# "I am certain, having lived there for the past decade, that 'Truk'
+# (now properly known as Chuuk) ... is in the time zone GMT+10."
+# Shanks & Pottenger write that Truk switched from UT +10 to +11
+# on 1978-10-01; ignore this for now.
+Zone Pacific/Chuuk -13:52:52 - LMT 1844 Dec 31
+ 10:07:08 - LMT 1901
+ 10:00 - +10 1914 Oct
+ 9:00 - +09 1919 Feb 1
+ 10:00 - +10 1941 Apr 1
+ 9:00 - +09 1945 Aug
+ 10:00 - +10
+Link Pacific/Chuuk Pacific/Truk
+Link Pacific/Chuuk Pacific/Yap
+
# Phoenix Islands, Kiribati
# From Paul Eggert (2021-05-27):
# Enderbury was inhabited 1860/1880s to mine guano, and 1938-03-06/1942-02-09
@@ -1140,9 +1601,23 @@ Zone Pacific/Enderbury 0 - -00 1860
-12:00 - -12 1942 Feb 9
0 - -00
+# Tuvalu
+Zone Pacific/Funafuti 11:56:52 - LMT 1901
+ 12:00 - +12
+
# Johnston
Zone Pacific/Johnston -10:00 - HST
+# Marshall Is
+Zone Pacific/Majuro 11:24:48 - LMT 1901
+ 11:00 - +11 1914 Oct
+ 9:00 - +09 1919 Feb 1
+ 11:00 - +11 1937
+ 10:00 - +10 1941 Apr 1
+ 9:00 - +09 1944 Jan 30
+ 11:00 - +11 1969 Oct
+ 12:00 - +12
+
# Midway
#
# From Mark Brader (2005-01-23):
@@ -1160,6 +1635,18 @@ Zone Pacific/Midway -11:49:28 - LMT 1901
-11:00 1:00 -10 1956 Sep 2
-11:00 - -11
+# Micronesia
+# Also see Pacific/Chuuk and commentary for Micronesia in 'australasia'.
+Zone Pacific/Pohnpei -13:27:08 - LMT 1844 Dec 31 # Kolonia
+ 10:32:52 - LMT 1901
+ 11:00 - +11 1914 Oct
+ 9:00 - +09 1919 Feb 1
+ 11:00 - +11 1937
+ 10:00 - +10 1941 Apr 1
+ 9:00 - +09 1945 Aug
+ 11:00 - +11
+Link Pacific/Pohnpei Pacific/Ponape
+
# N Mariana Is
Zone Pacific/Saipan -14:17:00 - LMT 1844 Dec 31
9:43:00 - LMT 1901
@@ -1167,6 +1654,33 @@ Zone Pacific/Saipan -14:17:00 - LMT 1844 Dec 31
10:00 - +10 2000 Dec 23
10:00 - ChST # Chamorro Standard Time
+
+# Wake
+
+# From Vernice Anderson, Personal Secretary to Philip Jessup,
+# US Ambassador At Large (oral history interview, 1971-02-02):
+#
+# Saturday, the 14th [of October, 1950] - ... The time was all the
+# more confusing at that point, because we had crossed the
+# International Date Line, thus getting two Sundays. Furthermore, we
+# discovered that Wake Island had two hours of daylight saving time
+# making calculation of time in Washington difficult if not almost
+# impossible.
+#
+# https://www.trumanlibrary.org/oralhist/andrsonv.htm
+
+# From Paul Eggert (2003-03-23):
+# We have no other report of DST in Wake Island, so omit this info for now.
+
+# Also see commentary for Micronesia in 'australasia'.
+Zone Pacific/Wake 11:06:28 - LMT 1901
+ 12:00 - +12
+
+
+# Wallis and Futuna
+Zone Pacific/Wallis 12:15:20 - LMT 1901
+ 12:00 - +12
+
# Local Variables:
# coding: utf-8
# End:
diff --git a/calendars b/calendars
index 8bc7062..f4ed9e4 100644
--- a/calendars
+++ b/calendars
@@ -71,7 +71,7 @@ kalenderväsen" by Lars-Olof Lodén (1968).
Grotefend's data
-From: "Michael Palmer" [with one obvious typo fixed]
+From: "Michael Palmer" [with two obvious typos fixed]
Subject: Re: Gregorian Calendar (was Re: Another FHC related question
Newsgroups: soc.genealogy.german
Date: Tue, 9 Feb 1999 02:32:48 -800
@@ -142,7 +142,7 @@ Gregorian calendar:
31 Dec 1700/
12 Jan 1701 - Friesland, Groningen, Zürich, Bern, Basel, Geneva,
- Turgau, and Schaffhausen
+ Thurgau, and Schaffhausen
1724 - Glarus, Appenzell, and the city of St. Gallen
diff --git a/date.c b/date.c
index b04d3f2..4e4b355 100644
--- a/date.c
+++ b/date.c
@@ -31,18 +31,6 @@
#include <locale.h>
#include <stdio.h>
-/*
-** The two things date knows about time are. . .
-*/
-
-#ifndef TM_YEAR_BASE
-#define TM_YEAR_BASE 1900
-#endif /* !defined TM_YEAR_BASE */
-
-#ifndef SECSPERMIN
-#define SECSPERMIN 60
-#endif /* !defined SECSPERMIN */
-
#if !HAVE_POSIX_DECLS
extern char * optarg;
extern int optind;
@@ -70,9 +58,9 @@ main(const int argc, char *argv[])
setlocale(LC_ALL, "");
#endif /* defined(LC_ALL) */
#if HAVE_GETTEXT
-#ifdef TZ_DOMAINDIR
+# ifdef TZ_DOMAINDIR
bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
-#endif /* defined(TEXTDOMAINDIR) */
+# endif /* defined(TEXTDOMAINDIR) */
textdomain(TZ_DOMAIN);
#endif /* HAVE_GETTEXT */
t = time(NULL);
@@ -132,7 +120,7 @@ dogmt(void)
register int from;
register int to;
register int n;
- static char tzegmt0[] = "TZ=GMT0";
+ static char tzeutc0[] = "TZ=UTC0";
for (n = 0; environ[n] != NULL; ++n)
continue;
@@ -143,7 +131,7 @@ dogmt(void)
exit(retval);
}
to = 0;
- fakeenv[to++] = tzegmt0;
+ fakeenv[to++] = tzeutc0;
for (from = 1; environ[from] != NULL; ++from)
if (strncmp(environ[from], "TZ=", 3) != 0)
fakeenv[to++] = environ[from];
@@ -192,8 +180,6 @@ display(char const *format, time_t now)
}
}
-#define INCR 1024
-
static void
timeout(FILE *fp, char const *format, struct tm const *tmp)
{
@@ -201,6 +187,7 @@ timeout(FILE *fp, char const *format, struct tm const *tmp)
size_t result;
size_t size;
struct tm tm;
+ int INCR = 1024;
if (!tmp) {
fprintf(stderr, _("date: error: time out of range\n"));
diff --git a/etcetera b/etcetera
index 1dc7411..a7e0eb4 100644
--- a/etcetera
+++ b/etcetera
@@ -17,12 +17,16 @@
# behind GMT but uses the completely misleading abbreviation "GMT".
Zone Etc/GMT 0 - GMT
+
+# The following zone is used by tzcode functions like gmtime,
+# which load the "UTC" file to handle seconds properly.
Zone Etc/UTC 0 - UTC
# The following link uses older naming conventions,
# but it belongs here, not in the file 'backward',
-# as functions like gmtime load the "GMT" file to handle leap seconds properly.
-# We want this to work even on installations that omit the other older names.
+# as it is needed for tzcode releases through 2022a,
+# where functions like gmtime load "GMT" instead of the "Etc/UTC".
+# We want this to work even on installations that omit 'backward'.
Link Etc/GMT GMT
Link Etc/UTC Etc/Universal
diff --git a/europe b/europe
index 208585d..c3a3cc4 100644
--- a/europe
+++ b/europe
@@ -303,8 +303,7 @@
# UT-00:25:22 and cites the International Telegraph Bureau. As it is
# not clear that there was any practical significance to the change
# from UT-00:25:22 to UT-00:25:21.1 in civil timekeeping, omit this
-# transition for now and just use the latter value, omitting its
-# fraction since our format cannot represent fractions.
+# transition for now and just use the latter value.
# "Countess Markievicz ... claimed that the [1916] abolition of Dublin Mean Time
# was among various actions undertaken by the 'English' government that
@@ -500,7 +499,7 @@ Rule GB-Eire 1990 1995 - Oct Sun>=22 1:00u 0 GMT
# Use Europe/London for Jersey, Guernsey, and the Isle of Man.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Europe/London -0:01:15 - LMT 1847 Dec 1 0:00s
+Zone Europe/London -0:01:15 - LMT 1847 Dec 1
0:00 GB-Eire %s 1968 Oct 27
1:00 - BST 1971 Oct 31 2:00u
0:00 GB-Eire %s 1996
@@ -538,7 +537,8 @@ Rule Eire 1990 1995 - Oct Sun>=22 1:00u -1:00 -
Rule Eire 1996 max - Oct lastSun 1:00u -1:00 -
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Europe/Dublin -0:25:00 - LMT 1880 Aug 2
+ #STDOFF -0:25:21.1
+Zone Europe/Dublin -0:25:21 - LMT 1880 Aug 2
-0:25:21 - DMT 1916 May 21 2:00s
-0:25:21 1:00 IST 1916 Oct 1 2:00s
0:00 GB-Eire %s 1921 Dec 6 # independence
@@ -961,6 +961,8 @@ Zone Europe/Brussels 0:17:30 - LMT 1880
1:00 C-Eur CE%sT 1944 Sep 3
1:00 Belgium CE%sT 1977
1:00 EU CE%sT
+Link Europe/Brussels Europe/Amsterdam
+Link Europe/Brussels Europe/Luxembourg
# Bosnia and Herzegovina
# See Europe/Belgrade.
@@ -1023,62 +1025,12 @@ Zone Europe/Prague 0:57:44 - LMT 1850
# End of rearguard section.
1:00 Czech CE%sT 1979
1:00 EU CE%sT
-# Use Europe/Prague also for Slovakia.
+Link Europe/Prague Europe/Bratislava
-# Denmark, Faroe Islands, and Greenland
-# From Jesper Nørgaard Welen (2005-04-26):
-# the law [introducing standard time] was in effect from 1894-01-01....
-# The page https://www.retsinformation.dk/eli/lta/1893/83
-# confirms this, and states that the law was put forth 1893-03-29.
-#
-# The EU [actually, EEC and Euratom] treaty with effect from 1973:
-# https://www.retsinformation.dk/eli/lta/1972/21100
-#
-# This provoked a new law from 1974 to make possible summer time changes
-# in subsequent decrees with the law
-# https://www.retsinformation.dk/eli/lta/1974/223
-#
-# It seems however that no decree was set forward until 1980. I have
-# not found any decree, but in another related law, the effecting DST
-# changes are stated explicitly to be from 1980-04-06 at 02:00 to
-# 1980-09-28 at 02:00. If this is true, this differs slightly from
-# the EU rule in that DST runs to 02:00, not 03:00. We don't know
-# when Denmark began using the EU rule correctly, but we have only
-# confirmation of the 1980-time, so I presume it was correct in 1981:
-# The law is about the management of the extra hour, concerning
-# working hours reported and effect on obligatory-rest rules (which
-# was suspended on that night):
-# https://web.archive.org/web/20140104053304/https://www.retsinformation.dk/Forms/R0710.aspx?id=60267
-
-# From Jesper Nørgaard Welen (2005-06-11):
-# The Herning Folkeblad (1980-09-26) reported that the night between
-# Saturday and Sunday the clock is set back from three to two.
-
-# From Paul Eggert (2005-06-11):
-# Hence the "02:00" of the 1980 law refers to standard time, not
-# wall-clock time, and so the EU rules were in effect in 1980.
+# Denmark, Faroe Islands, and Greenland
+# For Denmark see Europe/Berlin.
-# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
-Rule Denmark 1916 only - May 14 23:00 1:00 S
-Rule Denmark 1916 only - Sep 30 23:00 0 -
-Rule Denmark 1940 only - May 15 0:00 1:00 S
-Rule Denmark 1945 only - Apr 2 2:00s 1:00 S
-Rule Denmark 1945 only - Aug 15 2:00s 0 -
-Rule Denmark 1946 only - May 1 2:00s 1:00 S
-Rule Denmark 1946 only - Sep 1 2:00s 0 -
-Rule Denmark 1947 only - May 4 2:00s 1:00 S
-Rule Denmark 1947 only - Aug 10 2:00s 0 -
-Rule Denmark 1948 only - May 9 2:00s 1:00 S
-Rule Denmark 1948 only - Aug 8 2:00s 0 -
-#
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Europe/Copenhagen 0:50:20 - LMT 1890
- 0:50:20 - CMT 1894 Jan 1 # Copenhagen MT
- 1:00 Denmark CE%sT 1942 Nov 2 2:00s
- 1:00 C-Eur CE%sT 1945 Apr 2 2:00
- 1:00 Denmark CE%sT 1980
- 1:00 EU CE%sT
Zone Atlantic/Faroe -0:27:04 - LMT 1908 Jan 11 # Tórshavn
0:00 - WET 1981
0:00 EU WE%sT
@@ -1298,10 +1250,10 @@ Rule Finland 1942 only - Oct 4 1:00 0 -
Rule Finland 1981 1982 - Mar lastSun 2:00 1:00 S
Rule Finland 1981 1982 - Sep lastSun 3:00 0 -
-# Milne says Helsinki (Helsingfors) time was 1:39:49.2 (official document);
-# round to nearest.
+# Milne says Helsinki (Helsingfors) time was 1:39:49.2 (official document).
# Zone NAME STDOFF RULES FORMAT [UNTIL]
+ #STDOFF 1:39:49.2
Zone Europe/Helsinki 1:39:49 - LMT 1878 May 31
1:39:49 - HMT 1921 May # Helsinki Mean Time
2:00 Finland EE%sT 1983
@@ -1448,6 +1400,7 @@ Zone Europe/Paris 0:09:21 - LMT 1891 Mar 16
0:00 France WE%sT 1945 Sep 16 3:00
1:00 France CE%sT 1977
1:00 EU CE%sT
+Link Europe/Paris Europe/Monaco
# Germany
@@ -1491,21 +1444,11 @@ Zone Europe/Berlin 0:53:28 - LMT 1893 Apr
1:00 SovietZone CE%sT 1946
1:00 Germany CE%sT 1980
1:00 EU CE%sT
+Link Europe/Berlin Arctic/Longyearbyen
+Link Europe/Berlin Europe/Copenhagen
+Link Europe/Berlin Europe/Oslo
+Link Europe/Berlin Europe/Stockholm
-# From Tobias Conradi (2011-09-12):
-# Büsingen <http://www.buesingen.de>, surrounded by the Swiss canton
-# Schaffhausen, did not start observing DST in 1980 as the rest of DE
-# (West Germany at that time) and DD (East Germany at that time) did.
-# DD merged into DE, the area is currently covered by code DE in ISO 3166-1,
-# which in turn is covered by the zone Europe/Berlin.
-#
-# Source for the time in Büsingen 1980:
-# http://www.srf.ch/player/video?id=c012c029-03b7-4c2b-9164-aa5902cd58d3
-
-# From Arthur David Olson (2012-03-03):
-# Büsingen and Zurich have shared clocks since 1970.
-
-Link Europe/Zurich Europe/Busingen
# Georgia
# Please see the "asia" file for Asia/Tbilisi.
@@ -1514,7 +1457,7 @@ Link Europe/Zurich Europe/Busingen
# Gibraltar
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Europe/Gibraltar -0:21:24 - LMT 1880 Aug 2 0:00s
+Zone Europe/Gibraltar -0:21:24 - LMT 1880 Aug 2
0:00 GB-Eire %s 1957 Apr 14 2:00
1:00 - CET 1982
1:00 EU CE%sT
@@ -1625,62 +1568,7 @@ Zone Europe/Budapest 1:16:20 - LMT 1890 Nov 1
1:00 EU CE%sT
# Iceland
-#
-# From Adam David (1993-11-06):
-# The name of the timezone in Iceland for system / mail / news purposes is GMT.
-#
-# (1993-12-05):
-# This material is paraphrased from the 1988 edition of the University of
-# Iceland Almanak.
-#
-# From January 1st, 1908 the whole of Iceland was standardised at 1 hour
-# behind GMT. Previously, local mean solar time was used in different parts
-# of Iceland, the almanak had been based on Reykjavík mean solar time which
-# was 1 hour and 28 minutes behind GMT.
-#
-# "first day of winter" referred to [below] means the first day of the 26 weeks
-# of winter, according to the old icelandic calendar that dates back to the
-# time the norsemen first settled Iceland. The first day of winter is always
-# Saturday, but is not dependent on the Julian or Gregorian calendars.
-#
-# (1993-12-10):
-# I have a reference from the Oxford Icelandic-English dictionary for the
-# beginning of winter, which ties it to the ecclesiastical calendar (and thus
-# to the julian/gregorian calendar) over the period in question.
-# the winter begins on the Saturday next before St. Luke's day
-# (old style), or on St. Luke's day, if a Saturday.
-# St. Luke's day ought to be traceable from ecclesiastical sources. "old style"
-# might be a reference to the Julian calendar as opposed to Gregorian, or it
-# might mean something else (???).
-#
-# From Paul Eggert (2014-11-22):
-# The information below is taken from the 1988 Almanak; see
-# http://www.almanak.hi.is/klukkan.html
-#
-# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
-Rule Iceland 1917 1919 - Feb 19 23:00 1:00 -
-Rule Iceland 1917 only - Oct 21 1:00 0 -
-Rule Iceland 1918 1919 - Nov 16 1:00 0 -
-Rule Iceland 1921 only - Mar 19 23:00 1:00 -
-Rule Iceland 1921 only - Jun 23 1:00 0 -
-Rule Iceland 1939 only - Apr 29 23:00 1:00 -
-Rule Iceland 1939 only - Oct 29 2:00 0 -
-Rule Iceland 1940 only - Feb 25 2:00 1:00 -
-Rule Iceland 1940 1941 - Nov Sun>=2 1:00s 0 -
-Rule Iceland 1941 1942 - Mar Sun>=2 1:00s 1:00 -
-# 1943-1946 - first Sunday in March until first Sunday in winter
-Rule Iceland 1943 1946 - Mar Sun>=1 1:00s 1:00 -
-Rule Iceland 1942 1948 - Oct Sun>=22 1:00s 0 -
-# 1947-1967 - first Sunday in April until first Sunday in winter
-Rule Iceland 1947 1967 - Apr Sun>=1 1:00s 1:00 -
-# 1949 and 1967 Oct transitions delayed by 1 week
-Rule Iceland 1949 only - Oct 30 1:00s 0 -
-Rule Iceland 1950 1966 - Oct Sun>=22 1:00s 0 -
-Rule Iceland 1967 only - Oct 29 1:00s 0 -
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Atlantic/Reykjavik -1:28 - LMT 1908
- -1:00 Iceland -01/+00 1968 Apr 7 1:00s
- 0:00 - GMT
+# See Africa/Abidjan.
# Italy
#
@@ -1796,19 +1684,19 @@ Rule Italy 1978 only - Oct 1 0:00s 0 -
Rule Italy 1979 only - Sep 30 0:00s 0 -
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Rome 0:49:56 - LMT 1866 Dec 12
- 0:49:56 - RMT 1893 Oct 31 23:49:56 # Rome Mean
+ 0:49:56 - RMT 1893 Oct 31 23:00u # 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
+Link Europe/Rome Europe/Vatican
+Link Europe/Rome Europe/San_Marino
+
# Kosovo
# See Europe/Belgrade.
-Link Europe/Rome Europe/Vatican
-Link Europe/Rome Europe/San_Marino
-
# Latvia
# From Liene Kanepe (1998-09-17):
@@ -1892,16 +1780,7 @@ Zone Europe/Riga 1:36:34 - LMT 1880
2:00 EU EE%sT
# Liechtenstein
-
-# From Paul Eggert (2013-09-09):
-# Shanks & Pottenger say Vaduz is like Zurich.
-
-# From Alois Treindl (2019-07-04):
-# I was able to access the online archive of the Vaduz paper Vaterland ...
-# I could confirm from the paper that Liechtenstein did in fact follow
-# the same DST in 1941 and 1942 as Switzerland did.
-
-Link Europe/Zurich Europe/Vaduz
+# See Europe/Zurich.
# Lithuania
@@ -1957,40 +1836,7 @@ Zone Europe/Vilnius 1:41:16 - LMT 1880
2:00 EU EE%sT
# Luxembourg
-# Whitman disagrees with most of these dates in minor ways;
-# go with Shanks & Pottenger.
-# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
-Rule Lux 1916 only - May 14 23:00 1:00 S
-Rule Lux 1916 only - Oct 1 1:00 0 -
-Rule Lux 1917 only - Apr 28 23:00 1:00 S
-Rule Lux 1917 only - Sep 17 1:00 0 -
-Rule Lux 1918 only - Apr Mon>=15 2:00s 1:00 S
-Rule Lux 1918 only - Sep Mon>=15 2:00s 0 -
-Rule Lux 1919 only - Mar 1 23:00 1:00 S
-Rule Lux 1919 only - Oct 5 3:00 0 -
-Rule Lux 1920 only - Feb 14 23:00 1:00 S
-Rule Lux 1920 only - Oct 24 2:00 0 -
-Rule Lux 1921 only - Mar 14 23:00 1:00 S
-Rule Lux 1921 only - Oct 26 2:00 0 -
-Rule Lux 1922 only - Mar 25 23:00 1:00 S
-Rule Lux 1922 only - Oct Sun>=2 1:00 0 -
-Rule Lux 1923 only - Apr 21 23:00 1:00 S
-Rule Lux 1923 only - Oct Sun>=2 2:00 0 -
-Rule Lux 1924 only - Mar 29 23:00 1:00 S
-Rule Lux 1924 1928 - Oct Sun>=2 1:00 0 -
-Rule Lux 1925 only - Apr 5 23:00 1:00 S
-Rule Lux 1926 only - Apr 17 23:00 1:00 S
-Rule Lux 1927 only - Apr 9 23:00 1:00 S
-Rule Lux 1928 only - Apr 14 23:00 1:00 S
-Rule Lux 1929 only - Apr 20 23:00 1:00 S
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Europe/Luxembourg 0:24:36 - LMT 1904 Jun
- 1:00 Lux CE%sT 1918 Nov 25
- 0:00 Lux WE%sT 1929 Oct 6 2:00s
- 0:00 Belgium WE%sT 1940 May 14 3:00
- 1:00 C-Eur WE%sT 1944 Sep 18 3:00
- 1:00 Belgium CE%sT 1977
- 1:00 EU CE%sT
+# See Europe/Brussels.
# North Macedonia
# See Europe/Belgrade.
@@ -2009,7 +1855,7 @@ Rule Malta 1975 1979 - Apr Sun>=15 2:00 1:00 S
Rule Malta 1975 1980 - Sep Sun>=15 2:00 0 -
Rule Malta 1980 only - Mar 31 2:00 1:00 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 0:00s # Valletta
+Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 # Valletta
1:00 Italy CE%sT 1973 Mar 31
1:00 Malta CE%sT 1981
1:00 EU CE%sT
@@ -2091,126 +1937,16 @@ Zone Europe/Chisinau 1:55:20 - LMT 1880
2:00 Moldova EE%sT
# Monaco
-#
-# From Michael Deckers (2020-06-12):
-# In the "Journal de Monaco" of 1892-05-24, online at
-# https://journaldemonaco.gouv.mc/var/jdm/storage/original/application/b1c67c12c5af11b41ea888fb048e4fe8.pdf
-# we read: ...
-# [In virtue of a Sovereign Ordinance of the May 13 of the current [year],
-# legal time in the Principality will be set to, from the date of June 1,
-# 1892 onwards, to the meridian of Paris, as in France.]
-# In the "Journal de Monaco" of 1911-03-28, online at
-# https://journaldemonaco.gouv.mc/var/jdm/storage/original/application/de74ffb7db53d4f599059fe8f0ed482a.pdf
-# we read an ordinance of 1911-03-16: ...
-# [Legal time in the Principality will be set, from the date of promulgation
-# of the present ordinance, to legal time in France.... Consequently, legal
-# time will be retarded by 9 minutes and 21 seconds.]
-#
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Europe/Monaco 0:29:32 - LMT 1892 Jun 1
- 0:09:21 - PMT 1911 Mar 29 # Paris Mean Time
- 0:00 France WE%sT 1945 Sep 16 3:00
- 1:00 France CE%sT 1977
- 1:00 EU CE%sT
+# See Europe/Paris.
# Montenegro
# See Europe/Belgrade.
# Netherlands
-
-# Howse writes that the Netherlands' railways used GMT between 1892 and 1940,
-# but for other purposes the Netherlands used Amsterdam mean time.
-
-# However, Robert H. van Gent writes (2001-04-01):
-# Howse's statement is only correct up to 1909. From 1909-05-01 (00:00:00
-# Amsterdam mean time) onwards, the whole of the Netherlands (including
-# the Dutch railways) was required by law to observe Amsterdam mean time
-# (19 minutes 32.13 seconds ahead of GMT). This had already been the
-# common practice (except for the railways) for many decades but it was
-# not until 1909 when the Dutch government finally defined this by law.
-# On 1937-07-01 this was changed to 20 minutes (exactly) ahead of GMT and
-# was generally known as Dutch Time ("Nederlandse Tijd").
-#
-# (2001-04-08):
-# 1892-05-01 was the date when the Dutch railways were by law required to
-# observe GMT while the remainder of the Netherlands adhered to the common
-# practice of following Amsterdam mean time.
-#
-# (2001-04-09):
-# In 1835 the authorities of the province of North Holland requested the
-# municipal authorities of the towns and cities in the province to observe
-# Amsterdam mean time but I do not know in how many cases this request was
-# actually followed.
-#
-# From 1852 onwards the Dutch telegraph offices were by law required to
-# observe Amsterdam mean time. As the time signals from the observatory of
-# Leiden were also distributed by the telegraph system, I assume that most
-# places linked up with the telegraph (and railway) system automatically
-# adopted Amsterdam mean time.
-#
-# Although the early Dutch railway companies initially observed a variety
-# of times, most of them had adopted Amsterdam mean time by 1858 but it
-# was not until 1866 when they were all required by law to observe
-# Amsterdam mean time.
-
-# The data entries before 1945 are taken from
-# https://www.staff.science.uu.nl/~gent0113/wettijd/wettijd.htm
-
-# From Paul Eggert (2021-05-09):
-# I invented the abbreviations AMT for Amsterdam Mean Time and NST for
-# Netherlands Summer Time, used in the Netherlands from 1835 to 1937.
-
-# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
-Rule Neth 1916 only - May 1 0:00 1:00 NST # Netherlands Summer Time
-Rule Neth 1916 only - Oct 1 0:00 0 AMT # Amsterdam Mean Time
-Rule Neth 1917 only - Apr 16 2:00s 1:00 NST
-Rule Neth 1917 only - Sep 17 2:00s 0 AMT
-Rule Neth 1918 1921 - Apr Mon>=1 2:00s 1:00 NST
-Rule Neth 1918 1921 - Sep lastMon 2:00s 0 AMT
-Rule Neth 1922 only - Mar lastSun 2:00s 1:00 NST
-Rule Neth 1922 1936 - Oct Sun>=2 2:00s 0 AMT
-Rule Neth 1923 only - Jun Fri>=1 2:00s 1:00 NST
-Rule Neth 1924 only - Mar lastSun 2:00s 1:00 NST
-Rule Neth 1925 only - Jun Fri>=1 2:00s 1:00 NST
-# From 1926 through 1939 DST began 05-15, except that it was delayed by a week
-# in years when 05-15 fell in the Pentecost weekend.
-Rule Neth 1926 1931 - May 15 2:00s 1:00 NST
-Rule Neth 1932 only - May 22 2:00s 1:00 NST
-Rule Neth 1933 1936 - May 15 2:00s 1:00 NST
-Rule Neth 1937 only - May 22 2:00s 1:00 NST
-Rule Neth 1937 only - Jul 1 0:00 1:00 S
-Rule Neth 1937 1939 - Oct Sun>=2 2:00s 0 -
-Rule Neth 1938 1939 - May 15 2:00s 1:00 S
-Rule Neth 1945 only - Apr 2 2:00s 1:00 S
-Rule Neth 1945 only - Sep 16 2:00s 0 -
-#
-# Amsterdam Mean Time was +00:19:32.13, but the .13 is omitted
-# below because the current format requires STDOFF to be an integer.
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Europe/Amsterdam 0:19:32 - LMT 1835
- 0:19:32 Neth %s 1937 Jul 1
- 0:20 Neth +0020/+0120 1940 May 16 0:00
- 1:00 C-Eur CE%sT 1945 Apr 2 2:00
- 1:00 Neth CE%sT 1977
- 1:00 EU CE%sT
+# See Europe/Brussels.
# Norway
-# http://met.no/met/met_lex/q_u/sommertid.html (2004-01) agrees with Shanks &
-# Pottenger.
-# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
-Rule Norway 1916 only - May 22 1:00 1:00 S
-Rule Norway 1916 only - Sep 30 0:00 0 -
-Rule Norway 1945 only - Apr 2 2:00s 1:00 S
-Rule Norway 1945 only - Oct 1 2:00s 0 -
-Rule Norway 1959 1964 - Mar Sun>=15 2:00s 1:00 S
-Rule Norway 1959 1965 - Sep Sun>=15 2:00s 0 -
-Rule Norway 1965 only - Apr 25 2:00s 1:00 S
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Europe/Oslo 0:43:00 - LMT 1895 Jan 1
- 1:00 Norway CE%sT 1940 Aug 10 23:00
- 1:00 C-Eur CE%sT 1945 Apr 2 2:00
- 1:00 Norway CE%sT 1980
- 1:00 EU CE%sT
+# See Europe/Berlin.
# Svalbard & Jan Mayen
@@ -2257,9 +1993,9 @@ Zone Europe/Oslo 0:43:00 - LMT 1895 Jan 1
# the German armed forces at the Svalbard weather station code-named
# Haudegen did not surrender to the Allies until September 1945.
#
-# All these events predate our cutoff date of 1970, so use Europe/Oslo
+# All these events predate our cutoff date of 1970, so use Europe/Berlin
# for these regions.
-Link Europe/Oslo Arctic/Longyearbyen
+
# Poland
@@ -2313,7 +2049,6 @@ Zone Europe/Warsaw 1:24:00 - LMT 1880
# According to a Portuguese decree (1911-05-26)
# https://dre.pt/application/dir/pdf1sdip/1911/05/12500/23132313.pdf
# Lisbon was at -0:36:44.68, but switched to GMT on 1912-01-01 at 00:00.
-# Round the old offset to -0:36:45. This agrees with Willett....
#
# From Michael Deckers (2018-02-15):
# article 5 [of the 1911 decree; Deckers's translation] ...:
@@ -2400,6 +2135,7 @@ Rule Port 1981 1982 - Mar lastSun 1:00s 1:00 S
Rule Port 1983 only - Mar lastSun 2:00s 1:00 S
#
# Zone NAME STDOFF RULES FORMAT [UNTIL]
+ #STDOFF -0:36:44.68
Zone Europe/Lisbon -0:36:45 - LMT 1884
-0:36:45 - LMT 1912 Jan 1 0:00u # Lisbon MT
0:00 Port WE%sT 1966 Apr 3 2:00
@@ -2408,9 +2144,13 @@ Zone Europe/Lisbon -0:36:45 - LMT 1884
0:00 W-Eur WE%sT 1992 Sep 27 1:00s
1:00 EU CE%sT 1996 Mar 31 1:00u
0:00 EU WE%sT
-# This Zone can be simplified once we assume zic %z.
Zone Atlantic/Azores -1:42:40 - LMT 1884 # Ponta Delgada
-1:54:32 - HMT 1912 Jan 1 2:00u # Horta MT
+# Vanguard section, for zic and other parsers that support %z.
+# -2:00 Port %z 1966 Apr 3 2:00
+# -1:00 Port %z 1983 Sep 25 1:00s
+# -1:00 W-Eur %z 1992 Sep 27 1:00s
+# Rearguard section, for parsers lacking %z; see ziguard.awk.
-2:00 Port -02/-01 1942 Apr 25 22:00s
-2:00 Port +00 1942 Aug 15 22:00s
-2:00 Port -02/-01 1943 Apr 17 22:00s
@@ -2422,11 +2162,14 @@ Zone Atlantic/Azores -1:42:40 - LMT 1884 # Ponta Delgada
-2:00 Port -02/-01 1966 Apr 3 2:00
-1:00 Port -01/+00 1983 Sep 25 1:00s
-1:00 W-Eur -01/+00 1992 Sep 27 1:00s
+# End of rearguard section.
0:00 EU WE%sT 1993 Mar 28 1:00u
-1:00 EU -01/+00
-# This Zone can be simplified once we assume zic %z.
Zone Atlantic/Madeira -1:07:36 - LMT 1884 # Funchal
-1:07:36 - FMT 1912 Jan 1 1:00u # Funchal MT
+# Vanguard section, for zic and other parsers that support %z.
+# -1:00 Port %z 1966 Apr 3 2:00
+# Rearguard section, for parsers lacking %z; see ziguard.awk.
-1:00 Port -01/+00 1942 Apr 25 22:00s
-1:00 Port +01 1942 Aug 15 22:00s
-1:00 Port -01/+00 1943 Apr 17 22:00s
@@ -2436,6 +2179,7 @@ Zone Atlantic/Madeira -1:07:36 - LMT 1884 # Funchal
-1:00 Port -01/+00 1945 Apr 21 22:00s
-1:00 Port +01 1945 Aug 25 22:00s
-1:00 Port -01/+00 1966 Apr 3 2:00
+# End of rearguard section.
0:00 Port WE%sT 1983 Sep 25 1:00s
0:00 EU WE%sT
@@ -2854,20 +2598,19 @@ Zone Europe/Simferopol 2:16:24 - LMT 1880
2:00 - EET 1992 Mar 20
# Central Crimea used Moscow time 1994/1997.
#
-# From Paul Eggert (2006-03-22):
-# The _Economist_ (1994-05-28, p 45) reports that central Crimea switched
-# from Kiev to Moscow time sometime after the January 1994 elections.
+# From Paul Eggert (2022-07-21):
+# The _Economist_ (1994-05-28, p 45) reported that central Crimea switched
+# from Kyiv to Moscow time sometime after the January 1994 elections.
# Shanks (1999) says "date of change uncertain", but implies that it happened
# sometime between the 1994 DST switches. Shanks & Pottenger simply say
# 1994-09-25 03:00, but that can't be right. For now, guess it
-# changed in May.
+# changed in May. This change evidently didn't last long; see below.
2:00 C-Eur EE%sT 1994 May
-# From IATA SSIM (1994/1997), which also says that Kerch is still like Kiev.
- 3:00 E-Eur MSK/MSD 1996 Mar 31 0:00s
+# From IATA SSIM (1994/1997), which also said that Kerch is still like Kyiv.
+ 3:00 C-Eur MSK/MSD 1996 Mar 31 0:00s
3:00 1:00 MSD 1996 Oct 27 3:00s
-# IATA SSIM (1997-09) says Crimea switched to EET/EEST.
+# IATA SSIM (1997-09) said Crimea switched to EET/EEST.
# Assume it happened in March by not changing the clocks.
- 3:00 Russia MSK/MSD 1997
3:00 - MSK 1997 Mar lastSun 1:00u
# From Alexander Krivenyshev (2014-03-17):
# time change at 2:00 (2am) on March 30, 2014
@@ -3036,11 +2779,12 @@ Zone Europe/Ulyanovsk 3:13:36 - LMT 1919 Jul 1 0:00u
# Note: Effective 2005-12-01, (59) Perm Oblast and (81) Komi-Permyak
# Autonomous Okrug merged to form (90, RU-PER) Perm Krai.
-# Milne says Yekaterinburg was 4:02:32.9; round to nearest.
+# Milne says Yekaterinburg was 4:02:32.9.
# Byalokoz 1919 says its provincial time was based on Perm, at 3:45:05.
# Assume it switched on 1916-07-03, the time of the new standard.
# The 1919 and 1930 transitions are from Shanks.
+ #STDOFF 4:02:32.9
Zone Asia/Yekaterinburg 4:02:33 - LMT 1916 Jul 3
3:45:05 - PMT 1919 Jul 15 4:00
4:00 - +04 1930 Jun 21
@@ -3352,8 +3096,8 @@ Zone Asia/Vladivostok 8:47:31 - LMT 1922 Nov 15
# 14-28 **** Tomponsky District
# 14-30 **** Ust-Maysky District
-# From Arthur David Olson (2012-05-09):
-# Tomponskij and Ust'-Majskij switched from Vladivostok time to Yakutsk time
+# From Arthur David Olson (2022-03-21):
+# Tomponsky and Ust-Maysky switched from Vladivostok time to Yakutsk time
# in 2011.
# From Paul Eggert (2012-11-25):
@@ -3478,8 +3222,8 @@ Zone Asia/Srednekolymsk 10:14:52 - LMT 1924 May 2
# Asia/Ust-Nera covers parts of (14, RU-SA) Sakha (Yakutia) Republic:
# 14-22 **** Oymyakonsky District
-# From Arthur David Olson (2012-05-09):
-# Ojmyakonskij [and the Kuril Islands] switched from
+# From Arthur David Olson (2022-03-21):
+# Oymyakonsky and the Kuril Islands switched from
# Magadan time to Vladivostok time in 2011.
#
# From Tim Parenti (2014-07-06), per Alexander Krivenyshev (2014-07-02):
@@ -3553,7 +3297,7 @@ Link Europe/Belgrade Europe/Skopje # North Macedonia
Link Europe/Belgrade Europe/Zagreb # Croatia
# Slovakia
-Link Europe/Prague Europe/Bratislava
+# See Europe/Prague.
# Slovenia
# See Europe/Belgrade.
@@ -3642,7 +3386,7 @@ Rule SpainAfrica 1977 only - Sep 28 0:00 0 -
Rule SpainAfrica 1978 only - Jun 1 0:00 1:00 S
Rule SpainAfrica 1978 only - Aug 4 0:00 0 -
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Europe/Madrid -0:14:44 - LMT 1900 Dec 31 23:45:16
+Zone Europe/Madrid -0:14:44 - LMT 1901 Jan 1 0:00u
0:00 Spain WE%sT 1940 Mar 16 23:00
1:00 Spain CE%sT 1979
1:00 EU CE%sT
@@ -3664,61 +3408,7 @@ Zone Atlantic/Canary -1:01:36 - LMT 1922 Mar # Las Palmas de Gran C.
# Ignore this for now, as the Canaries are part of the EU.
# Sweden
-
-# From Ivan Nilsson (2001-04-13), superseding Shanks & Pottenger:
-#
-# The law "Svensk författningssamling 1878, no 14" about standard time in 1879:
-# From the beginning of 1879 (that is 01-01 00:00) the time for all
-# places in the country is "the mean solar time for the meridian at
-# three degrees, or twelve minutes of time, to the west of the
-# meridian of the Observatory of Stockholm". The law is dated 1878-05-31.
-#
-# The observatory at that time had the meridian 18° 03' 30"
-# eastern longitude = 01:12:14 in time. Less 12 minutes gives the
-# national standard time as 01:00:14 ahead of GMT....
-#
-# About the beginning of CET in Sweden. The lawtext ("Svensk
-# författningssamling 1899, no 44") states, that "from the beginning
-# of 1900... ... the same as the mean solar time for the meridian at
-# the distance of one hour of time from the meridian of the English
-# observatory at Greenwich, or at 12 minutes 14 seconds to the west
-# from the meridian of the Observatory of Stockholm". The law is dated
-# 1899-06-16. In short: At 1900-01-01 00:00:00 the new standard time
-# in Sweden is 01:00:00 ahead of GMT.
-#
-# 1916: The lawtext ("Svensk författningssamling 1916, no 124") states
-# that "1916-05-15 is considered to begin one hour earlier". It is
-# pretty obvious that at 05-14 23:00 the clocks are set to 05-15 00:00....
-# Further the law says, that "1916-09-30 is considered to end one hour later".
-#
-# The laws regulating [DST] are available on the site of the Swedish
-# Parliament beginning with 1985 - the laws regulating 1980/1984 are
-# not available on the site (to my knowledge they are only available
-# in Swedish): <http://www.riksdagen.se/english/work/sfst.asp> (type
-# "sommartid" without the quotes in the field "Fritext" and then click
-# the Sök-button).
-#
-# (2001-05-13):
-#
-# I have now found a newspaper stating that at 1916-10-01 01:00
-# summertime the church-clocks etc were set back one hour to show
-# 1916-10-01 00:00 standard time. The article also reports that some
-# people thought the switch to standard time would take place already
-# at 1916-10-01 00:00 summer time, but they had to wait for another
-# hour before the event took place.
-#
-# Source: The newspaper "Dagens Nyheter", 1916-10-01, page 7 upper left.
-
-# An extra-special abbreviation style is SET for Swedish Time (svensk
-# normaltid) 1879-1899, 3° west of the Stockholm Observatory.
-
-# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone Europe/Stockholm 1:12:12 - LMT 1879 Jan 1
- 1:00:14 - SET 1900 Jan 1 # Swedish Time
- 1:00 - CET 1916 May 14 23:00
- 1:00 1:00 CEST 1916 Oct 1 1:00
- 1:00 - CET 1980
- 1:00 EU CE%sT
+# See Europe/Berlin.
# Switzerland
# From Howse:
@@ -3812,6 +3502,19 @@ Zone Europe/Stockholm 1:12:12 - LMT 1879 Jan 1
# 1853-07-16, though it probably occurred at some other date in Zurich, and
# legal civil time probably changed at still some other transition date.
+# From Tobias Conradi (2011-09-12):
+# Büsingen <http://www.buesingen.de>, surrounded by the Swiss canton
+# Schaffhausen, did not start observing DST in 1980 as the rest of DE
+# (West Germany at that time) and DD (East Germany at that time) did.
+# DD merged into DE, the area is currently covered by code DE in ISO 3166-1,
+# which in turn is covered by the zone Europe/Berlin.
+#
+# Source for the time in Büsingen 1980:
+# http://www.srf.ch/player/video?id=c012c029-03b7-4c2b-9164-aa5902cd58d3
+#
+# From Arthur David Olson (2012-03-03):
+# Büsingen and Zurich have shared clocks since 1970.
+
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Swiss 1941 1942 - May Mon>=1 1:00 1:00 S
Rule Swiss 1941 1942 - Oct Mon>=1 2:00 0 -
@@ -3820,6 +3523,9 @@ Zone Europe/Zurich 0:34:08 - LMT 1853 Jul 16 # See above comment.
0:29:46 - BMT 1894 Jun # Bern Mean Time
1:00 Swiss CE%sT 1981
1:00 EU CE%sT
+Link Europe/Zurich Europe/Busingen
+Link Europe/Zurich Europe/Vaduz
+
# Turkey
@@ -4028,7 +3734,7 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
# Ukraine
#
-# From Alois Triendl (2014-03-01):
+# From Alois Treindl (2014-03-01):
# REGULATION A N O V A on March 20, 1992 N 139 ... means that from
# 1992 on, Ukraine had DST with begin time at 02:00 am, on last Sunday
# in March, and end time 03:00 am, last Sunday in September....
@@ -4088,7 +3794,7 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
# The law documents themselves are at
# http://w1.c1.rada.gov.ua/pls/zweb_n/webproc4_1?id=&pf3511=41484
-# From Vladimir in Moscow via Alois Treindl re Kiev time 1991/2 (2014-02-28):
+# From Vladimir in Moscow via Alois Treindl re Kyiv time 1991/2 (2014-02-28):
# First in Ukraine they changed Time zone from UTC+3 to UTC+2 with DST:
# 03 25 1990 02:00 -03.00 1 Time Zone 3 with DST
# 07 01 1990 02:00 -02.00 1 Time Zone 2 with DST
@@ -4116,23 +3822,23 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
# * Ukrainian Government's Resolution of 20.03.1992, No. 139.
# http://www.uazakon.com/documents/date_8u/pg_grcasa.htm
-# From Paul Eggert (2018-10-03):
+# From Paul Eggert (2022-04-12):
# As is usual in tzdb, Ukrainian zones use the most common English spellings.
-# For example, tzdb uses Europe/Kiev, as "Kiev" is the most common spelling in
-# English for Ukraine's capital, even though it is certainly wrong as a
-# transliteration of the Ukrainian "Київ". This is similar to tzdb's use of
-# Europe/Prague, which is certainly wrong as a transliteration of the Czech
-# "Praha". ("Kiev" came from old Slavic via Russian to English, and "Prague"
-# came from old Slavic via French to English, so the two cases have something
-# in common.) Admittedly English-language spelling of Ukrainian names is
-# controversial, and some day "Kyiv" may become substantially more popular in
-# English; in the meantime, stick with the traditional English "Kiev" as that
-# means less disruption for our users.
+# In particular, tzdb's name Europe/Kyiv uses the most common spelling in
+# English for Ukraine's capital. Although tzdb's former name was Europe/Kiev,
+# "Kyiv" is now more common due to widespread reporting of the current conflict.
+# Conversely, tzdb continues to use the names Europe/Uzhgorod and
+# Europe/Zaporozhye; this is similar to tzdb's use of Europe/Prague, which is
+# certainly wrong as a transliteration of the Czech "Praha".
+# English-language spelling of Ukrainian names is in flux, and
+# some day "Uzhhorod" or "Zaporizhzhia" may become substantially more
+# common in English; in the meantime, do not change these
+# English spellings as that means less disruption for our users.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-# This represents most of Ukraine. See above for the spelling of "Kiev".
-Zone Europe/Kiev 2:02:04 - LMT 1880
- 2:02:04 - KMT 1924 May 2 # Kiev Mean Time
+# This represents most of Ukraine. See above for the spelling of "Kyiv".
+Zone Europe/Kyiv 2:02:04 - LMT 1880
+ 2:02:04 - KMT 1924 May 2 # Kyiv Mean Time
2:00 - EET 1930 Jun 21
3:00 - MSK 1941 Sep 20
1:00 C-Eur CE%sT 1943 Nov 6
@@ -4155,7 +3861,7 @@ Zone Europe/Uzhgorod 1:29:12 - LMT 1890 Oct
2:00 C-Eur EE%sT 1996 May 13
2:00 EU EE%sT
# Zaporozh'ye and eastern Lugansk oblasts observed DST 1990/1991.
-# "Zaporizhia" is the transliteration of the Ukrainian name, but
+# "Zaporizhzhia" is the transliteration of the Ukrainian name, but
# "Zaporozh'ye" is more common in English. Use the common English
# spelling, except omit the apostrophe as it is not allowed in
# portable Posix file names.
diff --git a/leap-seconds.list b/leap-seconds.list
index 0f43115..5b519b7 100644
--- a/leap-seconds.list
+++ b/leap-seconds.list
@@ -204,10 +204,10 @@
# current -- the update time stamp, the data and the name of the file
# will not change.
#
-# Updated through IERS Bulletin C63
-# File expires on: 28 December 2022
+# Updated through IERS Bulletin C64
+# File expires on: 28 June 2023
#
-#@ 3881174400
+#@ 3896899200
#
2272060800 10 # 1 Jan 1972
2287785600 11 # 1 Jul 1972
@@ -252,4 +252,4 @@
# the hash line is also ignored in the
# computation.
#
-#h 732b2044 5863a938 b7e43179 1339c710 ded63837
+#h 2c413af9 124e1031 f165174 ff527c6b 756ae00b
diff --git a/leapseconds.awk b/leapseconds.awk
index b6c48bc..b6c48bc 100755..100644
--- a/leapseconds.awk
+++ b/leapseconds.awk
diff --git a/localtime.c b/localtime.c
index 913c7e8..073b096 100644
--- a/localtime.c
+++ b/localtime.c
@@ -29,28 +29,25 @@ static void unlock(void) { }
#endif
#ifndef TZ_ABBR_MAX_LEN
-#define TZ_ABBR_MAX_LEN 16
+# define TZ_ABBR_MAX_LEN 16
#endif /* !defined TZ_ABBR_MAX_LEN */
#ifndef TZ_ABBR_CHAR_SET
-#define TZ_ABBR_CHAR_SET \
+# define TZ_ABBR_CHAR_SET \
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
#endif /* !defined TZ_ABBR_CHAR_SET */
#ifndef TZ_ABBR_ERR_CHAR
-#define TZ_ABBR_ERR_CHAR '_'
+# define TZ_ABBR_ERR_CHAR '_'
#endif /* !defined TZ_ABBR_ERR_CHAR */
/*
-** SunOS 4.1.1 headers lack O_BINARY.
+** Support non-POSIX platforms that distinguish between text and binary files.
*/
-#ifdef O_BINARY
-#define OPEN_MODE (O_RDONLY | O_BINARY)
-#endif /* defined O_BINARY */
#ifndef O_BINARY
-#define OPEN_MODE O_RDONLY
-#endif /* !defined O_BINARY */
+# define O_BINARY 0
+#endif
#ifndef WILDABBR
/*
@@ -72,12 +69,13 @@ static void unlock(void) { }
** manual page of what this "time zone abbreviation" means (doing this so
** that tzname[0] has the "normal" length of three characters).
*/
-#define WILDABBR " "
+# define WILDABBR " "
#endif /* !defined WILDABBR */
static const char wildabbr[] = WILDABBR;
-static const char gmt[] = "GMT";
+static char const etc_utc[] = "Etc/UTC";
+static char const *utc = etc_utc + sizeof "Etc/" - 1;
/*
** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
@@ -86,7 +84,7 @@ static const char gmt[] = "GMT";
** for historical reasons, US rules are a common default.
*/
#ifndef TZDEFRULESTRING
-#define TZDEFRULESTRING ",M3.2.0,M11.1.0"
+# define TZDEFRULESTRING ",M3.2.0,M11.1.0"
#endif
struct ttinfo { /* time type information */
@@ -102,9 +100,6 @@ struct lsinfo { /* leap second information */
int_fast32_t ls_corr; /* correction to apply */
};
-#define SMALLEST(a, b) (((a) < (b)) ? (a) : (b))
-#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
-
/* This abbreviation means local time is unspecified. */
static char const UNSPEC[] = "-00";
@@ -112,13 +107,13 @@ static char const UNSPEC[] = "-00";
This needs to be at least 1 for null termination in case the input
data isn't properly terminated, and it also needs to be big enough
for ttunspecified to work without crashing. */
-enum { CHARS_EXTRA = BIGGEST(sizeof UNSPEC, 2) - 1 };
+enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 };
#ifdef TZNAME_MAX
-#define MY_TZNAME_MAX TZNAME_MAX
+# define MY_TZNAME_MAX TZNAME_MAX
#endif /* defined TZNAME_MAX */
#ifndef TZNAME_MAX
-#define MY_TZNAME_MAX 255
+# define MY_TZNAME_MAX 255
#endif /* !defined TZNAME_MAX */
struct state {
@@ -131,9 +126,8 @@ struct state {
time_t ats[TZ_MAX_TIMES];
unsigned char types[TZ_MAX_TIMES];
struct ttinfo ttis[TZ_MAX_TYPES];
- char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + CHARS_EXTRA,
- sizeof gmt),
- (2 * (MY_TZNAME_MAX + 1)))];
+ char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"),
+ 2 * (MY_TZNAME_MAX + 1))];
struct lsinfo lsis[TZ_MAX_LEAPS];
/* The time type to use for early times or if no transitions.
@@ -175,12 +169,12 @@ static struct state * gmtptr;
#ifndef ALL_STATE
static struct state lclmem;
static struct state gmtmem;
-#define lclptr (&lclmem)
-#define gmtptr (&gmtmem)
+static struct state *const lclptr = &lclmem;
+static struct state *const gmtptr = &gmtmem;
#endif /* State Farm */
#ifndef TZ_STRLEN_MAX
-#define TZ_STRLEN_MAX 255
+# define TZ_STRLEN_MAX 255
#endif /* !defined TZ_STRLEN_MAX */
static char lcl_TZname[TZ_STRLEN_MAX + 1];
@@ -292,42 +286,58 @@ update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp)
#endif
}
+/* If STDDST_MASK indicates that SP's TYPE provides useful info,
+ update tzname, timezone, and/or altzone and return STDDST_MASK,
+ diminished by the provided info if it is a specified local time.
+ Otherwise, return STDDST_MASK. See settzname for STDDST_MASK. */
+static int
+may_update_tzname_etc(int stddst_mask, struct state *sp, int type)
+{
+ struct ttinfo *ttisp = &sp->ttis[type];
+ int this_bit = 1 << ttisp->tt_isdst;
+ if (stddst_mask & this_bit) {
+ update_tzname_etc(sp, ttisp);
+ if (!ttunspecified(sp, type))
+ return stddst_mask & ~this_bit;
+ }
+ return stddst_mask;
+}
+
static void
settzname(void)
{
register struct state * const sp = lclptr;
register int i;
+ /* If STDDST_MASK & 1 we need info about a standard time.
+ If STDDST_MASK & 2 we need info about a daylight saving time.
+ When STDDST_MASK becomes zero we can stop looking. */
+ int stddst_mask = 0;
+
#if HAVE_TZNAME
- tzname[0] = tzname[1] = (char *) (sp ? wildabbr : gmt);
+ tzname[0] = tzname[1] = (char *) (sp ? wildabbr : utc);
+ stddst_mask = 3;
#endif
#if USG_COMPAT
- daylight = 0;
timezone = 0;
+ stddst_mask = 3;
#endif
#if ALTZONE
altzone = 0;
+ stddst_mask |= 2;
#endif
- if (sp == NULL) {
- return;
- }
/*
** And to get the latest time zone abbreviations into tzname. . .
*/
- for (i = 0; i < sp->typecnt; ++i) {
- register const struct ttinfo * const ttisp = &sp->ttis[i];
- update_tzname_etc(sp, ttisp);
+ if (sp) {
+ for (i = sp->timecnt - 1; stddst_mask && 0 <= i; i--)
+ stddst_mask = may_update_tzname_etc(stddst_mask, sp, sp->types[i]);
+ for (i = sp->typecnt - 1; stddst_mask && 0 <= i; i--)
+ stddst_mask = may_update_tzname_etc(stddst_mask, sp, i);
}
- for (i = 0; i < sp->timecnt; ++i) {
- register const struct ttinfo * const ttisp =
- &sp->ttis[
- sp->types[i]];
- update_tzname_etc(sp, ttisp);
#if USG_COMPAT
- if (ttisp->tt_isdst)
- daylight = 1;
+ daylight = stddst_mask >> 1 ^ 1;
#endif
- }
}
static void
@@ -378,8 +388,7 @@ union local_storage {
} u;
/* The file name to be opened. */
- char fullname[BIGGEST(sizeof(struct file_analysis),
- sizeof tzdirslash + 1024)];
+ char fullname[max(sizeof(struct file_analysis), sizeof tzdirslash + 1024)];
};
/* Load tz data from the file named NAME into *SP. Read extended
@@ -440,7 +449,7 @@ tzloadbody(char const *name, struct state *sp, bool doextend,
}
if (doaccess && access(name, R_OK) != 0)
return errno;
- fid = open(name, OPEN_MODE);
+ fid = open(name, O_RDONLY | O_BINARY);
if (fid < 0)
return errno;
@@ -1385,8 +1394,8 @@ tzparse(const char *name, struct state *sp, struct state *basep)
static void
gmtload(struct state *const sp)
{
- if (tzload(gmt, sp, true) != 0)
- tzparse("GMT0", sp, NULL);
+ if (tzload(etc_utc, sp, true) != 0)
+ tzparse("UTC0", sp, NULL);
}
/* Initialize *SP to a value appropriate for the TZ setting NAME.
@@ -1404,7 +1413,7 @@ zoneinit(struct state *sp, char const *name)
sp->charcnt = 0;
sp->goback = sp->goahead = false;
init_ttinfo(&sp->ttis[0], 0, false, 0);
- strcpy(sp->chars, gmt);
+ strcpy(sp->chars, utc);
sp->defaulttype = 0;
return 0;
} else {
@@ -1513,7 +1522,7 @@ tzfree(timezone_t sp)
** set the applicable parts of tzname, timezone and altzone;
** however, it's OK to omit this step if the timezone is POSIX-compatible,
** since in that case tzset should have already done this step correctly.
-** SETNAME's type is intfast32_t for compatibility with gmtsub,
+** SETNAME's type is int_fast32_t for compatibility with gmtsub,
** but it is actually a boolean and its value should be 0 or 1.
*/
@@ -1658,7 +1667,7 @@ gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset,
** but this is no time for a treasure hunt.
*/
tmp->TM_ZONE = ((char *)
- (offset ? wildabbr : gmtptr ? gmtptr->chars : gmt));
+ (offset ? wildabbr : gmtptr ? gmtptr->chars : utc));
#endif /* defined TM_ZONE */
return result;
}
@@ -1849,7 +1858,7 @@ ctime_r(const time_t *timep, char *buf)
*/
#ifndef WRONG
-#define WRONG (-1)
+# define WRONG (-1)
#endif /* !defined WRONG */
/*
@@ -2070,10 +2079,10 @@ time2sub(struct tm *const tmp,
&& (yourtm.TM_GMTOFF < 0
? (-SECSPERDAY <= yourtm.TM_GMTOFF
&& (mytm.TM_GMTOFF <=
- (SMALLEST(INT_FAST32_MAX, LONG_MAX)
+ (min(INT_FAST32_MAX, LONG_MAX)
+ yourtm.TM_GMTOFF)))
: (yourtm.TM_GMTOFF <= SECSPERDAY
- && ((BIGGEST(INT_FAST32_MIN, LONG_MIN)
+ && ((max(INT_FAST32_MIN, LONG_MIN)
+ yourtm.TM_GMTOFF)
<= mytm.TM_GMTOFF)))) {
/* MYTM matches YOURTM except with the wrong UT offset.
diff --git a/northamerica b/northamerica
index fb5c94b..13fb064 100644
--- a/northamerica
+++ b/northamerica
@@ -344,8 +344,7 @@ Zone PST8PDT -8:00 US P%sT
# From Paul Eggert (2014-09-06):
# Monthly Notices of the Royal Astronomical Society 44, 4 (1884-02-08), 208
# says that New York City Hall time was 3 minutes 58.4 seconds fast of
-# Eastern time (i.e., -4:56:01.6) just before the 1883 switch. Round to the
-# nearest second.
+# Eastern time (i.e., -4:56:01.6) just before the 1883 switch.
# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule NYC 1920 only - Mar lastSun 2:00 1:00 D
@@ -354,7 +353,8 @@ Rule NYC 1921 1966 - Apr lastSun 2:00 1:00 D
Rule NYC 1921 1954 - Sep lastSun 2:00 0 S
Rule NYC 1955 1966 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/New_York -4:56:02 - LMT 1883 Nov 18 12:03:58
+ #STDOFF -4:56:01.6
+Zone America/New_York -4:56:02 - LMT 1883 Nov 18 17:00u
-5:00 US E%sT 1920
-5:00 NYC E%sT 1942
-5:00 US E%sT 1946
@@ -2818,7 +2818,7 @@ Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 0:11:56
# Barbados
-# For 1899 Milne gives -3:58:29.2; round that.
+# For 1899 Milne gives -3:58:29.2.
# From P Chan (2020-12-09 and 2020-12-11):
# Standard time of GMT-4 was adopted in 1911.
@@ -2862,6 +2862,7 @@ Rule Barb 1978 1980 - Apr Sun>=15 2:00 1:00 D
Rule Barb 1979 only - Sep 30 2:00 0 S
Rule Barb 1980 only - Sep 25 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
+ #STDOFF -3:58:29.2
Zone America/Barbados -3:58:29 - LMT 1911 Aug 28 # Bridgetown
-4:00 Barb A%sT 1944
-4:00 Barb AST/-0330 1945
@@ -2922,10 +2923,10 @@ Zone America/Belize -5:52:48 - LMT 1912 Apr 1
# Bermuda
-# From Paul Eggert (2020-11-24):
+# From Paul Eggert (2022-07-27):
# For 1899 Milne gives -4:19:18.3 as the meridian of the clock tower,
# Bermuda dockyard, Ireland I. This agrees with standard offset given in the
-# Daylight Saving Act, 1917 cited below. Round that to the nearest second.
+# Daylight Saving Act, 1917 cited below.
# It is not known when this time became standard for Bermuda; guess 1890.
# The transition to -04 was specified by:
# 1930: The Time Zone Act, 1929 (1929: No. 39) [1929-11-08]
@@ -3020,6 +3021,7 @@ Rule Bermuda 1956 only - May Sun>=22 2:00 1:00 D
Rule Bermuda 1956 only - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
+ #STDOFF -4:19:18.3
Zone Atlantic/Bermuda -4:19:18 - LMT 1890 # Hamilton
-4:19:18 Bermuda BMT/BST 1930 Jan 1 2:00
-4:00 Bermuda A%sT 1974 Apr 28 2:00
@@ -3034,7 +3036,7 @@ Zone Atlantic/Bermuda -4:19:18 - LMT 1890 # Hamilton
# Costa Rica
-# Milne gives -5:36:13.3 as San José mean time; round to nearest.
+# Milne gives -5:36:13.3 as San José mean time.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule CR 1979 1980 - Feb lastSun 0:00 1:00 D
@@ -3046,6 +3048,7 @@ Rule CR 1991 only - Jul 1 0:00 0 S
Rule CR 1992 only - Mar 15 0:00 0 S
# There are too many San Josés elsewhere, so we'll use 'Costa Rica'.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
+ #STDOFF -5:36:13.3
Zone America/Costa_Rica -5:36:13 - LMT 1890 # San José
-5:36:13 - SJMT 1921 Jan 15 # San José Mean Time
-6:00 CR C%sT
@@ -3468,7 +3471,7 @@ Zone America/Tegucigalpa -5:48:52 - LMT 1921 Apr
# Jamaica
# Shanks & Pottenger give -5:07:12, but Milne records -5:07:10.41 from an
# unspecified official document, and says "This time is used throughout the
-# island". Go with Milne. Round to the nearest second as required by zic.
+# island". Go with Milne.
#
# Shanks & Pottenger give April 28 for the 1974 spring-forward transition, but
# Lance Neita writes that Prime Minister Michael Manley decreed it January 5.
@@ -3481,6 +3484,7 @@ Zone America/Tegucigalpa -5:48:52 - LMT 1921 Apr
# http://www.jamaicaobserver.com/columns/The-politician-in-all-of-us_17573647
#
# Zone NAME STDOFF RULES FORMAT [UNTIL]
+ #STDOFF -5:07:10.41
Zone America/Jamaica -5:07:10 - LMT 1890 # Kingston
-5:07:10 - KMT 1912 Feb # Kingston Mean Time
-5:00 - EST 1974
@@ -3678,6 +3682,7 @@ Zone America/Miquelon -3:44:40 - LMT 1911 May 15 # St Pierre
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Grand_Turk -4:44:32 - LMT 1890
+ #STDOFF -5:07:10.41
-5:07:10 - KMT 1912 Feb # Kingston Mean Time
-5:00 - EST 1979
-5:00 US E%sT 2015 Mar 8 2:00
diff --git a/private.h b/private.h
index e8c0942..9b9389f 100644
--- a/private.h
+++ b/private.h
@@ -36,7 +36,7 @@
*/
#ifndef HAVE_DECL_ASCTIME_R
-#define HAVE_DECL_ASCTIME_R 1
+# define HAVE_DECL_ASCTIME_R 1
#endif
#if !defined HAVE_GENERIC && defined __has_extension
@@ -55,51 +55,51 @@
#endif
#ifndef HAVE_GETTEXT
-#define HAVE_GETTEXT 0
+# define HAVE_GETTEXT 0
#endif /* !defined HAVE_GETTEXT */
#ifndef HAVE_INCOMPATIBLE_CTIME_R
-#define HAVE_INCOMPATIBLE_CTIME_R 0
+# define HAVE_INCOMPATIBLE_CTIME_R 0
#endif
#ifndef HAVE_LINK
-#define HAVE_LINK 1
+# define HAVE_LINK 1
#endif /* !defined HAVE_LINK */
#ifndef HAVE_MALLOC_ERRNO
-#define HAVE_MALLOC_ERRNO 1
+# define HAVE_MALLOC_ERRNO 1
#endif
#ifndef HAVE_POSIX_DECLS
-#define HAVE_POSIX_DECLS 1
+# define HAVE_POSIX_DECLS 1
#endif
#ifndef HAVE_STDBOOL_H
-#define HAVE_STDBOOL_H (199901 <= __STDC_VERSION__)
+# define HAVE_STDBOOL_H (199901 <= __STDC_VERSION__)
#endif
#ifndef HAVE_STRDUP
-#define HAVE_STRDUP 1
+# define HAVE_STRDUP 1
#endif
#ifndef HAVE_STRTOLL
-#define HAVE_STRTOLL 1
+# define HAVE_STRTOLL 1
#endif
#ifndef HAVE_SYMLINK
-#define HAVE_SYMLINK 1
+# define HAVE_SYMLINK 1
#endif /* !defined HAVE_SYMLINK */
#ifndef HAVE_SYS_STAT_H
-#define HAVE_SYS_STAT_H 1
+# define HAVE_SYS_STAT_H 1
#endif /* !defined HAVE_SYS_STAT_H */
#ifndef HAVE_UNISTD_H
-#define HAVE_UNISTD_H 1
+# define HAVE_UNISTD_H 1
#endif /* !defined HAVE_UNISTD_H */
#ifndef HAVE_UTMPX_H
-#define HAVE_UTMPX_H 1
+# define HAVE_UTMPX_H 1
#endif /* !defined HAVE_UTMPX_H */
#ifndef NETBSD_INSPIRED
@@ -107,8 +107,8 @@
#endif
#if HAVE_INCOMPATIBLE_CTIME_R
-#define asctime_r _incompatible_asctime_r
-#define ctime_r _incompatible_ctime_r
+# define asctime_r _incompatible_asctime_r
+# define ctime_r _incompatible_ctime_r
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
/* Enable tm_gmtoff, tm_zone, and environ on GNUish systems. */
@@ -182,11 +182,11 @@
#endif
#if HAVE_GETTEXT
-#include <libintl.h>
+# include <libintl.h>
#endif /* HAVE_GETTEXT */
#if HAVE_UNISTD_H
-#include <unistd.h> /* for R_OK, and other POSIX goodness */
+# include <unistd.h> /* for R_OK, and other POSIX goodness */
#endif /* HAVE_UNISTD_H */
#ifndef HAVE_STRFTIME_L
@@ -222,7 +222,7 @@
#endif
#ifndef R_OK
-#define R_OK 4
+# define R_OK 4
#endif /* !defined R_OK */
/*
@@ -232,14 +232,14 @@
** stdint.h, even with pre-C99 compilers.
*/
#ifndef HAVE_STDINT_H
-#define HAVE_STDINT_H \
+# define HAVE_STDINT_H \
(199901 <= __STDC_VERSION__ \
- || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
+ || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
|| __CYGWIN__ || INTMAX_MAX)
#endif /* !defined HAVE_STDINT_H */
#if HAVE_STDINT_H
-#include <stdint.h>
+# include <stdint.h>
#endif /* !HAVE_STDINT_H */
#ifndef HAVE_INTTYPES_H
@@ -358,14 +358,14 @@ typedef unsigned long uintmax_t;
#endif
#ifndef INT32_MAX
-#define INT32_MAX 0x7fffffff
+# define INT32_MAX 0x7fffffff
#endif /* !defined INT32_MAX */
#ifndef INT32_MIN
-#define INT32_MIN (-1 - INT32_MAX)
+# define INT32_MIN (-1 - INT32_MAX)
#endif /* !defined INT32_MIN */
#ifndef SIZE_MAX
-#define SIZE_MAX ((size_t) -1)
+# define SIZE_MAX ((size_t) -1)
#endif
#if 3 <= __GNUC__
@@ -632,6 +632,11 @@ time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE;
#define TYPE_SIGNED(type) (((type) -1) < 0)
#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
+/* Minimum and maximum of two values. Use lower case to avoid
+ naming clashes with standard include files. */
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
/* Max and min values of the integer type T, of which only the bottom
B bits are used, and where the highest-order used bit is considered
to be a sign bit if T is signed. */
@@ -737,47 +742,55 @@ char *ctime_r(time_t const *, char *);
/* Handy macros that are independent of tzfile implementation. */
-#define SECSPERMIN 60
-#define MINSPERHOUR 60
-#define HOURSPERDAY 24
-#define DAYSPERWEEK 7
-#define DAYSPERNYEAR 365
-#define DAYSPERLYEAR 366
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+enum {
+ SECSPERMIN = 60,
+ MINSPERHOUR = 60,
+ SECSPERHOUR = SECSPERMIN * MINSPERHOUR,
+ HOURSPERDAY = 24,
+ DAYSPERWEEK = 7,
+ DAYSPERNYEAR = 365,
+ DAYSPERLYEAR = DAYSPERNYEAR + 1,
+ MONSPERYEAR = 12,
+ YEARSPERREPEAT = 400 /* years before a Gregorian repeat */
+};
+
#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
-#define MONSPERYEAR 12
-#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
#define DAYSPERREPEAT ((int_fast32_t) 400 * 365 + 100 - 4 + 1)
#define SECSPERREPEAT ((int_fast64_t) DAYSPERREPEAT * SECSPERDAY)
#define AVGSECSPERYEAR (SECSPERREPEAT / YEARSPERREPEAT)
-#define TM_SUNDAY 0
-#define TM_MONDAY 1
-#define TM_TUESDAY 2
-#define TM_WEDNESDAY 3
-#define TM_THURSDAY 4
-#define TM_FRIDAY 5
-#define TM_SATURDAY 6
-
-#define TM_JANUARY 0
-#define TM_FEBRUARY 1
-#define TM_MARCH 2
-#define TM_APRIL 3
-#define TM_MAY 4
-#define TM_JUNE 5
-#define TM_JULY 6
-#define TM_AUGUST 7
-#define TM_SEPTEMBER 8
-#define TM_OCTOBER 9
-#define TM_NOVEMBER 10
-#define TM_DECEMBER 11
-
-#define TM_YEAR_BASE 1900
-#define TM_WDAY_BASE TM_MONDAY
-
-#define EPOCH_YEAR 1970
-#define EPOCH_WDAY TM_THURSDAY
+enum {
+ TM_SUNDAY,
+ TM_MONDAY,
+ TM_TUESDAY,
+ TM_WEDNESDAY,
+ TM_THURSDAY,
+ TM_FRIDAY,
+ TM_SATURDAY
+};
+
+enum {
+ TM_JANUARY,
+ TM_FEBRUARY,
+ TM_MARCH,
+ TM_APRIL,
+ TM_MAY,
+ TM_JUNE,
+ TM_JULY,
+ TM_AUGUST,
+ TM_SEPTEMBER,
+ TM_OCTOBER,
+ TM_NOVEMBER,
+ TM_DECEMBER
+};
+
+enum {
+ TM_YEAR_BASE = 1900,
+ TM_WDAY_BASE = TM_MONDAY,
+ EPOCH_YEAR = 1970,
+ EPOCH_WDAY = TM_THURSDAY
+};
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
diff --git a/southamerica b/southamerica
index c6249cd..2f2c873 100644
--- a/southamerica
+++ b/southamerica
@@ -400,6 +400,7 @@ Rule Arg 2008 only - Oct Sun>=15 0:00 1:00 -
#
# Buenos Aires (BA), Capital Federal (CF),
Zone America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 Oct 31
+ #STDOFF -4:16:48.25
-4:16:48 - CMT 1920 May # Córdoba Mean Time
-4:00 - -04 1930 Dec
-4:00 Arg -04/-03 1969 Oct 5
@@ -417,6 +418,7 @@ Zone America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 Oct 31
# - Santiago del Estero switched to -4:00 on 1991-04-01,
# then to -3:00 on 1991-04-26.
#
+ #STDOFF -4:16:48.25
Zone America/Argentina/Cordoba -4:16:48 - LMT 1894 Oct 31
-4:16:48 - CMT 1920 May
-4:00 - -04 1930 Dec
@@ -429,6 +431,7 @@ Zone America/Argentina/Cordoba -4:16:48 - LMT 1894 Oct 31
#
# Salta (SA), La Pampa (LP), Neuquén (NQ), Rio Negro (RN)
Zone America/Argentina/Salta -4:21:40 - LMT 1894 Oct 31
+ #STDOFF -4:16:48.25
-4:16:48 - CMT 1920 May
-4:00 - -04 1930 Dec
-4:00 Arg -04/-03 1969 Oct 5
@@ -441,6 +444,7 @@ Zone America/Argentina/Salta -4:21:40 - LMT 1894 Oct 31
#
# Tucumán (TM)
Zone America/Argentina/Tucuman -4:20:52 - LMT 1894 Oct 31
+ #STDOFF -4:16:48.25
-4:16:48 - CMT 1920 May
-4:00 - -04 1930 Dec
-4:00 Arg -04/-03 1969 Oct 5
@@ -454,6 +458,7 @@ Zone America/Argentina/Tucuman -4:20:52 - LMT 1894 Oct 31
#
# La Rioja (LR)
Zone America/Argentina/La_Rioja -4:27:24 - LMT 1894 Oct 31
+ #STDOFF -4:16:48.25
-4:16:48 - CMT 1920 May
-4:00 - -04 1930 Dec
-4:00 Arg -04/-03 1969 Oct 5
@@ -468,6 +473,7 @@ Zone America/Argentina/La_Rioja -4:27:24 - LMT 1894 Oct 31
#
# San Juan (SJ)
Zone America/Argentina/San_Juan -4:34:04 - LMT 1894 Oct 31
+ #STDOFF -4:16:48.25
-4:16:48 - CMT 1920 May
-4:00 - -04 1930 Dec
-4:00 Arg -04/-03 1969 Oct 5
@@ -482,6 +488,7 @@ Zone America/Argentina/San_Juan -4:34:04 - LMT 1894 Oct 31
#
# Jujuy (JY)
Zone America/Argentina/Jujuy -4:21:12 - LMT 1894 Oct 31
+ #STDOFF -4:16:48.25
-4:16:48 - CMT 1920 May
-4:00 - -04 1930 Dec
-4:00 Arg -04/-03 1969 Oct 5
@@ -497,6 +504,7 @@ Zone America/Argentina/Jujuy -4:21:12 - LMT 1894 Oct 31
#
# Catamarca (CT), Chubut (CH)
Zone America/Argentina/Catamarca -4:23:08 - LMT 1894 Oct 31
+ #STDOFF -4:16:48.25
-4:16:48 - CMT 1920 May
-4:00 - -04 1930 Dec
-4:00 Arg -04/-03 1969 Oct 5
@@ -511,6 +519,7 @@ Zone America/Argentina/Catamarca -4:23:08 - LMT 1894 Oct 31
#
# Mendoza (MZ)
Zone America/Argentina/Mendoza -4:35:16 - LMT 1894 Oct 31
+ #STDOFF -4:16:48.25
-4:16:48 - CMT 1920 May
-4:00 - -04 1930 Dec
-4:00 Arg -04/-03 1969 Oct 5
@@ -533,6 +542,7 @@ Rule SanLuis 2008 2009 - Mar Sun>=8 0:00 0 -
Rule SanLuis 2007 2008 - Oct Sun>=8 0:00 1:00 -
Zone America/Argentina/San_Luis -4:25:24 - LMT 1894 Oct 31
+ #STDOFF -4:16:48.25
-4:16:48 - CMT 1920 May
-4:00 - -04 1930 Dec
-4:00 Arg -04/-03 1969 Oct 5
@@ -551,6 +561,7 @@ Zone America/Argentina/San_Luis -4:25:24 - LMT 1894 Oct 31
#
# Santa Cruz (SC)
Zone America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 Oct 31
+ #STDOFF -4:16:48.25
-4:16:48 - CMT 1920 May
-4:00 - -04 1930 Dec
-4:00 Arg -04/-03 1969 Oct 5
@@ -563,6 +574,7 @@ Zone America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 Oct 31
#
# Tierra del Fuego, Antártida e Islas del Atlántico Sur (TF)
Zone America/Argentina/Ushuaia -4:33:12 - LMT 1894 Oct 31
+ #STDOFF -4:16:48.25
-4:16:48 - CMT 1920 May
-4:00 - -04 1930 Dec
-4:00 Arg -04/-03 1969 Oct 5
@@ -645,7 +657,7 @@ Zone America/La_Paz -4:32:36 - LMT 1890
# From Rodrigo Severo (2004-10-04):
# It's just the biannual change made necessary by the much hyped, supposedly
-# modern Brazilian eletronic voting machines which, apparently, can't deal
+# modern Brazilian ... voting machines which, apparently, can't deal
# with a time change between the first and the second rounds of the elections.
# From Steffen Thorsen (2007-09-20):
@@ -1141,7 +1153,7 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
# this is known to work for DST transitions starting in 2008 and
# may well be true for earlier transitions.
-# From Tim Parenti (2022-03-15):
+# From Tim Parenti (2022-07-06):
# For a brief period of roughly six weeks in 1946, DST was only observed on an
# emergency basis in specific regions of central Chile; namely, "the national
# territory between the provinces of Coquimbo and Concepción, inclusive".
@@ -1159,7 +1171,14 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
# Law Number 8,522, promulgated 1946-08-27, reunified Chilean clocks at their
# new "Summer Time" of -04, reckoned as that of "the meridian of the
# Astronomical Observatory of Lo Espejo, advanced by 42 minutes and 45
-# seconds".
+# seconds". Although this law specified the new Summer Time to start on 1
+# September each year, a special "transitional article" started it a few days
+# early, as soon as the law took effect. As the law was to take force "from
+# the date of its publication in the 'Diario Oficial', which happened the
+# following day, presume the change took place in Santiago and its environs
+# from 24:00 -03 to 23:00 -04 on Wednesday 1946-08-28. Although this was a
+# no-op for wall clocks in the north and south of the country, put their formal
+# start to DST an hour later when they reached 24:00 -04.
# https://www.diariooficial.interior.gob.cl/versiones-anteriores/do-h/19460828/#page/1
# After a brief "Winter Time" stint at -05 beginning 1947-04-01, Law Number
# 8,777, promulgated 1947-05-17, established year-round -04 "from 23:00 on the
@@ -1279,11 +1298,19 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
# So we extend the new rules on Saturdays at 24:00 mainland time indefinitely.
# From Juan Correa (2019-02-04):
# http://www.diariooficial.interior.gob.cl/publicaciones/2018/11/23/42212/01/1498738.pdf
-# From Paul Eggert (2019-09-01):
-# The above says the Magallanes exception expires 2022-04-02 at 24:00,
-# so in theory, they will revert to -04/-03 after that.
-# For now, assume that they will not revert,
-# since they have extended the expiration date once already.
+
+# From Juan Correa (2022-04-02):
+# I found there was a decree published last Thursday that will keep
+# Magallanes region to UTC -3 "indefinitely". The decree is available at
+# https://www.diariooficial.interior.gob.cl/publicaciones/2022/03/31/43217-B/01/2108910.pdf
+
+# From Juan Correa (2022-08-09):
+# the Internal Affairs Ministry (Ministerio del Interior) informed DST
+# for America/Santiago will start on midnight of September 11th;
+# and will end on April 1st, 2023. Magallanes region (America/Punta_Arenas)
+# will keep UTC -3 "indefinitely"... This is because on September 4th
+# we will have a voting whether to approve a new Constitution....
+# https://www.interior.gob.cl/noticias/2022/08/09/comunicado-el-proximo-sabado-10-de-septiembre-los-relojes-se-deben-adelantar-una-hora/
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Chile 1927 1931 - Sep 1 0:00 1:00 -
@@ -1321,7 +1348,9 @@ Rule Chile 2012 2014 - Sep Sun>=2 4:00u 1:00 -
Rule Chile 2016 2018 - May Sun>=9 3:00u 0 -
Rule Chile 2016 2018 - Aug Sun>=9 4:00u 1:00 -
Rule Chile 2019 max - Apr Sun>=2 3:00u 0 -
-Rule Chile 2019 max - Sep Sun>=2 4:00u 1:00 -
+Rule Chile 2019 2021 - Sep Sun>=2 4:00u 1:00 -
+Rule Chile 2022 only - Sep Sun>=9 4:00u 1:00 -
+Rule Chile 2023 max - Sep Sun>=2 4:00u 1:00 -
# IATA SSIM anomalies: (1992-02) says 1992-03-14;
# (1996-09) says 1998-03-08. Ignore these.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
@@ -1334,9 +1363,9 @@ Zone America/Santiago -4:42:45 - LMT 1890
-5:00 Chile -05/-04 1932 Sep 1
-4:00 - -04 1942 Jun 1
-5:00 - -05 1942 Aug 1
- -4:00 - -04 1946 Jul 15
- -4:00 1:00 -03 1946 Sep 1 # central Chile
- -4:00 - -04 1947 Apr 1
+ -4:00 - -04 1946 Jul 14 24:00
+ -4:00 1:00 -03 1946 Aug 28 24:00 # central CL
+ -5:00 1:00 -04 1947 Mar 31 24:00
-5:00 - -05 1947 May 21 23:00
-4:00 Chile -04/-03
Zone America/Punta_Arenas -4:43:40 - LMT 1890
@@ -1348,7 +1377,8 @@ Zone America/Punta_Arenas -4:43:40 - LMT 1890
-5:00 Chile -05/-04 1932 Sep 1
-4:00 - -04 1942 Jun 1
-5:00 - -05 1942 Aug 1
- -4:00 - -04 1947 Apr 1
+ -4:00 - -04 1946 Aug 28 24:00
+ -5:00 1:00 -04 1947 Mar 31 24:00
-5:00 - -05 1947 May 21 23:00
-4:00 Chile -04/-03 2016 Dec 4
-3:00 - -03
@@ -1382,13 +1412,14 @@ Zone Antarctica/Palmer 0 - -00 1965
# Colombia
-# Milne gives 4:56:16.4 for Bogotá time in 1899; round to nearest. He writes,
+# Milne gives 4:56:16.4 for Bogotá time in 1899. He writes,
# "A variation of fifteen minutes in the public clocks of Bogota is not rare."
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule CO 1992 only - May 3 0:00 1:00 -
Rule CO 1993 only - Apr 4 0:00 0 -
# Zone NAME STDOFF RULES FORMAT [UNTIL]
+ #STDOFF -4:56:16.4
Zone America/Bogota -4:56:16 - LMT 1884 Mar 13
-4:56:16 - BMT 1914 Nov 23 # Bogotá Mean Time
-5:00 CO -05/-04
diff --git a/strftime.c b/strftime.c
index 5273155..deba2b5 100644
--- a/strftime.c
+++ b/strftime.c
@@ -56,8 +56,6 @@ struct lc_time_T {
const char * date_fmt;
};
-#define Locale (&C_time_locale)
-
static const struct lc_time_T C_time_locale = {
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
@@ -113,7 +111,7 @@ static char * _fmt(const char *, const struct tm *, char *, const char *,
static char * _yconv(int, int, bool, bool, char *, char const *);
#ifndef YEAR_2000_NAME
-#define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
+# define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
#endif /* !defined YEAR_2000_NAME */
#if HAVE_STRFTIME_L
@@ -164,6 +162,8 @@ static char *
_fmt(const char *format, const struct tm *t, char *pt,
const char *ptlim, enum warn *warnp)
{
+ struct lc_time_T const *Locale = &C_time_locale;
+
for ( ; *format; ++format) {
if (*format == '%') {
label:
@@ -320,21 +320,11 @@ label:
time_t mkt;
tm = *t;
- tm.tm_yday = -1;
mkt = mktime(&tm);
- if (mkt == (time_t) -1) {
- /* Fail unless this -1 represents
- a valid time. */
- struct tm tm_1;
- if (!localtime_r(&mkt, &tm_1))
- return NULL;
- if (!(tm.tm_year == tm_1.tm_year
- && tm.tm_yday == tm_1.tm_yday
- && tm.tm_hour == tm_1.tm_hour
- && tm.tm_min == tm_1.tm_min
- && tm.tm_sec == tm_1.tm_sec))
- return NULL;
- }
+ /* There is no portable, definitive
+ test for whether whether mktime
+ succeeded, so treat (time_t) -1 as
+ the success that it might be. */
if (TYPE_SIGNED(time_t)) {
intmax_t n = mkt;
sprintf(buf, "%"PRIdMAX, n);
@@ -561,15 +551,15 @@ label:
# endif
negative = diff < 0;
if (diff == 0) {
-#ifdef TM_ZONE
+# ifdef TM_ZONE
negative = t->TM_ZONE[0] == '-';
-#else
+# else
negative = t->tm_isdst < 0;
-# if HAVE_TZNAME
+# if HAVE_TZNAME
if (tzname[t->tm_isdst != 0][0] == '-')
negative = true;
+# endif
# endif
-#endif
}
if (negative) {
sign = "-";
@@ -636,7 +626,7 @@ _yconv(int a, int b, bool convert_top, bool convert_yy,
register int lead;
register int trail;
-#define DIVISOR 100
+ int DIVISOR = 100;
trail = a % DIVISOR + b % DIVISOR;
lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR;
trail %= DIVISOR;
diff --git a/theory.html b/theory.html
index 28cc88e..2b14c51 100644
--- a/theory.html
+++ b/theory.html
@@ -376,9 +376,11 @@ The source file <code>etcetera</code> defines names that may be useful
on platforms that do not support POSIX-style <code>TZ</code> strings;
no other source file other than <code>backward</code>
contains links to its zones.
-One of <code>etcetera</code>'s names is <code>GMT</code>,
+One of <code>etcetera</code>'s names is <code>Etc/UTC</code>,
used by functions like <code>gmtime</code> to obtain leap
second information on platforms that support leap seconds.
+Another <code>etcetera</code> name, <code>GMT</code>,
+is used by older code releases.
</p>
</section>
@@ -468,6 +470,7 @@ in decreasing order of importance:
PST/PDT Philippine,
SAST South Africa,
SST Samoa,
+ UTC Universal,
WAT/WAST West Africa,
WET/WEST/WEMT Western European,
WIB Waktu Indonesia Barat,
@@ -502,7 +505,7 @@ in decreasing order of importance:
HMT Havana, Helsinki, Horta, Howrah;
IMT Irkutsk, Istanbul;
JMT Jerusalem;
- KMT Kaunas, Kiev, Kingston;
+ KMT Kaunas, Kyiv, Kingston;
LMT Lima, Lisbon, local, Luanda;
MMT Macassar, Madras, Malé, Managua, Minsk, Monrovia, Montevideo,
Moratuwa, Moscow;
@@ -720,8 +723,8 @@ href="https://www.dissentmagazine.org/blog/booked-a-global-history-of-time-vanes
than what the <code><abbr>tz</abbr></code> code can handle.
For example, from 1880 to 1916 clocks in Ireland observed Dublin Mean
Time (estimated to be <abbr>UT</abbr>
- &minus;00:25:21.1), but the <code><abbr>tz</abbr></code>
- code cannot represent the fractional second.
+ &minus;00:25:21.1); although the <code><abbr>tz</abbr></code>
+ source data can represent the .1 second, TZif files and the code cannot.
In practice these old specifications were rarely if ever
implemented to subsecond precision.
</li>
@@ -1295,7 +1298,8 @@ Because a leap second adjustment may be needed even
if no time zone correction is desired,
calls to <code>gmtime</code>-like functions
also need to consult a <abbr>TZif</abbr> file,
-conventionally named <samp><abbr>GMT</abbr></samp>,
+conventionally named <samp><abbr>Etc/UTC</abbr></samp>
+(<samp><abbr>GMT</abbr></samp> in previous versions),
to see whether leap second corrections are needed.
To convert an application's <code>time_t</code> timestamps to or from
POSIX <code>time_t</code> timestamps (for use when, say,
diff --git a/tz-how-to.html b/tz-how-to.html
index bf3e86f..e1e28f2 100644
--- a/tz-how-to.html
+++ b/tz-how-to.html
@@ -17,7 +17,7 @@ td.footnote {text-align: left;}
<h2>How to Read the <a href="https://en.wikipedia.org/wiki/Tz_database">tz
Database</a> Source Files</h2>
<h3>by Bill Seymour</h3>
-<p>This page uses the <code>America/Chicago</code> and
+<p>This guide uses the <code>America/Chicago</code> and
<code>Pacific/Honolulu</code> zones as examples of how to infer
times of day from the <a href="tz-link.html">tz database</a>
source files. It might be helpful, but not absolutely necessary,
@@ -25,7 +25,10 @@ for the reader to have already downloaded the
latest release of the database and become familiar with the basic layout
of the data files. The format is explained in the &ldquo;man
page&rdquo; for the zic compiler, <code>zic.8.txt</code>, in
-the <code>code</code> subdirectory.</p>
+the <code>code</code> subdirectory.
+Although this guide covers many of the common cases, it is not a
+complete summary of what zic accepts; the man page is the
+authoritative reference.</p>
<p>We&rsquo;ll begin by talking about the rules for changing between standard
and daylight saving time since we&rsquo;ll need that information when we talk
@@ -111,7 +114,8 @@ representable year.
<p>The next column, <code>-</code>, is reserved; for compatibility with earlier
releases, it always contains a hyphen, which acts as a kind of null value.
Prior to the 2020b release, it was called the <code>TYPE</code> field, though
-it was never used in the main data. An obsolescent supplementary file used the
+it had not been used in the main data since the 2000e release.
+An obsolescent supplementary file used the
field as a proof-of-concept to allow <code>zic</code> to apply a given Rule
line only to certain &ldquo;types&rdquo; of years within the specified range as
dictated by the output of a separate script, such as: only years which would
@@ -490,21 +494,26 @@ offset, so the local (wall clock) time during this period was GMT &minus;
10:30 + 1:00 = GMT &minus; 9:30.</p>
<p>The <code>FORMAT</code> column specifies the usual abbreviation of
-the time zone name. It can have one of three forms:</p>
+the time zone name. It should have one of four forms:</p>
<ul>
-<li>a string of three or more characters that are either ASCII alphanumerics,
-&ldquo;<code>+</code>&rdquo;, or &ldquo;<code>-</code>&rdquo;,
-in which case that&rsquo;s the abbreviation</li>
+<li>a time zone abbreviation that is a string of three or more
+characters that are either ASCII alphanumerics,
+&ldquo;<code>+</code>&rdquo;, or &ldquo;<code>-</code>&rdquo;</li>
-<li>a pair of strings separated by a slash
+<li>the string &ldquo;%z&rdquo;, in which case the
+&ldquo;<code>%z</code>&rdquo; will be replaced by a numeric time zone
+abbreviation</li>
+
+<li>a pair of time zone abbreviations separated by a slash
(&lsquo;<code>/</code>&rsquo;), in which case the first string is the
abbreviation for the standard time name and the second string is the
abbreviation for the daylight saving time name</li>
-<li>a string containing &ldquo;<code>%s</code>,&rdquo; in which case
+<li>a string containing &ldquo;<code>%s</code>&rdquo;, in which case
the &ldquo;<code>%s</code>&rdquo; will be replaced by the text in the
-appropriate Rule&rsquo;s <code>LETTER</code> column</li>
+appropriate Rule&rsquo;s <code>LETTER</code> column, and the resulting
+string should be a time zone abbreviation</li>
</ul>
<p>The last two make sense only if there&rsquo;s a named rule in effect.</p>
diff --git a/tz-link.html b/tz-link.html
index 92da48f..2532069 100644
--- a/tz-link.html
+++ b/tz-link.html
@@ -255,7 +255,8 @@ href="https://dev.mysql.com/doc/refman/en/time-zone-support.html">MySQL</a>,
<a href="https://nodatime.org/userguide/tzdb">Noda Time</a>, and <a
href="https://www.oracle.com/java/technologies/javase/tzupdater-readme.html">OpenJDK/Oracle JDK</a>.
</p>
-<p>Sources for the <code><abbr>tz</abbr></code> database are
+<p>Since version 2013a,
+sources for the <code><abbr>tz</abbr></code> database have been
<a href="https://en.wikipedia.org/wiki/UTF-8"><abbr
title="Unicode Transformation Format 8-bit">UTF-8</abbr></a>
<a href="https://en.wikipedia.org/wiki/Text_file">text files</a>
@@ -1060,7 +1061,9 @@ half second, even though every <abbr>POSIX</abbr> minute has exactly
sixty seconds. This approach works with the default <code><abbr>tz</abbr></code>
"<code>posix</code>" configuration, is <a
href="http://bk1.ntp.org/ntp-stable/README.leapsmear">supported</a> by
-the <abbr>NTP</abbr> reference implementation, and is used by major
+the <abbr>NTP</abbr> reference implementation, <a
+href="https://github.com/google/unsmear">supports</a> conversion between
+<abbr>UTC</abbr> and smeared <abbr>POSIX</abbr> timestamps, and is used by major
cloud service providers. However, according to
<a href="https://tools.ietf.org/html/rfc8633#section-3.7.1">&sect;3.7.1 of
Network Time Protocol Best Current Practices</a>
diff --git a/tzfile.h b/tzfile.h
index 9c3ea4e..6b18d6b 100644
--- a/tzfile.h
+++ b/tzfile.h
@@ -22,15 +22,15 @@
*/
#ifndef TZDIR
-#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
+# define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
#endif /* !defined TZDIR */
#ifndef TZDEFAULT
-#define TZDEFAULT "/etc/localtime"
+# define TZDEFAULT "/etc/localtime"
#endif /* !defined TZDEFAULT */
#ifndef TZDEFRULES
-#define TZDEFRULES "posixrules"
+# define TZDEFRULES "posixrules"
#endif /* !defined TZDEFRULES */
@@ -103,21 +103,21 @@ struct tzhead {
*/
#ifndef TZ_MAX_TIMES
-#define TZ_MAX_TIMES 2000
+# define TZ_MAX_TIMES 2000
#endif /* !defined TZ_MAX_TIMES */
#ifndef TZ_MAX_TYPES
/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */
-#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
+# define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
#endif /* !defined TZ_MAX_TYPES */
#ifndef TZ_MAX_CHARS
-#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
+# define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
/* (limited by what unsigned chars can hold) */
#endif /* !defined TZ_MAX_CHARS */
#ifndef TZ_MAX_LEAPS
-#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
+# define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
#endif /* !defined TZ_MAX_LEAPS */
#endif /* !defined TZFILE_H */
diff --git a/tzselect.8 b/tzselect.8
index 69514e2..8549659 100644
--- a/tzselect.8
+++ b/tzselect.8
@@ -4,6 +4,16 @@ tzselect \- select a timezone
.SH SYNOPSIS
.ie \n(.g .ds - \f(CW-\fP
.el .ds - \-
+.ds d " degrees
+.ds m " minutes
+.ds s " seconds
+.ds _ " \"
+.if t .if \n(.g .if c \(de .if c \(fm .if c \(sd \{\
+. ds d \(de
+. ds m \(fm
+. ds s \(sd
+. ds _ \|
+.\}
.B tzselect
[
.B \*-c
@@ -57,11 +67,11 @@ seconds, with any trailing fractions represent fractional minutes or
is present) seconds. The decimal point is that of the current locale.
For example, in the (default) C locale,
.B "\*-c\ +40.689\*-074.045"
-specifies 40.689\(de\|N, 74.045\(de\|W,
+specifies 40.689\*d\*_N, 74.045\*d\*_W,
.B "\*-c\ +4041.4\*-07402.7"
-specifies 40\(de\|41.4\(fm\|N, 74\(de\|2.7\(fm\|W, and
+specifies 40\*d\*_41.4\*m\*_N, 74\*d\*_2.7\*m\*_W, and
.B "\*-c\ +404121\*-0740240"
-specifies 40\(de\|41\(fm\|21\(sd\|N, 74\(de\|2\(fm\|40\(sd\|W.
+specifies 40\*d\*_41\*m\*_21\*s\*_N, 74\*d\*_2\*m\*_40\*s\*_W.
If
.I coord
is not one of the documented forms, the resulting behavior is unspecified.
diff --git a/zdump.c b/zdump.c
index 8b6788a..a63a343 100644
--- a/zdump.c
+++ b/zdump.c
@@ -35,11 +35,11 @@
#endif
#ifndef ZDUMP_LO_YEAR
-#define ZDUMP_LO_YEAR (-500)
+# define ZDUMP_LO_YEAR (-500)
#endif /* !defined ZDUMP_LO_YEAR */
#ifndef ZDUMP_HI_YEAR
-#define ZDUMP_HI_YEAR 2500
+# define ZDUMP_HI_YEAR 2500
#endif /* !defined ZDUMP_HI_YEAR */
#define SECSPERNYEAR (SECSPERDAY * DAYSPERNYEAR)
@@ -72,7 +72,7 @@ enum { SECSPER400YEARS_FITS = SECSPERLYEAR <= INTMAX_MAX / 400 };
#endif
#if HAVE_GETTEXT
-#include <locale.h> /* for setlocale */
+# include <locale.h> /* for setlocale */
#endif /* HAVE_GETTEXT */
#if ! HAVE_LOCALTIME_RZ
@@ -450,9 +450,9 @@ main(int argc, char *argv[])
cuthitime = absolute_max_time;
#if HAVE_GETTEXT
setlocale(LC_ALL, "");
-#ifdef TZ_DOMAINDIR
+# ifdef TZ_DOMAINDIR
bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
-#endif /* defined TEXTDOMAINDIR */
+# endif /* defined TEXTDOMAINDIR */
textdomain(TZ_DOMAIN);
#endif /* HAVE_GETTEXT */
progname = argv[0];
@@ -548,7 +548,7 @@ main(int argc, char *argv[])
for (i = optind; i < argc; i++) {
size_t arglen = strlen(argv[i]);
if (longest < arglen)
- longest = arglen < INT_MAX ? arglen : INT_MAX;
+ longest = min(arglen, INT_MAX);
}
for (i = optind; i < argc; ++i) {
@@ -1193,6 +1193,7 @@ dumptime(register const struct tm *timeptr)
};
register int lead;
register int trail;
+ int DIVISOR = 10;
/*
** The packaged localtime_rz and gmtime_r never put out-of-range
@@ -1208,7 +1209,6 @@ dumptime(register const struct tm *timeptr)
? mon_name[timeptr->tm_mon] : "???"),
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec);
-#define DIVISOR 10
trail = timeptr->tm_year % DIVISOR + TM_YEAR_BASE % DIVISOR;
lead = timeptr->tm_year / DIVISOR + TM_YEAR_BASE / DIVISOR +
trail / DIVISOR;
diff --git a/zic.8 b/zic.8
index a0a9743..772ee89 100644
--- a/zic.8
+++ b/zic.8
@@ -28,6 +28,16 @@ zic \- timezone compiler
. ds :
. ds - \-
.\}
+.ds d " degrees
+.ds m " minutes
+.ds s " seconds
+.ds _ " \"
+.if t .if \n(.g .if c \(de .if c \(fm .if c \(sd \{\
+. ds d \(de
+. ds m \(fm
+. ds s \(sd
+. ds _ \|
+.\}
The
.B zic
program reads text from the file(s) named on the command line
@@ -136,8 +146,7 @@ are possibly-signed decimal counts of seconds since the Epoch
Omitted counts default to extreme values.
The output files use UT offset 0 and abbreviation
.q "\*-00"
-in place of the omitted timestamp data;
-this typically reduces the files' sizes.
+in place of the omitted timestamp data.
For example,
.q "zic \*-r @0"
omits data intended for negative timestamps (i.e., before the Epoch), and
@@ -146,12 +155,31 @@ outputs data intended only for nonnegative timestamps that fit into
31-bit signed integers.
On platforms with GNU
.BR date ,
-.q "zic \-r @$(date +%s)"
+.q "zic \*-r @$(date +%s)"
omits data intended for past timestamps.
+Although this option typically reduces the output file's size,
+the size can increase due to the need to represent the timestamp range
+boundaries, particularly if
+.I hi
+causes a TZif file to contain explicit entries for
+.RI pre- hi
+transitions rather than concisely representing them
+with an extended POSIX TZ string.
Also see the
.B "\*-b slim"
option for another way to shrink output size.
.TP
+.BI "\*-R @" hi
+Generate redundant trailing explicit transitions for timestamps
+that occur less than
+.I hi
+seconds since the Epoch, even though the transitions could be
+more concisely represented via the extended POSIX TZ string.
+This option does not affect the represented timestamps.
+Although it accommodates nonstandard TZif readers
+that ignore the extended POSIX TZ string,
+it increases the size of the altered output files.
+.TP
.BI "\*-t " file
When creating local time information, put the configuration link in
the named file rather than in the standard location.
@@ -253,7 +281,8 @@ format.
.PP
Input files should be text files, that is, they should be a series of
zero or more lines, each ending in a newline byte and containing at
-most 511 bytes, and without any NUL bytes. The input text's encoding
+most 2048 bytes counting the newline, and without any NUL bytes.
+The input text's encoding
is typically UTF-8 or ASCII; it should have a unibyte representation
for the POSIX Portable Character Set (PPCS)
\*<https://pubs\*:.opengroup\*:.org/\*:onlinepubs/\*:9699919799/\*:basedefs/\*:V1_chap06\*:.html\*>
@@ -521,7 +550,7 @@ This field has the same format as the
.B AT
and
.B SAVE
-fields of rule lines;
+fields of rule lines, except without suffix letters;
begin the field with a minus sign if time must be subtracted from UT.
.TP
.B RULES
@@ -749,15 +778,13 @@ The
.BR DAY ,
and
.B HH:MM:SS
-fields give the expiration timestamp in UTC for the leap second table;
+fields give the expiration timestamp in UTC for the leap second table.
+.br
+.ne 22
.SH "EXTENDED EXAMPLE"
Here is an extended example of
.B zic
input, intended to illustrate many of its features.
-In this example, the EU rules are for the European Union
-and for its predecessor organization, the European Communities.
-.br
-.ne 22
.nf
.in +2m
.ta \w'# Rule\0\0'u +\w'NAME\0\0'u +\w'FROM\0\0'u +\w'1973\0\0'u +\w'\*-\0\0'u +\w'Apr\0\0'u +\w'lastSun\0\0'u +\w'2:00\0\0'u +\w'SAVE\0\0'u
@@ -784,13 +811,13 @@ Link Europe/Zurich Europe/Vaduz
.sp
.in
.fi
-In this example, the timezone is named Europe/Zurich but it has an alias
-as Europe/Vaduz. This example says that Zurich was 34 minutes and 8
+In this example, the EU rules are for the European Union
+and for its predecessor organization, the European Communities.
+The timezone is named Europe/Zurich and it has the alias Europe/Vaduz.
+This example says that Zurich was 34 minutes and 8
seconds east of UT until 1853-07-16 at 00:00, when the legal offset
was changed to
-.ds o 7 degrees 26 minutes 22.50 seconds
-.if \n(.g .if c \(de .if c \(fm .if c \(sd .ds o 7\(de\|26\(fm\|22.50\(sd
-\*o,
+7\*d\*_26\*m\*_22.50\*s,
which works out to 0:29:45.50;
.B zic
treats this by rounding it to 0:29:46.
diff --git a/zic.c b/zic.c
index 2d1a187..a29f679 100644
--- a/zic.c
+++ b/zic.c
@@ -29,7 +29,7 @@ typedef int_fast64_t zic_t;
#define SCNdZIC SCNdFAST64
#ifndef ZIC_MAX_ABBR_LEN_WO_WARN
-#define ZIC_MAX_ABBR_LEN_WO_WARN 6
+# define ZIC_MAX_ABBR_LEN_WO_WARN 6
#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */
#ifdef HAVE_DIRECT_H
@@ -40,12 +40,12 @@ typedef int_fast64_t zic_t;
#endif
#if HAVE_SYS_STAT_H
-#include <sys/stat.h>
+# include <sys/stat.h>
#endif
#ifdef S_IRUSR
-#define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
+# define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
#else
-#define MKDIR_UMASK 0755
+# define MKDIR_UMASK 0755
#endif
/* The maximum ptrdiff_t value, for pre-C99 platforms. */
@@ -58,6 +58,11 @@ static ptrdiff_t const PTRDIFF_MAX = MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t));
# define _Alignof(type) offsetof(struct { char a; type b; }, b)
#endif
+/* The maximum length of a text line, including the trailing newline. */
+#ifndef _POSIX2_LINE_MAX
+# define _POSIX2_LINE_MAX 2048
+#endif
+
/* The type for line numbers. Use PRIdMAX to format them; formerly
there was also "#define PRIdLINENO PRIdMAX" and formats used
PRIdLINENO, but xgettext cannot grok that. */
@@ -91,12 +96,13 @@ struct rule {
};
/*
-** r_dycode r_dayofmonth r_wday
+** r_dycode r_dayofmonth r_wday
*/
-
-#define DC_DOM 0 /* 1..31 */ /* unused */
-#define DC_DOWGEQ 1 /* 1..31 */ /* 0..6 (Sun..Sat) */
-#define DC_DOWLEQ 2 /* 1..31 */ /* 0..6 (Sun..Sat) */
+enum {
+ DC_DOM, /* 1..31 */ /* unused */
+ DC_DOWGEQ, /* 1..31 */ /* 0..6 (Sun..Sat) */
+ DC_DOWLEQ /* 1..31 */ /* 0..6 (Sun..Sat) */
+};
struct zone {
const char * z_filename;
@@ -145,7 +151,7 @@ static void leapadd(zic_t, int, int);
static void adjleap(void);
static void associate(void);
static void dolink(const char *, const char *, bool);
-static char ** getfields(char * buf);
+static int getfields(char *, char **, int);
static zic_t gethms(const char * string, const char * errstring);
static zic_t getsave(char *, bool *);
static void inexpires(char **, int);
@@ -208,86 +214,107 @@ static int unspecifiedtype;
** Line codes.
*/
-#define LC_RULE 0
-#define LC_ZONE 1
-#define LC_LINK 2
-#define LC_LEAP 3
-#define LC_EXPIRES 4
+enum {
+ LC_RULE,
+ LC_ZONE,
+ LC_LINK,
+ LC_LEAP,
+ LC_EXPIRES
+};
/*
** Which fields are which on a Zone line.
*/
-#define ZF_NAME 1
-#define ZF_STDOFF 2
-#define ZF_RULE 3
-#define ZF_FORMAT 4
-#define ZF_TILYEAR 5
-#define ZF_TILMONTH 6
-#define ZF_TILDAY 7
-#define ZF_TILTIME 8
-#define ZONE_MINFIELDS 5
-#define ZONE_MAXFIELDS 9
+enum {
+ ZF_NAME = 1,
+ ZF_STDOFF,
+ ZF_RULE,
+ ZF_FORMAT,
+ ZF_TILYEAR,
+ ZF_TILMONTH,
+ ZF_TILDAY,
+ ZF_TILTIME,
+ ZONE_MAXFIELDS,
+ ZONE_MINFIELDS = ZF_TILYEAR
+};
/*
** Which fields are which on a Zone continuation line.
*/
-#define ZFC_STDOFF 0
-#define ZFC_RULE 1
-#define ZFC_FORMAT 2
-#define ZFC_TILYEAR 3
-#define ZFC_TILMONTH 4
-#define ZFC_TILDAY 5
-#define ZFC_TILTIME 6
-#define ZONEC_MINFIELDS 3
-#define ZONEC_MAXFIELDS 7
+enum {
+ ZFC_STDOFF,
+ ZFC_RULE,
+ ZFC_FORMAT,
+ ZFC_TILYEAR,
+ ZFC_TILMONTH,
+ ZFC_TILDAY,
+ ZFC_TILTIME,
+ ZONEC_MAXFIELDS,
+ ZONEC_MINFIELDS = ZFC_TILYEAR
+};
/*
** Which files are which on a Rule line.
*/
-#define RF_NAME 1
-#define RF_LOYEAR 2
-#define RF_HIYEAR 3
-#define RF_COMMAND 4
-#define RF_MONTH 5
-#define RF_DAY 6
-#define RF_TOD 7
-#define RF_SAVE 8
-#define RF_ABBRVAR 9
-#define RULE_FIELDS 10
+enum {
+ RF_NAME = 1,
+ RF_LOYEAR,
+ RF_HIYEAR,
+ RF_COMMAND,
+ RF_MONTH,
+ RF_DAY,
+ RF_TOD,
+ RF_SAVE,
+ RF_ABBRVAR,
+ RULE_FIELDS
+};
/*
** Which fields are which on a Link line.
*/
-#define LF_TARGET 1
-#define LF_LINKNAME 2
-#define LINK_FIELDS 3
+enum {
+ LF_TARGET = 1,
+ LF_LINKNAME,
+ LINK_FIELDS
+};
/*
** Which fields are which on a Leap line.
*/
-#define LP_YEAR 1
-#define LP_MONTH 2
-#define LP_DAY 3
-#define LP_TIME 4
-#define LP_CORR 5
-#define LP_ROLL 6
-#define LEAP_FIELDS 7
+enum {
+ LP_YEAR = 1,
+ LP_MONTH,
+ LP_DAY,
+ LP_TIME,
+ LP_CORR,
+ LP_ROLL,
+ LEAP_FIELDS,
+
+ /* Expires lines are like Leap lines, except without CORR and ROLL fields. */
+ EXPIRES_FIELDS = LP_TIME + 1
+};
-/* Expires lines are like Leap lines, except without CORR and ROLL fields. */
-#define EXPIRES_FIELDS 5
+/* The maximum number of fields on any of the above lines.
+ (The "+"s pacify gcc -Wenum-compare.) */
+enum {
+ MAX_FIELDS = max(max(+RULE_FIELDS, +LINK_FIELDS),
+ max(+LEAP_FIELDS, +EXPIRES_FIELDS))
+};
/*
** Year synonyms.
*/
-#define YR_MINIMUM 0
-#define YR_MAXIMUM 1
-#define YR_ONLY 2
+enum {
+ YR_MINIMUM,
+ YR_MAXIMUM,
+ YR_ONLY
+};
static struct rule * rules;
static ptrdiff_t nrules; /* number of rules */
@@ -480,7 +507,7 @@ growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
return ptr;
else {
ptrdiff_t nitems_max = PTRDIFF_MAX - WORK_AROUND_QTBUG_53071;
- ptrdiff_t amax = nitems_max < SIZE_MAX ? nitems_max : SIZE_MAX;
+ ptrdiff_t amax = min(nitems_max, SIZE_MAX);
if ((amax - 1) / 3 * 2 < *nitems_alloc)
memory_exhausted(_("integer overflow"));
*nitems_alloc += (*nitems_alloc >> 1) + 1;
@@ -571,7 +598,8 @@ usage(FILE *stream, int status)
_("%s: usage is %s [ --version ] [ --help ] [ -v ] \\\n"
"\t[ -b {slim|fat} ] [ -d directory ] [ -l localtime ]"
" [ -L leapseconds ] \\\n"
- "\t[ -p posixrules ] [ -r '[@lo][/@hi]' ] [ -t localtime-link ] \\\n"
+ "\t[ -p posixrules ] [ -r '[@lo][/@hi]' ] [ -R '@hi' ] \\\n"
+ "\t[ -t localtime-link ] \\\n"
"\t[ filename ... ]\n\n"
"Report bugs to %s.\n"),
progname, progname, REPORT_BUGS_TO);
@@ -662,7 +690,7 @@ check_for_signal(void)
}
}
-#define TIME_T_BITS_IN_FILE 64
+enum { TIME_T_BITS_IN_FILE = 64 };
/* The minimum and maximum values representable in a TZif file. */
static zic_t const min_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
@@ -673,6 +701,9 @@ static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
static zic_t lo_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
static zic_t hi_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
+/* The time specified by the -R option, defaulting to MIN_TIME. */
+static zic_t redundant_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
+
/* The time specified by an Expires line, or negative if no such line. */
static zic_t leapexpires = -1;
@@ -699,11 +730,27 @@ timerange_option(char *timerange)
}
if (*hi_end || hi < lo || max_time < lo || hi < min_time)
return false;
- lo_time = lo < min_time ? min_time : lo;
- hi_time = max_time < hi ? max_time : hi;
+ lo_time = max(lo, min_time);
+ hi_time = min(hi, max_time);
return true;
}
+/* Generate redundant time stamps up to OPT. Return true if successful. */
+static bool
+redundant_time_option(char *opt)
+{
+ if (*opt == '@') {
+ intmax_t redundant;
+ char *opt_end;
+ redundant = strtoimax(opt + 1, &opt_end, 10);
+ if (opt_end != opt + 1 && !*opt_end) {
+ redundant_time = max(redundant_time, redundant);
+ return true;
+ }
+ }
+ return false;
+}
+
static const char * psxrules;
static const char * lcltime;
static const char * directory;
@@ -737,9 +784,9 @@ main(int argc, char **argv)
#endif
#if HAVE_GETTEXT
setlocale(LC_ALL, "");
-#ifdef TZ_DOMAINDIR
+# ifdef TZ_DOMAINDIR
bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
-#endif /* defined TEXTDOMAINDIR */
+# endif /* defined TEXTDOMAINDIR */
textdomain(TZ_DOMAIN);
#endif /* HAVE_GETTEXT */
progname = argv[0];
@@ -756,7 +803,8 @@ main(int argc, char **argv)
} else if (strcmp(argv[k], "--help") == 0) {
usage(stdout, EXIT_SUCCESS);
}
- while ((c = getopt(argc, argv, "b:d:l:L:p:r:st:vy:")) != EOF && c != -1)
+ while ((c = getopt(argc, argv, "b:d:l:L:p:r:R:st:vy:")) != EOF
+ && c != -1)
switch (c) {
default:
usage(stderr, EXIT_FAILURE);
@@ -843,12 +891,23 @@ _("%s: invalid time range: %s\n"),
}
timerange_given = true;
break;
+ case 'R':
+ if (! redundant_time_option(optarg)) {
+ fprintf(stderr, _("%s: invalid time: %s\n"),
+ progname, optarg);
+ return EXIT_FAILURE;
+ }
+ break;
case 's':
warning(_("-s ignored"));
break;
}
if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
usage(stderr, EXIT_FAILURE); /* usage message by request */
+ if (hi_time + (hi_time < ZIC_MAX) < redundant_time) {
+ fprintf(stderr, _("%s: -R time exceeds -r cutoff\n"), progname);
+ return EXIT_FAILURE;
+ }
if (bloat == 0) {
static char const bloat_default[] = ZIC_BLOAT_DEFAULT;
if (strcmp(bloat_default, "slim") == 0)
@@ -1304,17 +1363,47 @@ associate(void)
exit(EXIT_FAILURE);
}
+/* Read a text line from FP into BUF, which is of size BUFSIZE.
+ Terminate it with a NUL byte instead of a newline.
+ Return the line's length, not counting the NUL byte.
+ On EOF, return a negative number.
+ On error, report the error and exit. */
+static ptrdiff_t
+inputline(FILE *fp, char *buf, ptrdiff_t bufsize)
+{
+ ptrdiff_t linelen = 0, ch;
+ while ((ch = getc(fp)) != '\n') {
+ if (ch < 0) {
+ if (ferror(fp)) {
+ error(_("input error"));
+ exit(EXIT_FAILURE);
+ }
+ if (linelen == 0)
+ return -1;
+ error(_("unterminated line"));
+ exit(EXIT_FAILURE);
+ }
+ if (!ch) {
+ error(_("NUL input byte"));
+ exit(EXIT_FAILURE);
+ }
+ buf[linelen++] = ch;
+ if (linelen == bufsize) {
+ error(_("line too long"));
+ exit(EXIT_FAILURE);
+ }
+ }
+ buf[linelen] = '\0';
+ return linelen;
+}
+
static void
infile(const char *name)
{
register FILE * fp;
- register char ** fields;
- register char * cp;
register const struct lookup * lp;
- register int nfields;
register bool wantcont;
register lineno num;
- char buf[BUFSIZ];
if (strcmp(name, "-") == 0) {
name = _("standard input");
@@ -1328,24 +1417,16 @@ infile(const char *name)
}
wantcont = false;
for (num = 1; ; ++num) {
+ ptrdiff_t linelen;
+ char buf[_POSIX2_LINE_MAX];
+ int nfields;
+ char *fields[MAX_FIELDS];
eat(name, num);
- if (fgets(buf, sizeof buf, fp) != buf)
- break;
- cp = strchr(buf, '\n');
- if (cp == NULL) {
- error(_("line too long"));
- exit(EXIT_FAILURE);
- }
- *cp = '\0';
- fields = getfields(buf);
- nfields = 0;
- while (fields[nfields] != NULL) {
- static char nada;
-
- if (strcmp(fields[nfields], "-") == 0)
- fields[nfields] = &nada;
- ++nfields;
- }
+ linelen = inputline(fp, buf, sizeof buf);
+ if (linelen < 0)
+ break;
+ nfields = getfields(buf, fields,
+ sizeof fields / sizeof *fields);
if (nfields == 0) {
/* nothing to do */
} else if (wantcont) {
@@ -1379,7 +1460,6 @@ infile(const char *name)
default: UNREACHABLE();
}
}
- free(fields);
}
close_file(fp, NULL, filename, NULL);
if (wantcont)
@@ -1960,11 +2040,11 @@ struct timerange {
int defaulttype;
ptrdiff_t base, count;
int leapbase, leapcount;
- bool pretrans, leapexpiry;
+ bool leapexpiry;
};
static struct timerange
-limitrange(struct timerange r, bool locut, zic_t lo, zic_t hi,
+limitrange(struct timerange r, zic_t lo, zic_t hi,
zic_t const *ats, unsigned char const *types)
{
/* Omit ordinary transitions < LO. */
@@ -1974,10 +2054,6 @@ limitrange(struct timerange r, bool locut, zic_t lo, zic_t hi,
r.base++;
}
- /* "-00" before any -r low cutoff. */
- if (min_time < lo_time)
- r.defaulttype = unspecifiedtype;
-
/* Omit as many initial leap seconds as possible, such that the
first leap second in the truncated list is <= LO, and is a
positive leap second if and only if it has a positive correction.
@@ -2003,14 +2079,6 @@ limitrange(struct timerange r, bool locut, zic_t lo, zic_t hi,
r.leapcount--;
}
- /* Determine whether to keep the last too-low transition if no
- transition is exactly at LO. The kept transition will be output
- as a LO "transition"; see "Output a LO_TIME transition" below.
- This is needed when the output is truncated at the start, and is
- also useful when catering to buggy 32-bit clients that do not use
- time type 0 for timestamps before the first transition. */
- r.pretrans = locut && r.base && ! (r.count && ats[r.base] == lo);
-
/* Determine whether to append an expiration to the leap second table. */
r.leapexpiry = 0 <= leapexpires && leapexpires - 1 <= hi;
@@ -2036,7 +2104,7 @@ writezone(const char *const name, const char *const string, char version,
_Alignof(zic_t)));
void *typesptr = ats + nats;
unsigned char *types = typesptr;
- struct timerange rangeall, range32, range64;
+ struct timerange rangeall = {0}, range32, range64;
/*
** Sort.
@@ -2120,14 +2188,13 @@ writezone(const char *const name, const char *const string, char version,
}
rangeall.defaulttype = defaulttype;
- rangeall.base = rangeall.leapbase = 0;
rangeall.count = timecnt;
rangeall.leapcount = leapcnt;
- rangeall.pretrans = rangeall.leapexpiry = false;
- range64 = limitrange(rangeall, min_time < lo_time,
- lo_time, hi_time, ats, types);
- range32 = limitrange(range64, true,
- INT32_MIN, INT32_MAX, ats, types);
+ range64 = limitrange(rangeall, lo_time,
+ max(hi_time,
+ redundant_time - (ZIC_MIN < redundant_time)),
+ ats, types);
+ range32 = limitrange(range64, INT32_MIN, INT32_MAX, ats, types);
/* TZif version 4 is needed if a no-op transition is appended to
indicate the expiration of the leap second table, or if the first
@@ -2161,9 +2228,9 @@ writezone(const char *const name, const char *const string, char version,
register ptrdiff_t thistimei, thistimecnt, thistimelim;
register int thisleapi, thisleapcnt, thisleaplim;
struct tzhead tzh;
- int thisdefaulttype;
- bool hicut, pretrans, thisleapexpiry;
- zic_t lo;
+ int pretranstype = -1, thisdefaulttype;
+ bool locut, hicut, thisleapexpiry;
+ zic_t lo, thismin, thismax;
int old0;
char omittype[TZ_MAX_TYPES];
int typemap[TZ_MAX_TYPES];
@@ -2174,28 +2241,15 @@ writezone(const char *const name, const char *const string, char version,
int indmap[TZ_MAX_CHARS];
if (pass == 1) {
- /* Arguably the default time type in the 32-bit data
- should be range32.defaulttype, which is suited for
- timestamps just before INT32_MIN. However, zic
- traditionally used the time type of the indefinite
- past instead. Internet RFC 8532 says readers should
- ignore 32-bit data, so this discrepancy matters only
- to obsolete readers where the traditional type might
- be more appropriate even if it's "wrong". So, use
- the historical zic value, unless -r specifies a low
- cutoff that excludes some 32-bit timestamps. */
- thisdefaulttype = (lo_time <= INT32_MIN
- ? range64.defaulttype
- : range32.defaulttype);
-
+ thisdefaulttype = range32.defaulttype;
thistimei = range32.base;
thistimecnt = range32.count;
toomanytimes = thistimecnt >> 31 >> 1 != 0;
thisleapi = range32.leapbase;
thisleapcnt = range32.leapcount;
- pretrans = range32.pretrans;
thisleapexpiry = range32.leapexpiry;
- hicut = hi_time < INT32_MAX;
+ thismin = INT32_MIN;
+ thismax = INT32_MAX;
} else {
thisdefaulttype = range64.defaulttype;
thistimei = range64.base;
@@ -2203,17 +2257,46 @@ writezone(const char *const name, const char *const string, char version,
toomanytimes = thistimecnt >> 31 >> 31 >> 2 != 0;
thisleapi = range64.leapbase;
thisleapcnt = range64.leapcount;
- pretrans = range64.pretrans;
thisleapexpiry = range64.leapexpiry;
- hicut = hi_time < max_time;
+ thismin = min_time;
+ thismax = max_time;
}
if (toomanytimes)
error(_("too many transition times"));
+ locut = thismin < lo_time && lo_time <= thismax;
+ hicut = thismin <= hi_time && hi_time < thismax;
thistimelim = thistimei + thistimecnt;
memset(omittype, true, typecnt);
+
+ /* Determine whether to output a transition before the first
+ transition in range. This is needed when the output is
+ truncated at the start, and is also useful when catering to
+ buggy 32-bit clients that do not use time type 0 for
+ timestamps before the first transition. */
+ if ((locut || (pass == 1 && thistimei))
+ && ! (thistimecnt && ats[thistimei] == lo_time)) {
+ pretranstype = thisdefaulttype;
+ omittype[pretranstype] = false;
+ }
+
+ /* Arguably the default time type in the 32-bit data
+ should be range32.defaulttype, which is suited for
+ timestamps just before INT32_MIN. However, zic
+ traditionally used the time type of the indefinite
+ past instead. Internet RFC 8532 says readers should
+ ignore 32-bit data, so this discrepancy matters only
+ to obsolete readers where the traditional type might
+ be more appropriate even if it's "wrong". So, use
+ the historical zic value, unless -r specifies a low
+ cutoff that excludes some 32-bit timestamps. */
+ if (pass == 1 && lo_time <= thismin)
+ thisdefaulttype = range64.defaulttype;
+
+ if (locut)
+ thisdefaulttype = unspecifiedtype;
omittype[thisdefaulttype] = false;
- for (i = thistimei - pretrans; i < thistimelim; i++)
+ for (i = thistimei; i < thistimelim; i++)
omittype[types[i]] = false;
if (hicut)
omittype[unspecifiedtype] = false;
@@ -2237,7 +2320,13 @@ writezone(const char *const name, const char *const string, char version,
register int mrudst, mrustd, hidst, histd, type;
hidst = histd = mrudst = mrustd = -1;
- for (i = thistimei - pretrans; i < thistimelim; ++i)
+ if (0 <= pretranstype) {
+ if (isdsts[pretranstype])
+ mrudst = pretranstype;
+ else
+ mrustd = pretranstype;
+ }
+ for (i = thistimei; i < thistimelim; i++)
if (isdsts[types[i]])
mrudst = types[i];
else mrustd = types[i];
@@ -2307,7 +2396,8 @@ writezone(const char *const name, const char *const string, char version,
indmap[desigidx[i]] = j;
}
if (pass == 1 && !want_bloat()) {
- pretrans = hicut = thisleapexpiry = false;
+ hicut = thisleapexpiry = false;
+ pretranstype = -1;
thistimecnt = thisleapcnt = 0;
thistypecnt = thischarcnt = 1;
}
@@ -2318,7 +2408,8 @@ writezone(const char *const name, const char *const string, char version,
convert(utcnt, tzh.tzh_ttisutcnt);
convert(stdcnt, tzh.tzh_ttisstdcnt);
convert(thisleapcnt + thisleapexpiry, tzh.tzh_leapcnt);
- convert(pretrans + thistimecnt + hicut, tzh.tzh_timecnt);
+ convert((0 <= pretranstype) + thistimecnt + hicut,
+ tzh.tzh_timecnt);
convert(thistypecnt, tzh.tzh_typecnt);
convert(thischarcnt, tzh.tzh_charcnt);
DO(tzh_magic);
@@ -2345,14 +2436,16 @@ writezone(const char *const name, const char *const string, char version,
for this pass. */
lo = pass == 1 && lo_time < INT32_MIN ? INT32_MIN : lo_time;
- if (pretrans)
+ if (0 <= pretranstype)
puttzcodepass(lo, fp, pass);
for (i = thistimei; i < thistimelim; ++i) {
puttzcodepass(ats[i], fp, pass);
}
if (hicut)
puttzcodepass(hi_time + 1, fp, pass);
- for (i = thistimei - pretrans; i < thistimelim; ++i)
+ if (0 <= pretranstype)
+ putc(typemap[pretranstype], fp);
+ for (i = thistimei; i < thistimelim; i++)
putc(typemap[types[i]], fp);
if (hicut)
putc(typemap[unspecifiedtype], fp);
@@ -2453,6 +2546,8 @@ abbroffset(char *buf, zic_t offset)
}
}
+static char const disable_percent_s[] = "";
+
static size_t
doabbr(char *abbr, struct zone const *zp, char const *letters,
bool isdst, zic_t save, bool doquotes)
@@ -2469,6 +2564,8 @@ doabbr(char *abbr, struct zone const *zp, char const *letters,
letters = abbroffset(letterbuf, zp->z_stdoff + save);
else if (!letters)
letters = "%s";
+ else if (letters == disable_percent_s)
+ return 0;
sprintf(abbr, format, letters);
} else if (isdst) {
strcpy(abbr, slashp + 1);
@@ -2739,18 +2836,10 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
static void
outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
{
- register const struct zone * zp;
- register struct rule * rp;
register ptrdiff_t i, j;
- register bool usestart, useuntil;
register zic_t starttime, untiltime;
- register zic_t stdoff;
- register zic_t save;
- register zic_t year;
- register zic_t startoff;
register bool startttisstd;
register bool startttisut;
- register int type;
register char * startbuf;
register char * ab;
register char * envvar;
@@ -2761,8 +2850,6 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
register bool do_extend;
register char version;
ptrdiff_t lastatmax = -1;
- zic_t one = 1;
- zic_t y2038_boundary = one << 31;
zic_t max_year0;
int defaulttype = -1;
@@ -2794,11 +2881,11 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
updateminmax(leapmaxyear + (leapmaxyear < ZIC_MAX));
}
for (i = 0; i < zonecount; ++i) {
- zp = &zpfirst[i];
+ struct zone const *zp = &zpfirst[i];
if (i < zonecount - 1)
updateminmax(zp->z_untilrule.r_loyear);
for (j = 0; j < zp->z_nrules; ++j) {
- rp = &zp->z_rules[j];
+ struct rule *rp = &zp->z_rules[j];
if (rp->r_lowasnum)
updateminmax(rp->r_loyear);
if (rp->r_hiwasnum)
@@ -2860,6 +2947,8 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
max_year = min_year + years_of_observations;
}
}
+ max_year = max(max_year, (redundant_time / (SECSPERDAY * DAYSPERNYEAR)
+ + EPOCH_YEAR + 1));
max_year0 = max_year;
if (want_bloat()) {
/* For the benefit of older systems,
@@ -2875,22 +2964,23 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
for (i = 0; i < zonecount; ++i) {
struct rule *prevrp = NULL;
- zic_t prevktime;
- INITIALIZE(prevktime);
/*
** A guess that may well be corrected later.
*/
- save = 0;
- zp = &zpfirst[i];
- usestart = i > 0 && (zp - 1)->z_untiltime > min_time;
- useuntil = i < (zonecount - 1);
+ zic_t save = 0;
+ struct zone const *zp = &zpfirst[i];
+ bool usestart = i > 0 && (zp - 1)->z_untiltime > min_time;
+ bool useuntil = i < (zonecount - 1);
+ zic_t stdoff = zp->z_stdoff;
+ zic_t startoff = stdoff;
+ zic_t prevktime;
+ INITIALIZE(prevktime);
if (useuntil && zp->z_untiltime <= min_time)
continue;
- stdoff = zp->z_stdoff;
eat(zp->z_filename, zp->z_linenum);
*startbuf = '\0';
- startoff = zp->z_stdoff;
if (zp->z_nrules == 0) {
+ int type;
save = zp->z_save;
doabbr(startbuf, zp, NULL, zp->z_isdst, save, false);
type = addtype(oadd(zp->z_stdoff, save),
@@ -2901,7 +2991,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
usestart = false;
} else
defaulttype = type;
- } else for (year = min_year; year <= max_year; ++year) {
+ } else {
+ zic_t year;
+ for (year = min_year; year <= max_year; ++year) {
if (useuntil && year > zp->z_untilrule.r_hiyear)
break;
/*
@@ -2910,7 +3002,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
** The former TYPE field was also considered here.
*/
for (j = 0; j < zp->z_nrules; ++j) {
- rp = &zp->z_rules[j];
+ zic_t one = 1;
+ zic_t y2038_boundary = one << 31;
+ struct rule *rp = &zp->z_rules[j];
eats(zp->z_filename, zp->z_linenum,
rp->r_filename, rp->r_linenum);
rp->r_todo = year >= rp->r_loyear &&
@@ -2926,6 +3020,8 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
register ptrdiff_t k;
register zic_t jtime, ktime;
register zic_t offset;
+ struct rule *rp;
+ int type;
INITIALIZE(ktime);
if (useuntil) {
@@ -2948,15 +3044,15 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
*/
k = -1;
for (j = 0; j < zp->z_nrules; ++j) {
- rp = &zp->z_rules[j];
- if (!rp->r_todo)
+ struct rule *r = &zp->z_rules[j];
+ if (!r->r_todo)
continue;
eats(zp->z_filename, zp->z_linenum,
- rp->r_filename, rp->r_linenum);
- offset = rp->r_todisut ? 0 : stdoff;
- if (!rp->r_todisstd)
+ r->r_filename, r->r_linenum);
+ offset = r->r_todisut ? 0 : stdoff;
+ if (!r->r_todisstd)
offset = oadd(offset, save);
- jtime = rp->r_temp;
+ jtime = r->r_temp;
if (jtime == min_time ||
jtime == max_time)
continue;
@@ -2968,11 +3064,11 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
char const *dup_rules_msg =
_("two rules for same instant");
eats(zp->z_filename, zp->z_linenum,
- rp->r_filename, rp->r_linenum);
+ r->r_filename, r->r_linenum);
warning("%s", dup_rules_msg);
- rp = &zp->z_rules[k];
+ r = &zp->z_rules[k];
eats(zp->z_filename, zp->z_linenum,
- rp->r_filename, rp->r_linenum);
+ r->r_filename, r->r_linenum);
error("%s", dup_rules_msg);
}
}
@@ -2980,8 +3076,15 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
break; /* go on to next year */
rp = &zp->z_rules[k];
rp->r_todo = false;
- if (useuntil && ktime >= untiltime)
+ if (useuntil && ktime >= untiltime) {
+ if (!*startbuf
+ && (oadd(zp->z_stdoff, rp->r_save)
+ == startoff))
+ doabbr(startbuf, zp, rp->r_abbrvar,
+ rp->r_isdst, rp->r_save,
+ false);
break;
+ }
save = rp->r_save;
if (usestart && ktime == starttime)
usestart = false;
@@ -3014,6 +3117,7 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
offset = oadd(zp->z_stdoff, rp->r_save);
if (!want_bloat() && !useuntil && !do_extend
&& prevrp && lo_time <= prevktime
+ && redundant_time <= ktime
&& rp->r_hiyear == ZIC_MAX
&& prevrp->r_hiyear == ZIC_MAX)
break;
@@ -3029,20 +3133,19 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
prevrp = rp;
prevktime = ktime;
}
+ }
}
if (usestart) {
- if (*startbuf == '\0' &&
- zp->z_format != NULL &&
- strchr(zp->z_format, '%') == NULL &&
- strchr(zp->z_format, '/') == NULL)
- strcpy(startbuf, zp->z_format);
+ bool isdst = startoff != zp->z_stdoff;
+ if (*startbuf == '\0' && zp->z_format)
+ doabbr(startbuf, zp, disable_percent_s,
+ isdst, save, false);
eat(zp->z_filename, zp->z_linenum);
if (*startbuf == '\0')
error(_("can't determine time zone abbreviation to use just after until time"));
else {
- bool isdst = startoff != zp->z_stdoff;
- type = addtype(startoff, startbuf, isdst,
- startttisstd, startttisut);
+ int type = addtype(startoff, startbuf, isdst,
+ startttisstd, startttisut);
if (defaulttype < 0 && !isdst)
defaulttype = type;
addtt(starttime, type);
@@ -3344,23 +3447,20 @@ byword(const char *word, const struct lookup *table)
return foundlp;
}
-static char **
-getfields(register char *cp)
+static int
+getfields(char *cp, char **array, int arrayelts)
{
register char * dp;
- register char ** array;
register int nsubs;
- if (cp == NULL)
- return NULL;
- array = emalloc(size_product(strlen(cp) + 1, sizeof *array));
nsubs = 0;
for ( ; ; ) {
+ char *dstart;
while (is_space(*cp))
++cp;
if (*cp == '\0' || *cp == '#')
break;
- array[nsubs++] = dp = cp;
+ dstart = dp = cp;
do {
if ((*dp = *cp++) != '"')
++dp;
@@ -3375,9 +3475,13 @@ getfields(register char *cp)
if (is_space(*cp))
++cp;
*dp = '\0';
+ if (nsubs == arrayelts) {
+ error(_("Too many input fields"));
+ exit(EXIT_FAILURE);
+ }
+ array[nsubs++] = dstart + (*dstart == '-' && dp == dstart + 1);
}
- array[nsubs] = NULL;
- return array;
+ return nsubs;
}
static _Noreturn void
diff --git a/ziguard.awk b/ziguard.awk
index 2be6d52..0728baa 100644
--- a/ziguard.awk
+++ b/ziguard.awk
@@ -9,7 +9,11 @@
# it does not do these nonessential tasks now.
#
# Although main and vanguard forms are currently equivalent,
-# this need not always be the case.
+# this need not always be the case. When the two forms differ,
+# this script can convert either from main to vanguard form (needed then),
+# or from vanguard to main form (this conversion would be needed later,
+# after main became rearguard and vanguard became main).
+# There is no need to convert rearguard to other forms.
#
# When converting to vanguard form, the output can use negative SAVE
# values.
@@ -19,14 +23,69 @@
# of the input data as best it can within the constraints of the
# rearguard format.
+# Given a FIELD like "-0:30", return a minute count like -30.
+function get_minutes(field, \
+ sign, hours, minutes)
+{
+ sign = field ~ /^-/ ? -1 : 1
+ hours = +field
+ if (field ~ /:/) {
+ minutes = field
+ sub(/[^:]*:/, "", minutes)
+ }
+ return 60 * hours + sign * minutes
+}
+
+# Given an OFFSET, which is a minute count like 300 or 330,
+# return a %z-style abbreviation like "+05" or "+0530".
+function offset_abbr(offset, \
+ hours, minutes, sign)
+{
+ hours = int(offset / 60)
+ minutes = offset % 60
+ if (minutes) {
+ return sprintf("%+.4d", hours * 100 + minutes);
+ } else {
+ return sprintf("%+.2d", hours)
+ }
+}
+
+# Round TIMESTAMP (a +-hh:mm:ss.dddd string) to the nearest second.
+function round_to_second(timestamp, \
+ hh, mm, ss, seconds, dot_dddd, subseconds)
+{
+ dot_dddd = timestamp
+ if (!sub(/^[+-]?[0-9]+:[0-9]+:[0-9]+\./, ".", dot_dddd))
+ return timestamp
+ hh = mm = ss = timestamp
+ sub(/^[-+]?[0-9]+:[0-9]+:/, "", ss)
+ sub(/^[-+]?[0-9]+:/, "", mm)
+ sub(/^[-+]?/, "", hh)
+ seconds = 3600 * hh + 60 * mm + ss
+ subseconds = +dot_dddd
+ seconds += 0.5 < subseconds || ((subseconds == 0.5) && (seconds % 2));
+ return sprintf("%s%d:%.2d:%.2d", timestamp ~ /^-/ ? "-" : "", \
+ seconds / 3600, seconds / 60 % 60, seconds % 60)
+}
+
BEGIN {
dataform_type["vanguard"] = 1
dataform_type["main"] = 1
dataform_type["rearguard"] = 1
+ if (PACKRATLIST) {
+ while (getline <PACKRATLIST) {
+ if ($0 ~ /^#/) continue
+ packratlist[$3] = 1
+ }
+ }
+
# The command line should set DATAFORM.
if (!dataform_type[DATAFORM]) exit 1
- vanguard = DATAFORM == "vanguard"
+}
+
+$1 == "#PACKRATLIST" && $2 == PACKRATLIST {
+ sub(/^#PACKRATLIST[\t ]+[^\t ]+[\t ]+/, "")
}
/^Zone/ { zone = $2 }
@@ -38,7 +97,7 @@ DATAFORM != "main" {
# If this line should differ due to Czechoslovakia using negative SAVE values,
# uncomment the desired version and comment out the undesired one.
if (zone == "Europe/Prague" && /^#?[\t ]+[01]:00[\t ]/ && /1947 Feb 23/) {
- if (($(in_comment + 2) != "-") == vanguard) {
+ if (($(in_comment + 2) != "-") == (DATAFORM != "rearguard")) {
uncomment = in_comment
} else {
comment_out = !in_comment
@@ -54,7 +113,7 @@ DATAFORM != "main" {
if (Rule_Eire || Zone_Dublin_post_1968) {
if ((Rule_Eire \
|| (Zone_Dublin_post_1968 && $(in_comment + 3) == "IST/GMT")) \
- == vanguard) {
+ == (DATAFORM != "rearguard")) {
uncomment = in_comment
} else {
comment_out = !in_comment
@@ -71,11 +130,20 @@ DATAFORM != "main" {
&& ((1994 <= $(in_comment + 4) && $(in_comment + 4) <= 2017) \
|| in_comment + 3 == NF))))
if (Rule_Namibia || Zone_using_Namibia_rule) {
- if ((Rule_Namibia \
- ? ($(in_comment + 9) ~ /^-/ \
- || ($(in_comment + 9) == 0 && $(in_comment + 10) == "CAT")) \
- : $(in_comment + 1) == "2:00" && $(in_comment + 2) == "Namibia") \
- == vanguard) {
+ if ((Rule_Namibia \
+ ? ($9 ~ /^-/ || ($9 == 0 && $10 == "CAT")) \
+ : $(in_comment + 1) == "2:00" && $(in_comment + 2) == "Namibia") \
+ == (DATAFORM != "rearguard")) {
+ uncomment = in_comment
+ } else {
+ comment_out = !in_comment
+ }
+ }
+
+ # If this line should differ due to Portugal benefiting from %z if supported,
+ # uncomment the desired version and comment out the undesired one.
+ if (/^#?[\t ]+-[12]:00[\t ]+Port[\t ]+[%+-]/) {
+ if (/%z/ == (DATAFORM == "vanguard")) {
uncomment = in_comment
} else {
comment_out = !in_comment
@@ -89,37 +157,143 @@ DATAFORM != "main" {
sub(/^/, "#")
}
- # In rearguard format, change the Japan rule line with "Sat>=8 25:00"
- # to "Sun>=9 1:00", to cater to zic before 2007 and to older Java.
- if (!vanguard && $1 == "Rule" && $7 == "Sat>=8" && $8 == "25:00") {
- sub(/Sat>=8/, "Sun>=9")
- sub(/25:00/, " 1:00")
+ # Prefer %z in vanguard form, explicit abbreviations otherwise.
+ if (DATAFORM == "vanguard") {
+ sub(/^(Zone[\t ]+[^\t ]+)?[\t ]+[^\t ]+[\t ]+[^\t ]+[\t ]+[-+][^\t ]+/, \
+ "&CHANGE-TO-%z")
+ sub(/-00CHANGE-TO-%z/, "-00")
+ sub(/[-+][^\t ]+CHANGE-TO-/, "")
+ } else {
+ if (/^[^#]*%z/) {
+ stdoff_column = 2 * /^Zone/ + 1
+ rules_column = stdoff_column + 1
+ stdoff = get_minutes($stdoff_column)
+ rules = $rules_column
+ stdabbr = offset_abbr(stdoff)
+ if (rules == "-") {
+ abbr = stdabbr
+ } else {
+ dstabbr_only = rules ~ /^[+0-9-]/
+ if (dstabbr_only) {
+ dstoff = get_minutes(rules)
+ } else {
+ # The DST offset is normally an hour, but there are special cases.
+ if (rules == "Morocco" && NF == 3) {
+ dstoff = -60
+ } else if (rules == "NBorneo") {
+ dstoff = 20
+ } else if (((rules == "Cook" || rules == "LH") && NF == 3) \
+ || (rules == "Uruguay" \
+ && /[\t ](1942 Dec 14|1960|1970|1974 Dec 22)$/)) {
+ dstoff = 30
+ } else if (rules == "Uruguay" && /[\t ]1974 Mar 10$/) {
+ dstoff = 90
+ } else {
+ dstoff = 60
+ }
+ }
+ dstabbr = offset_abbr(stdoff + dstoff)
+ if (dstabbr_only) {
+ abbr = dstabbr
+ } else {
+ abbr = stdabbr "/" dstabbr
+ }
+ }
+ sub(/%z/, abbr)
+ }
}
- # In rearguard format, change the Morocco lines with negative SAVE values
- # to use positive SAVE values.
- if (!vanguard && $1 == "Rule" && $2 == "Morocco" && $4 == 2018 \
- && $6 == "Oct") {
- sub(/\t2018\t/, "\t2017\t")
+ # Normally, prefer whole seconds. However, prefer subseconds
+ # if generating vanguard form and the otherwise-undocumented
+ # VANGUARD_SUBSECONDS environment variable is set.
+ # This relies on #STDOFF comment lines in the data.
+ # It is for hypothetical clients that support UT offsets that are
+ # not integer multiples of one second (e.g., Europe/Lisbon, 1884 to 1912).
+ # No known clients need this currently, and this experimental
+ # feature may be changed or withdrawn in future releases.
+ if ($1 == "#STDOFF") {
+ stdoff = $2
+ rounded_stdoff = round_to_second(stdoff)
+ if (DATAFORM == "vanguard" && ENVIRON["VANGUARD_SUBSECONDS"]) {
+ stdoff_subst[0] = rounded_stdoff
+ stdoff_subst[1] = stdoff
+ } else {
+ stdoff_subst[0] = stdoff
+ stdoff_subst[1] = rounded_stdoff
+ }
+ } else if (stdoff_subst[0]) {
+ stdoff_column = 2 * /^Zone/ + 1
+ stdoff_column_val = $stdoff_column
+ if (stdoff_column_val == stdoff_subst[0]) {
+ sub(stdoff_subst[0], stdoff_subst[1])
+ } else if (stdoff_column_val != stdoff_subst[1]) {
+ stdoff_subst[0] = 0
+ }
}
- if (!vanguard && $1 == "Rule" && $2 == "Morocco" && 2019 <= $3) {
- if ($9 == "0") {
- last_std_date = $3 " " $6 " " $7 " " $8
- sub(/\t0\t/, "\t1:00\t")
+
+ # In rearguard form, change the Japan rule line with "Sat>=8 25:00"
+ # to "Sun>=9 1:00", to cater to zic before 2007 and to older Java.
+ if (/^Rule/ && $2 == "Japan") {
+ if (DATAFORM == "rearguard") {
+ if ($7 == "Sat>=8" && $8 == "25:00") {
+ sub(/Sat>=8/, "Sun>=9")
+ sub(/25:00/, " 1:00")
+ }
} else {
- sub(/\t-1:00\t/, "\t0\t")
+ if ($7 == "Sun>=9" && $8 == "1:00") {
+ sub(/Sun>=9/, "Sat>=8")
+ sub(/ 1:00/, "25:00")
+ }
}
}
- if (!vanguard && $1 == "1:00" && $2 == "Morocco" && $3 == "+01/+00") {
- # This introduces a transition from 01:59:59 +00 to 03:00:00 +01
- # with both times being standard (i.e., a change to standard UT offset).
- # This is rearguard's way to approximate the actual prediction,
- # which is that of an ordinary transition from DST to standard time.
- sub(/1:00\tMorocco\t\+01\/\+00$/,
- "0:00\tMorocco\t+00/+01\t" last_std_date "\n\t\t\t 1:00\t-\t+01")
+
+ # In rearguard form, change the Morocco lines with negative SAVE values
+ # to use positive SAVE values.
+ if ($2 == "Morocco") {
+ if (/^Rule/) {
+ if ($4 ~ /^201[78]$/ && $6 == "Oct") {
+ if (DATAFORM == "rearguard") {
+ sub(/\t2018\t/, "\t2017\t")
+ } else {
+ sub(/\t2017\t/, "\t2018\t")
+ }
+ }
+
+ if (2019 <= $3) {
+ if ($8 == "2:00") {
+ if (DATAFORM == "rearguard") {
+ sub(/\t0\t/, "\t1:00\t")
+ } else {
+ sub(/\t1:00\t/, "\t0\t")
+ }
+ } else {
+ if (DATAFORM == "rearguard") {
+ sub(/\t-1:00\t/, "\t0\t")
+ } else {
+ sub(/\t0\t/, "\t-1:00\t")
+ }
+ }
+ }
+ }
+ if ($1 ~ /^[+0-9-]/ && NF == 3) {
+ if (DATAFORM == "rearguard") {
+ sub(/1:00\tMorocco/, "0:00\tMorocco")
+ sub(/\t\+01\/\+00$/, "\t+00/+01")
+ } else {
+ sub(/0:00\tMorocco/, "1:00\tMorocco")
+ sub(/\t\+00\/+01$/, "\t+01/+00")
+ }
+ }
}
}
+/^Zone/ {
+ packrat_ignored = FILENAME == PACKRATDATA && PACKRATLIST && !packratlist[$2];
+}
+packrat_ignored && !/^Rule/ {
+ sub(/^/, "#")
+}
+
# If a Link line is followed by a Link or Zone line for the same data, comment
# out the Link line. This can happen if backzone overrides a Link
# with a Zone or a different Link.
diff --git a/zishrink.awk b/zishrink.awk
index 1947c7c..66968e8 100644
--- a/zishrink.awk
+++ b/zishrink.awk
@@ -23,7 +23,7 @@ function record_hash(n, name)
function gen_rule_name(name, \
n)
{
- # Use a simple memonic: the first two letters.
+ # Use a simple mnemonic: the first two letters.
n = substr(name, 1, 2)
record_hash(n, name)
# printf "# %s = %s\n", n, name
@@ -150,10 +150,19 @@ function prehash_rule_names( \
}
}
+function make_line(n, field, \
+ f, r)
+{
+ r = field[1]
+ for (f = 2; f <= n; f++)
+ r = r " " field[f]
+ return r
+}
+
# Process the input line LINE and save it for later output.
function process_input_line(line, \
- field, end, i, n, startdef, \
+ f, field, end, i, n, r, startdef, \
linkline, ruleline, zoneline)
{
# Remove comments, normalize spaces, and append a space to each line.
@@ -218,12 +227,11 @@ function process_input_line(line, \
n = split(line, field)
- # Abbreviate rule names.
- i = zoneline ? 4 : linkline ? 0 : 2
- if (i && field[i] ~ /^[^-+0-9]/) {
- if (!rule[field[i]])
- rule[field[i]] = gen_rule_name(field[i])
- field[i] = rule[field[i]]
+ # Record which rule names are used, and generate their abbreviations.
+ f = zoneline ? 4 : linkline || ruleline ? 0 : 2
+ r = field[f]
+ if (r ~ /^[^-+0-9]/) {
+ rule_used[r] = 1
}
# If this zone supersedes an earlier one, delete the earlier one
@@ -246,10 +254,38 @@ function process_input_line(line, \
zonedef[zonename] = nout + 1
# Save the line for later output.
- line = field[1]
- for (i = 2; i <= n; i++)
- line = line " " field[i]
- output_line[nout++] = line
+ output_line[nout++] = make_line(n, field)
+}
+
+function omit_unused_rules( \
+ i, field)
+{
+ for (i = 0; i < nout; i++) {
+ split(output_line[i], field)
+ if (field[1] == "R" && !rule_used[field[2]]) {
+ output_line[i] = ""
+ }
+ }
+}
+
+function abbreviate_rule_names( \
+ abbr, f, field, i, n, r)
+{
+ for (i = 0; i < nout; i++) {
+ n = split(output_line[i], field)
+ if (n) {
+ f = field[1] == "Z" ? 4 : field[1] == "L" ? 0 : 2
+ r = field[f]
+ if (r ~ /^[^-+0-9]/) {
+ abbr = rule[r]
+ if (!abbr) {
+ rule[r] = abbr = gen_rule_name(r)
+ }
+ field[f] = abbr
+ output_line[i] = make_line(n, field)
+ }
+ }
+ }
}
function output_saved_lines( \
@@ -314,5 +350,7 @@ BEGIN {
}
END {
+ omit_unused_rules()
+ abbreviate_rule_names()
output_saved_lines()
}
diff --git a/zone.tab b/zone.tab
index 086458f..1f73dda 100644
--- a/zone.tab
+++ b/zone.tab
@@ -130,7 +130,7 @@ CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west)
CA +6227-11421 America/Yellowknife Mountain - NT (central)
CA +682059-1334300 America/Inuvik Mountain - NT (west)
CA +4906-11631 America/Creston MST - BC (Creston)
-CA +5946-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John)
+CA +5546-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John)
CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson)
CA +6043-13503 America/Whitehorse MST - Yukon (east)
CA +6404-13925 America/Dawson MST - Yukon (west)
@@ -400,7 +400,7 @@ TT +1039-06131 America/Port_of_Spain
TV -0831+17913 Pacific/Funafuti
TW +2503+12130 Asia/Taipei
TZ -0648+03917 Africa/Dar_es_Salaam
-UA +5026+03031 Europe/Kiev Ukraine (most areas)
+UA +5026+03031 Europe/Kyiv Ukraine (most areas)
UA +4837+02218 Europe/Uzhgorod Transcarpathia
UA +4750+03510 Europe/Zaporozhye Zaporozhye and east Lugansk
UG +0019+03225 Africa/Kampala
diff --git a/zone1970.tab b/zone1970.tab
index c614be8..3e1948c 100644
--- a/zone1970.tab
+++ b/zone1970.tab
@@ -34,7 +34,7 @@
#country-
#codes coordinates TZ comments
AD +4230+00131 Europe/Andorra
-AE,OM +2518+05518 Asia/Dubai
+AE,OM,RE,SC,TF +2518+05518 Asia/Dubai UAE, Oman, Réunion, Seychelles, Crozet, Scattered Is
AF +3431+06912 Asia/Kabul
AL +4120+01950 Europe/Tirane
AM +4011+04430 Asia/Yerevan
@@ -44,7 +44,6 @@ AQ -6736+06253 Antarctica/Mawson Mawson
AQ -6448-06406 Antarctica/Palmer Palmer
AQ -6734-06808 Antarctica/Rothera Rothera
AQ -720041+0023206 Antarctica/Troll Troll
-AQ -7824+10654 Antarctica/Vostok Vostok
AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF)
AR -3124-06411 America/Argentina/Cordoba Argentina (most areas: CB, CC, CN, ER, FM, MN, SE, SF)
AR -2447-06525 America/Argentina/Salta Salta (SA, LP, NQ, RN)
@@ -74,10 +73,9 @@ AU -3143+12852 Australia/Eucla Western Australia (Eucla)
AZ +4023+04951 Asia/Baku
BB +1306-05937 America/Barbados
BD +2343+09025 Asia/Dhaka
-BE +5050+00420 Europe/Brussels
+BE,LU,NL +5050+00420 Europe/Brussels
BG +4241+02319 Europe/Sofia
BM +3217-06446 Atlantic/Bermuda
-BN +0456+11455 Asia/Brunei
BO -1630-06809 America/La_Paz
BR -0351-03225 America/Noronha Atlantic islands
BR -0127-04829 America/Belem Pará (east); Amapá
@@ -118,30 +116,27 @@ CA +5333-11328 America/Edmonton Mountain - AB; BC (E); SK (W)
CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west)
CA +6227-11421 America/Yellowknife Mountain - NT (central)
CA +682059-1334300 America/Inuvik Mountain - NT (west)
-CA +5946-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John)
+CA +5546-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John)
CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson)
CA +6043-13503 America/Whitehorse MST - Yukon (east)
CA +6404-13925 America/Dawson MST - Yukon (west)
CA +4916-12307 America/Vancouver Pacific - BC (most areas)
-CC -1210+09655 Indian/Cocos
CH,DE,LI +4723+00832 Europe/Zurich Swiss time
-CI,BF,GH,GM,GN,ML,MR,SH,SL,SN,TG +0519-00402 Africa/Abidjan
+CI,BF,GH,GM,GN,IS,ML,MR,SH,SL,SN,TG +0519-00402 Africa/Abidjan
CK -2114-15946 Pacific/Rarotonga
CL -3327-07040 America/Santiago Chile (most areas)
CL -5309-07055 America/Punta_Arenas Region of Magallanes
CL -2709-10926 Pacific/Easter Easter Island
CN +3114+12128 Asia/Shanghai Beijing Time
-CN +4348+08735 Asia/Urumqi Xinjiang Time
+CN,AQ +4348+08735 Asia/Urumqi Xinjiang Time, Vostok
CO +0436-07405 America/Bogota
CR +0956-08405 America/Costa_Rica
CU +2308-08222 America/Havana
CV +1455-02331 Atlantic/Cape_Verde
-CX -1025+10543 Indian/Christmas
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
+DE,DK,NO,SE,SJ +5230+01322 Europe/Berlin Germany (most areas), Scandinavia
DO +1828-06954 America/Santo_Domingo
DZ +3647+00303 Africa/Algiers
EC -0210-07950 America/Guayaquil Ecuador (mainland)
@@ -155,11 +150,9 @@ ES +2806-01524 Atlantic/Canary Canary Islands
FI,AX +6010+02458 Europe/Helsinki
FJ -1808+17825 Pacific/Fiji
FK -5142-05751 Atlantic/Stanley
-FM +0725+15147 Pacific/Chuuk Chuuk/Truk, Yap
-FM +0658+15813 Pacific/Pohnpei Pohnpei/Ponape
FM +0519+16259 Pacific/Kosrae Kosrae
FO +6201-00646 Atlantic/Faroe
-FR +4852+00220 Europe/Paris
+FR,MC +4852+00220 Europe/Paris
GB,GG,IM,JE +513030-0000731 Europe/London
GE +4143+04449 Asia/Tbilisi
GF +0456-05220 America/Cayenne
@@ -188,14 +181,13 @@ IN +2232+08822 Asia/Kolkata
IO -0720+07225 Indian/Chagos
IQ +3321+04425 Asia/Baghdad
IR +3540+05126 Asia/Tehran
-IS +6409-02151 Atlantic/Reykjavik
IT,SM,VA +4154+01229 Europe/Rome
JM +175805-0764736 America/Jamaica
JO +3157+03556 Asia/Amman
JP +353916+1394441 Asia/Tokyo
KE,DJ,ER,ET,KM,MG,SO,TZ,UG,YT -0117+03649 Africa/Nairobi
KG +4254+07436 Asia/Bishkek
-KI +0125+17300 Pacific/Tarawa Gilbert Islands
+KI,MH,TV,UM,WF +0125+17300 Pacific/Tarawa Gilberts, Marshalls, Tuvalu, Wallis & Futuna, Wake
KI -0247-17143 Pacific/Kanton Phoenix Islands
KI +0152-15720 Pacific/Kiritimati Line Islands
KP +3901+12545 Asia/Pyongyang
@@ -211,15 +203,12 @@ LB +3353+03530 Asia/Beirut
LK +0656+07951 Asia/Colombo
LR +0618-01047 Africa/Monrovia
LT +5441+02519 Europe/Vilnius
-LU +4936+00609 Europe/Luxembourg
LV +5657+02406 Europe/Riga
LY +3254+01311 Africa/Tripoli
MA +3339-00735 Africa/Casablanca
-MC +4342+00723 Europe/Monaco
MD +4700+02850 Europe/Chisinau
-MH +0709+17112 Pacific/Majuro Marshall Islands (most areas)
MH +0905+16720 Pacific/Kwajalein Kwajalein
-MM +1647+09610 Asia/Yangon
+MM,CC +1647+09610 Asia/Yangon
MN +4755+10653 Asia/Ulaanbaatar Mongolia (most areas)
MN +4801+09139 Asia/Hovd Bayan-Ölgii, Govi-Altai, Hovd, Uvs, Zavkhan
MN +4804+11430 Asia/Choibalsan Dornod, Sükhbaatar
@@ -227,7 +216,7 @@ MO +221150+1133230 Asia/Macau
MQ +1436-06105 America/Martinique
MT +3554+01431 Europe/Malta
MU -2010+05730 Indian/Mauritius
-MV +0410+07330 Indian/Maldives
+MV,TF +0410+07330 Indian/Maldives Maldives, Kerguelen, St Paul I, Amsterdam I
MX +1924-09909 America/Mexico_City Central Time
MX +2105-08646 America/Cancun Eastern Standard Time - Quintana Roo
MX +2058-08937 America/Merida Central Time - Campeche, Yucatán
@@ -239,16 +228,13 @@ MX +2934-10425 America/Ojinaga Mountain Time US - Chihuahua (US border)
MX +2904-11058 America/Hermosillo Mountain Standard Time - Sonora
MX +3232-11701 America/Tijuana Pacific Time US - Baja California
MX +2048-10515 America/Bahia_Banderas Central Time - Bahía de Banderas
-MY +0310+10142 Asia/Kuala_Lumpur Malaysia (peninsula)
-MY +0133+11020 Asia/Kuching Sabah, Sarawak
+MY,BN +0133+11020 Asia/Kuching Sabah, Sarawak, Brunei
MZ,BI,BW,CD,MW,RW,ZM,ZW -2558+03235 Africa/Maputo Central Africa Time
NA -2234+01706 Africa/Windhoek
NC -2216+16627 Pacific/Noumea
NF -2903+16758 Pacific/Norfolk
NG,AO,BJ,CD,CF,CG,CM,GA,GQ,NE +0627+00324 Africa/Lagos West Africa Time
NI +1209-08617 America/Managua
-NL +5222+00454 Europe/Amsterdam
-NO,SJ +5955+01045 Europe/Oslo
NP +2743+08519 Asia/Kathmandu
NR -0031+16655 Pacific/Nauru
NU -1901-16955 Pacific/Niue
@@ -259,7 +245,7 @@ PE -1203-07703 America/Lima
PF -1732-14934 Pacific/Tahiti Society Islands
PF -0900-13930 Pacific/Marquesas Marquesas Islands
PF -2308-13457 Pacific/Gambier Gambier Islands
-PG,AQ -0930+14710 Pacific/Port_Moresby Papua New Guinea (most areas), Dumont d'Urville
+PG,AQ,FM -0930+14710 Pacific/Port_Moresby Papua New Guinea (most areas), Chuuk, Yap, Dumont d'Urville
PG -0613+15534 Pacific/Bougainville Bougainville
PH +1435+12100 Asia/Manila
PK +2452+06703 Asia/Karachi
@@ -275,7 +261,6 @@ PT +3744-02540 Atlantic/Azores Azores
PW +0720+13429 Pacific/Palau
PY -2516-05740 America/Asuncion
QA,BH +2517+05132 Asia/Qatar
-RE,TF -2052+05528 Indian/Reunion Réunion, Crozet, Scattered Islands
RO +4426+02606 Europe/Bucharest
RS,BA,HR,ME,MK,SI +4450+02030 Europe/Belgrade
RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad
@@ -307,10 +292,8 @@ RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); North Kuril Is
RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka
RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea
SA,AQ,KW,YE +2438+04643 Asia/Riyadh Arabia, Syowa
-SB -0932+16012 Pacific/Guadalcanal
-SC -0440+05528 Indian/Mahe
+SB,FM -0932+16012 Pacific/Guadalcanal Solomons, Pohnpei
SD +1536+03232 Africa/Khartoum
-SE +5920+01803 Europe/Stockholm
SG,MY +0117+10351 Asia/Singapore Singapore, peninsular Malaysia
SR +0550-05510 America/Paramaribo
SS +0451+03137 Africa/Juba
@@ -319,8 +302,7 @@ SV +1342-08912 America/El_Salvador
SY +3330+03618 Asia/Damascus
TC +2128-07108 America/Grand_Turk
TD +1207+01503 Africa/Ndjamena
-TF -492110+0701303 Indian/Kerguelen Kerguelen, St Paul Island, Amsterdam Island
-TH,KH,LA,VN +1345+10031 Asia/Bangkok Indochina (most areas)
+TH,CX,KH,LA,VN +1345+10031 Asia/Bangkok Indochina (most areas)
TJ +3835+06848 Asia/Dushanbe
TK -0922-17114 Pacific/Fakaofo
TL -0833+12535 Asia/Dili
@@ -328,12 +310,10 @@ TM +3757+05823 Asia/Ashgabat
TN +3648+01011 Africa/Tunis
TO -210800-1751200 Pacific/Tongatapu
TR +4101+02858 Europe/Istanbul
-TV -0831+17913 Pacific/Funafuti
TW +2503+12130 Asia/Taipei
-UA +5026+03031 Europe/Kiev Ukraine (most areas)
+UA +5026+03031 Europe/Kyiv Ukraine (most areas)
UA +4837+02218 Europe/Uzhgorod Transcarpathia
UA +4750+03510 Europe/Zaporozhye Zaporozhye and east Lugansk
-UM +1917+16637 Pacific/Wake Wake Island
US +404251-0740023 America/New_York Eastern (most areas)
US +421953-0830245 America/Detroit Eastern - MI (most areas)
US +381515-0854534 America/Kentucky/Louisville Eastern - KY (Louisville area)
@@ -369,6 +349,5 @@ UZ +4120+06918 Asia/Tashkent Uzbekistan (east)
VE +1030-06656 America/Caracas
VN +1045+10640 Asia/Ho_Chi_Minh Vietnam (south)
VU -1740+16825 Pacific/Efate
-WF -1318-17610 Pacific/Wallis
WS -1350-17144 Pacific/Apia
ZA,LS,SZ -2615+02800 Africa/Johannesburg