Welcome to 2022b:
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.
This commit is contained in:
parent
728612bd0e
commit
0129e5c6c8
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: asctime.c,v 1.27 2019/01/27 02:40:49 dholland Exp $ */
|
||||
/* $NetBSD: asctime.c,v 1.28 2022/08/16 10:56:21 christos Exp $ */
|
||||
|
||||
/* asctime and asctime_r a la POSIX and ISO C, except pad years before 1000. */
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
|||
#if 0
|
||||
static char elsieid[] = "@(#)asctime.c 8.5";
|
||||
#else
|
||||
__RCSID("$NetBSD: asctime.c,v 1.27 2019/01/27 02:40:49 dholland Exp $");
|
||||
__RCSID("$NetBSD: asctime.c,v 1.28 2022/08/16 10:56:21 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
|
@ -32,12 +32,6 @@ __RCSID("$NetBSD: asctime.c,v 1.27 2019/01/27 02:40:49 dholland Exp $");
|
|||
__weak_alias(asctime_r,_asctime_r)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** 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.
|
||||
|
@ -50,24 +44,16 @@ __weak_alias(asctime_r,_asctime_r)
|
|||
** 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
|
||||
|
@ -75,12 +61,10 @@ __weak_alias(asctime_r,_asctime_r)
|
|||
** 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(const struct tm *timeptr, char *buf)
|
||||
|
@ -95,7 +79,7 @@ asctime_r(const struct tm *timeptr, char *buf)
|
|||
const char * wn;
|
||||
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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: localtime.c,v 1.133 2022/03/25 19:34:04 rillig Exp $ */
|
||||
/* $NetBSD: localtime.c,v 1.134 2022/08/16 10:56:21 christos Exp $ */
|
||||
|
||||
/* Convert timestamp from time_t to struct tm. */
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
|||
#if 0
|
||||
static char elsieid[] = "@(#)localtime.c 8.17";
|
||||
#else
|
||||
__RCSID("$NetBSD: localtime.c,v 1.133 2022/03/25 19:34:04 rillig Exp $");
|
||||
__RCSID("$NetBSD: localtime.c,v 1.134 2022/08/16 10:56:21 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
|
@ -37,28 +37,25 @@ __weak_alias(tzname,_tzname)
|
|||
#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 | O_CLOEXEC)
|
||||
#endif /* defined O_BINARY */
|
||||
#ifndef O_BINARY
|
||||
#define OPEN_MODE (O_RDONLY | O_CLOEXEC)
|
||||
#endif /* !defined O_BINARY */
|
||||
# define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#ifndef WILDABBR
|
||||
/*
|
||||
|
@ -80,12 +77,13 @@ __weak_alias(tzname,_tzname)
|
|||
** 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.
|
||||
|
@ -94,7 +92,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
|
||||
|
||||
typedef int_fast64_t __time_t;
|
||||
|
@ -112,9 +110,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";
|
||||
|
||||
|
@ -122,13 +117,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 */
|
||||
|
||||
#define state __state
|
||||
|
@ -142,9 +137,8 @@ struct state {
|
|||
__time_t ats[TZ_MAX_TIMES];
|
||||
unsigned char types[TZ_MAX_TIMES];
|
||||
struct ttinfo ttis[TZ_MAX_TYPES];
|
||||
char chars[/*CONSTCOND*/
|
||||
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.
|
||||
|
@ -181,7 +175,7 @@ static bool tzparse(char const *, struct state *, struct state *);
|
|||
static timezone_t gmtptr;
|
||||
|
||||
#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];
|
||||
|
@ -351,42 +345,59 @@ 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 timezone_t 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] =
|
||||
(__aconst char *) __UNCONST(sp ? wildabbr : gmt);
|
||||
tzname[0] = tzname[1] = __UNCONST(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)
|
||||
update_tzname_etc(sp, &sp->ttis[i]);
|
||||
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
|
||||
|
@ -437,8 +448,7 @@ union local_storage {
|
|||
} u;
|
||||
|
||||
/* The file name to be opened. */
|
||||
char fullname[/*CONSTCOND*/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
|
||||
|
@ -499,7 +509,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;
|
||||
|
||||
|
@ -1450,8 +1460,8 @@ tzparse(const char *name, struct state *sp, struct state *basep)
|
|||
static void
|
||||
gmtload(struct state *const sp)
|
||||
{
|
||||
if (tzload(gmt, sp, true) != 0)
|
||||
(void)tzparse("GMT0", sp, NULL);
|
||||
if (tzload(etc_utc, sp, true) != 0)
|
||||
(void)tzparse("UTC0", sp, NULL);
|
||||
}
|
||||
|
||||
/* Initialize *SP to a value appropriate for the TZ setting NAME.
|
||||
|
@ -1469,7 +1479,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 {
|
||||
|
@ -1588,7 +1598,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.
|
||||
*/
|
||||
|
||||
|
@ -1735,7 +1745,7 @@ gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset,
|
|||
*/
|
||||
if (result)
|
||||
result->TM_ZONE = offset ? __UNCONST(wildabbr) : gmtptr ?
|
||||
gmtptr->chars : __UNCONST(gmt);
|
||||
gmtptr->chars : __UNCONST(utc);
|
||||
#endif /* defined TM_ZONE */
|
||||
return result;
|
||||
}
|
||||
|
@ -1983,7 +1993,7 @@ ctime_rz(const timezone_t sp, const time_t * timep, char *buf)
|
|||
*/
|
||||
|
||||
#ifndef WRONG
|
||||
#define WRONG ((time_t)-1)
|
||||
# define WRONG ((time_t)-1)
|
||||
#endif /* !defined WRONG */
|
||||
|
||||
/*
|
||||
|
@ -2233,10 +2243,10 @@ again:
|
|||
&& (yourtm.TM_GMTOFF < 0
|
||||
? (-SECSPERDAY <= yourtm.TM_GMTOFF
|
||||
&& (mytm.TM_GMTOFF <=
|
||||
(/*CONSTCOND*/SMALLEST(INT_FAST32_MAX, LONG_MAX)
|
||||
(min(INT_FAST32_MAX, LONG_MAX)
|
||||
+ yourtm.TM_GMTOFF)))
|
||||
: (yourtm.TM_GMTOFF <= SECSPERDAY
|
||||
&& ((/*CONSTCOND*/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.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Private header for tzdb code. */
|
||||
|
||||
/* $NetBSD: private.h,v 1.58 2022/03/22 17:48:39 christos Exp $ */
|
||||
/* $NetBSD: private.h,v 1.59 2022/08/16 10:56:21 christos Exp $ */
|
||||
|
||||
#ifndef PRIVATE_H
|
||||
#define PRIVATE_H
|
||||
|
@ -48,7 +48,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
|
||||
|
@ -67,51 +67,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
|
||||
|
@ -119,8 +119,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. */
|
||||
|
@ -198,11 +198,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
|
||||
|
@ -238,7 +238,7 @@
|
|||
#endif
|
||||
|
||||
#ifndef R_OK
|
||||
#define R_OK 4
|
||||
# define R_OK 4
|
||||
#endif /* !defined R_OK */
|
||||
|
||||
/*
|
||||
|
@ -248,14 +248,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
|
||||
|
@ -374,14 +374,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__
|
||||
|
@ -655,6 +655,11 @@ time_t time2posix_z(timezone_t __restrict, time_t) ATTRIBUTE_PURE;
|
|||
#define TYPE_SIGNED(type) (/*CONSTCOND*/((type) -1) < 0)
|
||||
#define TWOS_COMPLEMENT(t) (/*CONSTCOND*/(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. */
|
||||
|
@ -760,47 +765,63 @@ 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)
|
||||
#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
|
||||
#define MONSPERYEAR 12
|
||||
#ifndef SECSPERMIN
|
||||
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 */
|
||||
};
|
||||
#endif
|
||||
|
||||
#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
|
||||
|
||||
#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
|
||||
#ifndef TM_SUNDAY
|
||||
enum {
|
||||
TM_SUNDAY,
|
||||
TM_MONDAY,
|
||||
TM_TUESDAY,
|
||||
TM_WEDNESDAY,
|
||||
TM_THURSDAY,
|
||||
TM_FRIDAY,
|
||||
TM_SATURDAY
|
||||
};
|
||||
#endif
|
||||
|
||||
#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
|
||||
#ifndef TM_JANUARY
|
||||
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
|
||||
};
|
||||
#endif
|
||||
|
||||
#define TM_YEAR_BASE 1900
|
||||
#define TM_WDAY_BASE TM_MONDAY
|
||||
|
||||
#define EPOCH_YEAR 1970
|
||||
#define EPOCH_WDAY TM_THURSDAY
|
||||
#ifndef TM_YEAR_BASE
|
||||
enum {
|
||||
TM_YEAR_BASE = 1900,
|
||||
TM_WDAY_BASE = TM_MONDAY,
|
||||
EPOCH_YEAR = 1970,
|
||||
EPOCH_WDAY = TM_THURSDAY
|
||||
};
|
||||
#endif
|
||||
|
||||
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: strftime.c,v 1.49 2021/10/22 14:26:04 christos Exp $ */
|
||||
/* $NetBSD: strftime.c,v 1.50 2022/08/16 10:56:21 christos Exp $ */
|
||||
|
||||
/* Convert a broken-down timestamp to a string. */
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
|||
static char elsieid[] = "@(#)strftime.c 7.64";
|
||||
static char elsieid[] = "@(#)strftime.c 8.3";
|
||||
#else
|
||||
__RCSID("$NetBSD: strftime.c,v 1.49 2021/10/22 14:26:04 christos Exp $");
|
||||
__RCSID("$NetBSD: strftime.c,v 1.50 2022/08/16 10:56:21 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
|
@ -93,7 +93,7 @@ static char * _fmt(const timezone_t, const char *, const struct tm *, char *,
|
|||
static char * _yconv(int, int, bool, bool, char *, const char *, locale_t);
|
||||
|
||||
#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 */
|
||||
|
||||
#define IN_NONE 0
|
||||
|
@ -376,23 +376,10 @@ label:
|
|||
|
||||
tm = *t;
|
||||
mkt = mktime_z(sp, &tm);
|
||||
if (mkt == (time_t) -1) {
|
||||
/* Fail unless this -1
|
||||
* represents a valid time.
|
||||
*/
|
||||
struct tm tm_1;
|
||||
#define sametm(tm1, tm2) \
|
||||
((tm1)->tm_year == (tm2)->tm_year && \
|
||||
(tm1)->tm_yday == (tm2)->tm_yday && \
|
||||
(tm1)->tm_hour == (tm2)->tm_hour && \
|
||||
(tm1)->tm_min == (tm2)->tm_min && \
|
||||
(tm1)->tm_sec == (tm2)->tm_sec)
|
||||
if (!localtime_rz(sp, &mkt,
|
||||
&tm_1))
|
||||
return NULL;
|
||||
if (!sametm(&tm, &tm_1))
|
||||
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. */
|
||||
/* CONSTCOND */
|
||||
if (TYPE_SIGNED(time_t)) {
|
||||
intmax_t n = mkt;
|
||||
|
@ -667,15 +654,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 = "-";
|
||||
|
@ -793,7 +780,7 @@ _yconv(int a, int b, bool convert_top, bool convert_yy,
|
|||
int lead;
|
||||
int trail;
|
||||
|
||||
#define DIVISOR 100
|
||||
int DIVISOR = 100;
|
||||
trail = a % DIVISOR + b % DIVISOR;
|
||||
lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR;
|
||||
trail %= DIVISOR;
|
||||
|
|
|
@ -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>
|
||||
−00:25:21.1), but the <code><abbr>tz</abbr></code>
|
||||
code cannot represent the fractional second.
|
||||
−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,
|
||||
|
|
|
@ -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 “man
|
||||
page” 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’ll begin by talking about the rules for changing between standard
|
||||
and daylight saving time since we’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 “types” 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 −
|
|||
10:30 + 1:00 = GMT − 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,
|
||||
“<code>+</code>”, or “<code>-</code>”,
|
||||
in which case that’s the abbreviation</li>
|
||||
<li>a time zone abbreviation that is a string of three or more
|
||||
characters that are either ASCII alphanumerics,
|
||||
“<code>+</code>”, or “<code>-</code>”</li>
|
||||
|
||||
<li>a pair of strings separated by a slash
|
||||
<li>the string “%z”, in which case the
|
||||
“<code>%z</code>” will be replaced by a numeric time zone
|
||||
abbreviation</li>
|
||||
|
||||
<li>a pair of time zone abbreviations separated by a slash
|
||||
(‘<code>/</code>’), 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 “<code>%s</code>,” in which case
|
||||
<li>a string containing “<code>%s</code>”, in which case
|
||||
the “<code>%s</code>” will be replaced by the text in the
|
||||
appropriate Rule’s <code>LETTER</code> column</li>
|
||||
appropriate Rule’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’s a named rule in effect.</p>
|
||||
|
|
|
@ -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">§3.7.1 of
|
||||
Network Time Protocol Best Current Practices</a>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: tzselect.8,v 1.10 2022/03/22 17:48:39 christos Exp $
|
||||
.\" $NetBSD: tzselect.8,v 1.11 2022/08/16 10:56:21 christos Exp $
|
||||
.\"
|
||||
.TH TZSELECT 8
|
||||
.SH NAME
|
||||
|
@ -6,6 +6,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
|
||||
|
@ -59,11 +69,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.
|
||||
|
|
|
@ -1 +1 @@
|
|||
2022a
|
||||
2022b
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: zdump.c,v 1.56 2022/03/22 17:48:39 christos Exp $ */
|
||||
/* $NetBSD: zdump.c,v 1.57 2022/08/16 10:56:21 christos Exp $ */
|
||||
/* Dump time zone data in a textual format. */
|
||||
|
||||
/*
|
||||
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: zdump.c,v 1.56 2022/03/22 17:48:39 christos Exp $");
|
||||
__RCSID("$NetBSD: zdump.c,v 1.57 2022/08/16 10:56:21 christos Exp $");
|
||||
#endif /* !defined lint */
|
||||
|
||||
#ifndef NETBSD_INSPIRED
|
||||
|
@ -40,11 +40,11 @@ __RCSID("$NetBSD: zdump.c,v 1.56 2022/03/22 17:48:39 christos Exp $");
|
|||
#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)
|
||||
|
@ -77,7 +77,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
|
||||
(void) setlocale(LC_ALL, "");
|
||||
#ifdef TZ_DOMAINDIR
|
||||
# ifdef TZ_DOMAINDIR
|
||||
(void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
|
||||
#endif /* defined TEXTDOMAINDIR */
|
||||
# endif /* defined TEXTDOMAINDIR */
|
||||
(void) 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) {
|
||||
|
@ -1194,6 +1194,7 @@ dumptime(const struct tm *timeptr)
|
|||
};
|
||||
int lead;
|
||||
int trail;
|
||||
int DIVISOR = 10;
|
||||
|
||||
/*
|
||||
** The packaged localtime_rz and gmtime_r never put out-of-range
|
||||
|
@ -1209,7 +1210,6 @@ dumptime(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;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.\" $NetBSD: zic.8,v 1.37 2021/10/22 14:26:04 christos Exp $
|
||||
.Dd Fabruary 28, 2021
|
||||
.\" $NetBSD: zic.8,v 1.38 2022/08/16 10:56:21 christos Exp $
|
||||
.Dd August 16, 2022
|
||||
.Dt ZIC 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -116,27 +116,44 @@ 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,
|
||||
.Bd literal
|
||||
.Bd -literal
|
||||
zic -r @0
|
||||
.Ed
|
||||
omits data intended for negative timestamps (i.e., before the Epoch), and
|
||||
.Bd literal
|
||||
.Bd -literal
|
||||
zic -r @0/@2147483648
|
||||
.Ed
|
||||
outputs data intended only for nonnegative timestamps that fit into
|
||||
31-bit signed integers.
|
||||
Or using
|
||||
.Xr date 1 ,
|
||||
.Bd literal
|
||||
.Bd -literal
|
||||
zic -r @$(date +%s)
|
||||
.Ed
|
||||
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
|
||||
.Ar hi
|
||||
causes a TZif file to contain explicit entries for
|
||||
.Ar pre- hi
|
||||
transitions rather than concisely representing them
|
||||
with an extended POSIX TZ string.
|
||||
Also see the
|
||||
.Fl b Ar slim
|
||||
option for another way to shrink output size.
|
||||
.It Fl R Ar @hi
|
||||
Generate redundant trailing explicit transitions for timestamps
|
||||
that occur less than
|
||||
Ar 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.
|
||||
.It Fl t Ar file
|
||||
When creating local time information, put the configuration link in
|
||||
the named file rather than in the standard location.
|
||||
|
@ -237,7 +254,7 @@ or that starts with
|
|||
.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
|
||||
most 2048 bytes counting the newline, and without any
|
||||
.Dv NUL
|
||||
bytes.
|
||||
The input text's encoding
|
||||
|
@ -505,7 +522,7 @@ This field has the same format as the
|
|||
.Em AT
|
||||
and
|
||||
.Em 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.
|
||||
.It RULES
|
||||
The name of the rules that apply in the timezone or,
|
||||
|
@ -711,13 +728,11 @@ The
|
|||
.Em DAY ,
|
||||
and
|
||||
.Em 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.
|
||||
.Sh EXTENDED EXAMPLE
|
||||
Here is an extended example of
|
||||
.Ic 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.
|
||||
.Pp
|
||||
.Bl -column -compact -offset indent "# Rule" "Swiss" "FROM" "1995" "\&*" "Oct" "lastSun" "1:00u" "SAVE" "LETTER/S"
|
||||
.It # Rule NAME FROM TO \&- IN ON AT SAVE LETTER/S
|
||||
|
@ -744,8 +759,9 @@ and for its predecessor organization, the European Communities.
|
|||
.It Link Europe/Zurich Europe/Vaduz
|
||||
.El
|
||||
.Pp
|
||||
In this example, the timezone is named Europe/Zurich but it has an alias
|
||||
as Europe/Vaduz.
|
||||
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 7\(de\|26\(fm\|22.50\(sd; which this works out to
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: zic.c,v 1.81 2022/03/22 17:48:39 christos Exp $ */
|
||||
/* $NetBSD: zic.c,v 1.82 2022/08/16 10:56:21 christos Exp $ */
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 2006-07-17 by Arthur David Olson.
|
||||
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: zic.c,v 1.81 2022/03/22 17:48:39 christos Exp $");
|
||||
__RCSID("$NetBSD: zic.c,v 1.82 2022/08/16 10:56:21 christos Exp $");
|
||||
#endif /* !defined lint */
|
||||
|
||||
/* Use the system 'time' function, instead of any private replacement.
|
||||
|
@ -39,7 +39,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
|
||||
|
@ -50,12 +50,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. */
|
||||
|
@ -68,6 +68,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. */
|
||||
|
@ -101,12 +106,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;
|
||||
|
@ -155,7 +161,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);
|
||||
|
@ -218,86 +224,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. */
|
||||
#define EXPIRES_FIELDS 5
|
||||
/* Expires lines are like Leap lines, except without CORR and ROLL fields. */
|
||||
EXPIRES_FIELDS = LP_TIME + 1
|
||||
};
|
||||
|
||||
/* 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 */
|
||||
|
@ -490,8 +517,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 = (ptrdiff_t)((size_t)nitems_max < SIZE_MAX ?
|
||||
(size_t)nitems_max : SIZE_MAX);
|
||||
ptrdiff_t amax = min((size_t)nitems_max, SIZE_MAX);
|
||||
if ((amax - 1) / 3 * 2 < *nitems_alloc)
|
||||
memory_exhausted(_("integer overflow"));
|
||||
*nitems_alloc += (*nitems_alloc >> 1) + 1;
|
||||
|
@ -582,7 +608,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);
|
||||
|
@ -673,7 +700,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);
|
||||
|
@ -684,6 +711,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;
|
||||
|
||||
|
@ -710,11 +740,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;
|
||||
|
@ -748,9 +794,9 @@ main(int argc, char **argv)
|
|||
#endif
|
||||
#if HAVE_GETTEXT
|
||||
setlocale(LC_MESSAGES, "");
|
||||
#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];
|
||||
|
@ -767,7 +813,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);
|
||||
|
@ -854,12 +901,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)
|
||||
|
@ -1315,17 +1373,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)
|
||||
{
|
||||
FILE * fp;
|
||||
char ** fields;
|
||||
char * cp;
|
||||
const struct lookup * lp;
|
||||
int nfields;
|
||||
bool wantcont;
|
||||
lineno num;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
if (strcmp(name, "-") == 0) {
|
||||
name = _("standard input");
|
||||
|
@ -1339,24 +1427,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, (int) 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) {
|
||||
|
@ -1390,7 +1470,6 @@ infile(const char *name)
|
|||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
free(fields);
|
||||
}
|
||||
close_file(fp, NULL, filename, NULL);
|
||||
if (wantcont)
|
||||
|
@ -1971,11 +2050,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. */
|
||||
|
@ -1985,10 +2064,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.
|
||||
|
@ -2014,14 +2089,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;
|
||||
|
||||
|
@ -2047,7 +2114,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.
|
||||
|
@ -2131,14 +2198,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
|
||||
|
@ -2172,9 +2238,9 @@ writezone(const char *const name, const char *const string, char version,
|
|||
ptrdiff_t thistimei, thistimecnt, thistimelim;
|
||||
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];
|
||||
|
@ -2185,28 +2251,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;
|
||||
|
@ -2214,17 +2267,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;
|
||||
|
@ -2248,7 +2330,13 @@ writezone(const char *const name, const char *const string, char version,
|
|||
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];
|
||||
|
@ -2318,7 +2406,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;
|
||||
}
|
||||
|
@ -2329,7 +2418,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);
|
||||
|
@ -2356,14 +2446,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);
|
||||
|
@ -2464,6 +2556,8 @@ abbroffset(char *buf, zic_t offset)
|
|||
}
|
||||
}
|
||||
|
||||
static char const disable_percent_s[] = "";
|
||||
|
||||
static size_t
|
||||
doabbr(char *abbr, size_t abbrlen, struct zone const *zp, const char *letters,
|
||||
bool isdst, zic_t save, bool doquotes)
|
||||
|
@ -2480,6 +2574,8 @@ doabbr(char *abbr, size_t abbrlen, struct zone const *zp, const char *letters,
|
|||
letters = abbroffset(letterbuf, zp->z_stdoff + save);
|
||||
else if (!letters)
|
||||
letters = "%s";
|
||||
else if (letters == disable_percent_s)
|
||||
return 0;
|
||||
snprintf(abbr, abbrlen, format, letters);
|
||||
} else if (isdst) {
|
||||
strlcpy(abbr, slashp + 1, abbrlen);
|
||||
|
@ -2755,18 +2851,10 @@ stringzone(char *result, int resultlen, const struct zone *const zpfirst,
|
|||
static void
|
||||
outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
|
||||
{
|
||||
const struct zone * zp;
|
||||
struct rule * rp;
|
||||
ptrdiff_t i, j;
|
||||
bool usestart, useuntil;
|
||||
zic_t starttime, untiltime;
|
||||
zic_t stdoff;
|
||||
zic_t save;
|
||||
zic_t year;
|
||||
zic_t startoff;
|
||||
bool startttisstd;
|
||||
bool startttisut;
|
||||
int type;
|
||||
char * startbuf;
|
||||
char * ab;
|
||||
char * envvar;
|
||||
|
@ -2777,8 +2865,6 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
|
|||
bool do_extend;
|
||||
char version;
|
||||
ptrdiff_t lastatmax = -1;
|
||||
zic_t one = 1;
|
||||
zic_t y2038_boundary = one << 31;
|
||||
zic_t max_year0;
|
||||
int defaulttype = -1;
|
||||
|
||||
|
@ -2810,11 +2896,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)
|
||||
|
@ -2876,6 +2962,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,
|
||||
|
@ -2891,22 +2979,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, max_abbr_len + 1,
|
||||
zp, NULL, zp->z_isdst, save, false);
|
||||
|
@ -2918,7 +3007,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;
|
||||
/*
|
||||
|
@ -2927,7 +3018,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 &&
|
||||
|
@ -2943,6 +3036,8 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
|
|||
ptrdiff_t k;
|
||||
zic_t jtime, ktime;
|
||||
zic_t offset;
|
||||
struct rule *rp;
|
||||
int type;
|
||||
|
||||
INITIALIZE(ktime);
|
||||
if (useuntil) {
|
||||
|
@ -2965,15 +3060,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;
|
||||
|
@ -2985,11 +3080,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);
|
||||
}
|
||||
}
|
||||
|
@ -2997,8 +3092,16 @@ 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, max_abbr_len + 1,
|
||||
zp, rp->r_abbrvar,
|
||||
rp->r_isdst, rp->r_save,
|
||||
false);
|
||||
break;
|
||||
}
|
||||
save = rp->r_save;
|
||||
if (usestart && ktime == starttime)
|
||||
usestart = false;
|
||||
|
@ -3034,6 +3137,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;
|
||||
|
@ -3049,21 +3153,20 @@ 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)
|
||||
strncpy(startbuf, zp->z_format,
|
||||
max_abbr_len + 1 - 1);
|
||||
bool isdst = startoff != zp->z_stdoff;
|
||||
if (*startbuf == '\0' && zp->z_format)
|
||||
doabbr(startbuf, max_abbr_len + 1,
|
||||
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);
|
||||
|
@ -3366,23 +3469,20 @@ byword(const char *word, const struct lookup *table)
|
|||
return foundlp;
|
||||
}
|
||||
|
||||
static char **
|
||||
getfields(char *cp)
|
||||
static int
|
||||
getfields(char *cp, char **array, int arrayelts)
|
||||
{
|
||||
char * dp;
|
||||
char ** array;
|
||||
int nsubs;
|
||||
|
||||
if (cp == NULL)
|
||||
return NULL;
|
||||
array = zic_malloc(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;
|
||||
|
@ -3397,9 +3497,13 @@ getfields(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
|
||||
|
|
Loading…
Reference in New Issue