1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-26 11:47:31 +00:00

Update tzcode to 2024b.

MFC after:	3 weeks
Sponsored by:	Klara, Inc.
Reviewed by:	philip
Differential Revision:	https://reviews.freebsd.org/D46565
This commit is contained in:
Dag-Erling Smørgrav 2024-09-07 15:46:13 +02:00
commit a979394afe
20 changed files with 926 additions and 647 deletions

View File

@ -23,10 +23,10 @@ such as renaming, adding or removing zones, please read
"Theory and pragmatics of the tz code and data"
<https://www.iana.org/time-zones/repository/theory.html>.
It is also good to browse the mailing list archives
<https://mm.icann.org/pipermail/tz/> for examples of patches that tend
to work well. Additions to data should contain commentary citing
reliable sources as justification. Citations should use "https:" URLs
if available.
<https://lists.iana.org/hyperkitty/list/tz@iana.org/>
for examples of patches that tend to work well.
Changes should contain commentary citing reliable sources.
Citations should use "https:" URLs if available.
For changes that fix sensitive security-related bugs, please see the
distribution's 'SECURITY' file.
@ -63,12 +63,16 @@ If you use Git the following workflow may be helpful:
* Edit source files. Include commentary that justifies the
changes by citing reliable sources.
* Debug the changes, e.g.:
* Debug the changes locally, e.g.:
make check
make install
make TOPDIR=$PWD/tz clean check install
./zdump -v America/Los_Angeles
Although builds assume only basic POSIX, they use extra features
if available. 'make check' accesses validator.w3.org unless you
lack 'curl' or use 'make CURL=:'. If you have the latest GCC,
"make CFLAGS='$(GCC_DEBUG_FLAGS)'" does extra checking.
* For each separable change, commit it in the new branch, e.g.:
git add northamerica

View File

@ -3,17 +3,17 @@
# 2009-05-17 by Arthur David Olson.
# Request POSIX conformance; this must be the first non-comment line.
.POSIX:
# On older platforms you may need to scrounge for a POSIX-conforming 'make'.
# For example, on Solaris 10 (2005), use /usr/sfw/bin/gmake or
# /usr/xpg4/bin/make, not /usr/ccs/bin/make.
# On older platforms you may need to scrounge for POSIX conformance.
# For example, on Solaris 10 (2005) with Sun Studio 12 aka Sun C 5.9 (2007),
# use 'PATH=/usr/xpg4/bin:$PATH make CC=c99'.
# To affect how this Makefile works, you can run a shell script like this:
#
# #!/bin/sh
# make CC='gcc -std=gnu11' "$@"
# make CC='gcc -std=gnu23' "$@"
#
# This example script is appropriate for a pre-2017 GNU/Linux system
# where a non-default setting is needed to support this package's use of C99.
# This example script is appropriate for a circa 2024 GNU/Linux system
# where a non-default setting enables this package's optional use of C23.
#
# Alternatively, you can simply edit this Makefile to tailor the following
# macro definitions.
@ -53,7 +53,7 @@ DATAFORM= main
LOCALTIME= Factory
# The POSIXRULES macro controls interpretation of POSIX-2017.1-like TZ
# The POSIXRULES macro controls interpretation of POSIX-like TZ
# settings like TZ='EET-2EEST' that lack DST transition rules.
# If POSIXRULES is '-', no template is installed; this is the default.
# Any other value for POSIXRULES is obsolete and should not be relied on, as:
@ -132,8 +132,9 @@ LIBDIR = $(TOPDIR)/$(USRDIR)/lib
# Types to try, as an alternative to time_t.
TIME_T_ALTERNATIVES = $(TIME_T_ALTERNATIVES_HEAD) $(TIME_T_ALTERNATIVES_TAIL)
TIME_T_ALTERNATIVES_HEAD = int_least64_t
TIME_T_ALTERNATIVES_TAIL = int_least32_t uint_least32_t uint_least64_t
TIME_T_ALTERNATIVES_HEAD = int_least64_t.ck
TIME_T_ALTERNATIVES_TAIL = int_least32_t.ck uint_least32_t.ck \
uint_least64_t.ck
# What kind of TZif data files to generate. (TZif is the binary time
# zone data format that zic generates; see Internet RFC 8536.)
@ -219,6 +220,7 @@ LDLIBS=
# than what POSIX specifies, assuming local time is UT.
# For example, N is 252460800 on AmigaOS.
# -DHAVE_DECL_ASCTIME_R=0 if <time.h> does not declare asctime_r
# on POSIX platforms predating POSIX.1-2024
# -DHAVE_DECL_ENVIRON if <unistd.h> declares 'environ'
# -DHAVE_DECL_TIMEGM=0 if <time.h> does not declare timegm
# -DHAVE_DIRECT_H if mkdir needs <direct.h> (MS-Windows)
@ -229,7 +231,7 @@ LDLIBS=
# where LDLIBS also needs to contain -lintl on some hosts;
# -DHAVE_GETTEXT=0 to avoid using gettext
# -DHAVE_INCOMPATIBLE_CTIME_R if your system's time.h declares
# ctime_r and asctime_r incompatibly with the POSIX standard
# ctime_r and asctime_r incompatibly with POSIX.1-2017 and earlier
# (Solaris when _POSIX_PTHREAD_SEMANTICS is not defined).
# -DHAVE_INTTYPES_H=0 if <inttypes.h> does not work*+
# -DHAVE_LINK=0 if your system lacks a link function
@ -261,8 +263,11 @@ LDLIBS=
# -DRESERVE_STD_EXT_IDS if your platform reserves standard identifiers
# with external linkage, e.g., applications cannot define 'localtime'.
# -Dssize_t=long on hosts like MS-Windows that lack ssize_t
# -DSUPPORT_C89 if the tzcode library should support C89 callers+
# However, this might trigger latent bugs in C99-or-later callers.
# -DSUPPORT_C89=0 if the tzcode library should not support C89 callers
# Although -DSUPPORT_C89=0 might work around latent bugs in callers,
# it does not conform to POSIX.
# -DSUPPORT_POSIX2008 if the library should support older POSIX callers+
# However, this might cause problems in POSIX.1-2024-or-later callers.
# -DSUPPRESS_TZDIR to not prepend TZDIR to file names; this has
# security implications and is not recommended for general use
# -DTHREAD_SAFE to make localtime.c thread-safe, as POSIX requires;
@ -274,7 +279,7 @@ LDLIBS=
# -DTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory;
# the default is system-supplied, typically "/usr/lib/locale"
# -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified
# DST transitions for POSIX.1-2017-style TZ strings lacking them,
# DST transitions for proleptic format TZ strings lacking them,
# in the usual case where POSIXRULES is '-'. If not specified,
# TZDEFRULESTRING defaults to US rules for future DST transitions.
# This mishandles some past timestamps, as US DST rules have changed.
@ -302,23 +307,25 @@ LDLIBS=
#
# * Options marked "*" can be omitted if your compiler is C23 compatible.
# * Options marked "+" are obsolescent and are planned to be removed
# once the code assumes C99 or later, say in the year 2029.
# once the code assumes C99 or later (say in the year 2029)
# and POSIX.1-2024 or later (say in the year 2034).
#
# Select instrumentation via "make GCC_INSTRUMENT='whatever'".
GCC_INSTRUMENT = \
-fsanitize=undefined -fsanitize-address-use-after-scope \
-fsanitize-undefined-trap-on-error -fstack-protector
# Omit -fanalyzer from GCC_DEBUG_FLAGS, as it makes GCC too slow.
GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 \
$(GCC_INSTRUMENT) \
-Wall -Wextra \
-Walloc-size-larger-than=100000 -Warray-bounds=2 \
-Wbad-function-cast -Wbidi-chars=any,ucn -Wcast-align=strict -Wdate-time \
-Wdeclaration-after-statement -Wdouble-promotion \
-Wduplicated-branches -Wduplicated-cond \
-Wduplicated-branches -Wduplicated-cond -Wflex-array-member-not-at-end \
-Wformat=2 -Wformat-overflow=2 -Wformat-signedness -Wformat-truncation \
-Wimplicit-fallthrough=5 -Winit-self -Wlogical-op \
-Wmissing-declarations -Wmissing-prototypes -Wnested-externs \
-Wmissing-declarations -Wmissing-prototypes \
-Wmissing-variable-declarations -Wnested-externs \
-Wnull-dereference \
-Wold-style-definition -Woverlength-strings -Wpointer-arith \
-Wshadow -Wshift-overflow=2 -Wstrict-overflow \
@ -327,10 +334,9 @@ 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 -Wuse-after-free=3 \
-Wtrampolines -Wundef -Wunused-macros -Wuse-after-free=3 \
-Wvariadic-macros -Wvla -Wwrite-strings \
-Wno-address -Wno-format-nonliteral -Wno-sign-compare \
-Wno-type-limits
-Wno-format-nonliteral -Wno-sign-compare
#
# If your system has a "GMT offset" field in its "struct tm"s
# (or if you decide to add such a field in your system's "time.h" file),
@ -341,9 +347,8 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
# Similarly, if your system has a "zone abbreviation" field, define
# -DTM_ZONE=tm_zone
# and define NO_TM_ZONE to suppress any guessing.
# Although these two fields are not required by POSIX.1-2017,
# POSIX 202x/D4 requires them and they are widely available
# on GNU/Linux and BSD systems.
# Although POSIX.1-2024 requires these fields and they are widely available
# on GNU/Linux and BSD systems, some older systems lack them.
#
# The next batch of options control support for external variables
# exported by tzcode. In practice these variables are less useful
@ -353,7 +358,9 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
# # -DHAVE_TZNAME=0 # do not support "tzname"
# # -DHAVE_TZNAME=1 # support "tzname", which is defined by system library
# # -DHAVE_TZNAME=2 # support and define "tzname"
# # to the "CFLAGS=" line. "tzname" is required by POSIX.1-1988 and later.
# # to the "CFLAGS=" line. Although "tzname" is required by POSIX.1-1988
# # and later, its contents are unspecified if you use a geographical TZ
# # and the variable is planned to be removed in a future POSIX edition.
# # If not defined, the code attempts to guess HAVE_TZNAME from other macros.
# # Warning: unless time_tz is also defined, HAVE_TZNAME=1 can cause
# # crashes when combined with some platforms' standard libraries,
@ -364,7 +371,9 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
# # -DUSG_COMPAT=1 # support, and variables are defined by system library
# # -DUSG_COMPAT=2 # support and define variables
# # to the "CFLAGS=" line; "timezone" and "daylight" are inspired by Unix
# # Systems Group code and are required by POSIX.1-2008 and later (with XSI).
# # Systems Group code and are required by POSIX.1-2008 and later (with XSI),
# # although their contents are unspecified if you use a geographical TZ
# # and the variables are planned to be removed in a future edition of POSIX.
# # If not defined, the code attempts to guess USG_COMPAT from other macros.
# #
# # To support the external variable "altzone", add
@ -428,18 +437,13 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
# The name of a POSIX-like library archiver, its flags, C compiler,
# linker flags, and 'make' utility. Ordinarily the defaults suffice.
# The commented-out values are the defaults specified by POSIX.1-202x/D4.
# The commented-out values are the defaults specified by POSIX.1-2024.
#AR = ar
#ARFLAGS = -rv
#CC = c17
#LDFLAGS =
#MAKE = make
# For leap seconds, this Makefile uses LEAPSECONDS='-L leapseconds' in
# submake command lines. The default is no leap seconds.
LEAPSECONDS=
# Where to fetch leap-seconds.list from.
leaplist_URI = \
https://hpiers.obspm.fr/iers/bul/bulc/ntp/leap-seconds.list
@ -461,7 +465,7 @@ ZFLAGS=
# How to use zic to install TZif files.
ZIC_INSTALL= $(ZIC) -d '$(DESTDIR)$(TZDIR)' $(LEAPSECONDS)
ZIC_INSTALL= $(ZIC) -d '$(DESTDIR)$(TZDIR)'
# The name of a POSIX-compliant 'awk' on your system.
# mawk 1.3.3 and Solaris 10 /usr/bin/awk do not work.
@ -480,6 +484,7 @@ KSHELL= /bin/bash
# Name of curl <https://curl.haxx.se/>, used for HTML validation
# and to fetch leap-seconds.list from upstream.
# Set CURL=: to disable use of the Internet.
CURL= curl
# Name of GNU Privacy Guard <https://gnupg.org/>, used to sign distributions.
@ -533,21 +538,28 @@ OK_LINE= '^'$(OK_CHAR)'*$$'
# Flags to give 'tar' when making a distribution.
# Try to use flags appropriate for GNU tar.
GNUTARFLAGS= --format=pax --pax-option='delete=atime,delete=ctime' \
GNUTARFLAGS= --format=pax --pax-option=delete=atime,delete=ctime \
--numeric-owner --owner=0 --group=0 \
--mode=go+u,go-w --sort=name
TARFLAGS= `if tar $(GNUTARFLAGS) --version >/dev/null 2>&1; \
then echo $(GNUTARFLAGS); \
else :; \
fi`
SETUP_TAR= \
export LC_ALL=C && \
if tar $(GNUTARFLAGS) --version >/dev/null 2>&1; then \
TAR='tar $(GNUTARFLAGS)'; \
else \
TAR=tar; \
fi
# Flags to give 'gzip' when making a distribution.
GZIPFLAGS= -9n
# When comparing .tzs files, use GNU diff's -F'^TZ=' option if supported.
# This makes it easier to see which Zone has been affected.
DIFF_TZS= diff -u$$(! diff -u -F'^TZ=' - - <>/dev/null >&0 2>&1 \
|| echo ' -F^TZ=')
SETUP_DIFF_TZS = \
if diff -u -F'^TZ=' - - <>/dev/null >&0 2>&1; then \
DIFF_TZS='diff -u -F^TZ='; \
else \
DIFF_TZS='diff -u'; \
fi
# ':' on typical hosts; 'ranlib' on the ancient hosts that still need ranlib.
RANLIB= :
@ -561,8 +573,8 @@ RANLIB= :
TZCOBJS= zic.o
TZDOBJS= zdump.o localtime.o asctime.o strftime.o
DATEOBJS= date.o localtime.o strftime.o asctime.o
TZDOBJS= zdump.o localtime.o strftime.o
DATEOBJS= date.o localtime.o strftime.o
LIBSRCS= localtime.c asctime.c difftime.c strftime.c
LIBOBJS= localtime.o asctime.o difftime.o strftime.o
HEADERS= tzfile.h private.h
@ -579,8 +591,7 @@ MANTXTS= newctime.3.txt newstrftime.3.txt newtzset.3.txt \
COMMON= calendars CONTRIBUTING LICENSE Makefile \
NEWS README SECURITY theory.html version
WEB_PAGES= tz-art.html tz-how-to.html tz-link.html
CHECK_WEB_PAGES=check_theory.html check_tz-art.html \
check_tz-how-to.html check_tz-link.html
CHECK_WEB_PAGES=theory.ck tz-art.ck tz-how-to.ck tz-link.ck
DOCS= $(MANS) date.1 $(MANTXTS) $(WEB_PAGES)
PRIMARY_YDATA= africa antarctica asia australasia \
europe northamerica southamerica
@ -641,8 +652,7 @@ install: all $(DATA) $(REDO) $(MANS)
'$(DESTDIR)$(MANDIR)/man3' '$(DESTDIR)$(MANDIR)/man5' \
'$(DESTDIR)$(MANDIR)/man8'
$(ZIC_INSTALL) -l $(LOCALTIME) \
`case '$(POSIXRULES)' in ?*) echo '-p';; esac \
` $(POSIXRULES) \
-p $(POSIXRULES) \
-t '$(DESTDIR)$(TZDEFAULT)'
cp -f $(TABDATA) '$(DESTDIR)$(TZDIR)/.'
cp tzselect '$(DESTDIR)$(BINDIR)/.'
@ -665,10 +675,10 @@ INSTALL: ALL install date.1
# and append "-dirty" if the contents do not already end in "-dirty".
version: $(VERSION_DEPS)
{ (type git) >/dev/null 2>&1 && \
V=`git describe --match '[0-9][0-9][0-9][0-9][a-z]*' \
--abbrev=7 --dirty` || \
if test '$(VERSION)' = unknown && V=`cat $@`; then \
case $$V in *-dirty);; *) V=$$V-dirty;; esac; \
V=$$(git describe --match '[0-9][0-9][0-9][0-9][a-z]*' \
--abbrev=7 --dirty) || \
if test '$(VERSION)' = unknown && read -r V <$@; then \
V=$${V%-dirty}-dirty; \
else \
V='$(VERSION)'; \
fi; } && \
@ -678,7 +688,7 @@ version: $(VERSION_DEPS)
# These files can be tailored by setting BACKWARD, PACKRATDATA, PACKRATLIST.
vanguard.zi main.zi rearguard.zi: $(DSTDATA_ZI_DEPS)
$(AWK) \
-v DATAFORM=`expr $@ : '\(.*\).zi'` \
-v DATAFORM=$(@:.zi=) \
-v PACKRATDATA='$(PACKRATDATA)' \
-v PACKRATLIST='$(PACKRATLIST)' \
-f ziguard.awk \
@ -687,7 +697,7 @@ vanguard.zi main.zi rearguard.zi: $(DSTDATA_ZI_DEPS)
# This file has a version comment that attempts to capture any tailoring
# via BACKWARD, DATAFORM, PACKRATDATA, PACKRATLIST, and REDO.
tzdata.zi: $(DATAFORM).zi version zishrink.awk
version=`sed 1q version` && \
read -r version <version && \
LC_ALL=C $(AWK) \
-v dataform='$(DATAFORM)' \
-v deps='$(DSTDATA_ZI_DEPS) zishrink.awk' \
@ -708,7 +718,7 @@ tzdir.h:
mv $@.out $@
version.h: version
VERSION=`cat version` && printf '%s\n' \
read -r VERSION <version && printf '%s\n' \
'static char const PKGVERSION[]="($(PACKAGE)) ";' \
"static char const TZVERSION[]=\"$$VERSION\";" \
'static char const REPORT_BUGS_TO[]="$(BUGEMAIL)";' \
@ -748,12 +758,11 @@ commit-leap-seconds.list: fetch-leap-seconds.list
git commit --author="$$author" --date="$$date" -m'make $@' \
leap-seconds.list
# Arguments to pass to submakes of install_data.
# Arguments to pass to submakes.
# They can be overridden by later submake arguments.
INSTALLARGS = \
BACKWARD='$(BACKWARD)' \
DESTDIR='$(DESTDIR)' \
LEAPSECONDS='$(LEAPSECONDS)' \
PACKRATDATA='$(PACKRATDATA)' \
PACKRATLIST='$(PACKRATLIST)' \
TZDEFAULT='$(TZDEFAULT)' \
@ -762,16 +771,11 @@ INSTALLARGS = \
INSTALL_DATA_DEPS = zic leapseconds tzdata.zi
# 'make install_data' installs one set of TZif files.
install_data: $(INSTALL_DATA_DEPS)
posix_only: $(INSTALL_DATA_DEPS)
$(ZIC_INSTALL) tzdata.zi
posix_only: $(INSTALL_DATA_DEPS)
$(MAKE) $(INSTALLARGS) LEAPSECONDS= install_data
right_only: $(INSTALL_DATA_DEPS)
$(MAKE) $(INSTALLARGS) LEAPSECONDS='-L leapseconds' \
install_data
$(ZIC_INSTALL) -L leapseconds tzdata.zi
# In earlier versions of this makefile, the other two directories were
# subdirectories of $(TZDIR). However, this led to configuration errors.
@ -802,8 +806,7 @@ ZDS = dummy.zd
# Rule used only by submakes invoked by the $(TZS_NEW) rule.
# It is separate so that GNU 'make -j' can run instances in parallel.
$(ZDS): zdump
./zdump -i $(TZS_CUTOFF_FLAG) '$(wd)/'$$(expr $@ : '\(.*\).zd') \
>$@
./zdump -i $(TZS_CUTOFF_FLAG) "$$PWD/$(@:.zd=)" >$@
TZS_NEW_DEPS = tzdata.zi zdump zic
$(TZS_NEW): $(TZS_NEW_DEPS)
@ -812,20 +815,19 @@ $(TZS_NEW): $(TZS_NEW_DEPS)
$(zic) -d tzs$(TZS_YEAR).dir tzdata.zi
$(AWK) '/^L/{print "Link\t" $$2 "\t" $$3}' \
tzdata.zi | LC_ALL=C sort >$@.out
wd=`pwd` && \
x=`$(AWK) '/^Z/{print "tzs$(TZS_YEAR).dir/" $$2 ".zd"}' \
x=$$($(AWK) '/^Z/{print "tzs$(TZS_YEAR).dir/" $$2 ".zd"}' \
tzdata.zi \
| LC_ALL=C sort -t . -k 2,2` && \
| LC_ALL=C sort -t . -k 2,2) && \
set x $$x && \
shift && \
ZDS=$$* && \
$(MAKE) wd="$$wd" TZS_CUTOFF_FLAG="$(TZS_CUTOFF_FLAG)" \
$(MAKE) TZS_CUTOFF_FLAG="$(TZS_CUTOFF_FLAG)" \
ZDS="$$ZDS" $$ZDS && \
sed 's,^TZ=".*\.dir/,TZ=",' $$ZDS >>$@.out
rm -fr tzs$(TZS_YEAR).dir
mv $@.out $@
# If $(TZS) exists but 'make check_tzs' fails, a maintainer should inspect the
# If $(TZS) exists but 'make tzs.ck' fails, a maintainer should inspect the
# failed output and fix the inconsistency, perhaps by running 'make force_tzs'.
$(TZS):
touch $@
@ -842,7 +844,7 @@ date: $(DATEOBJS)
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(DATEOBJS) $(LDLIBS)
tzselect: tzselect.ksh version
VERSION=`cat version` && sed \
read -r VERSION <version && sed \
-e "s'#!/bin/bash'#!"'$(KSHELL)'\' \
-e s\''\(AWK\)=[^}]*'\''\1=\'\''$(AWK)\'\'\' \
-e s\''\(PKGVERSION\)=.*'\''\1=\'\''($(PACKAGE)) \'\'\' \
@ -853,11 +855,11 @@ tzselect: tzselect.ksh version
chmod +x $@.out
mv $@.out $@
check: check_back check_mild
check_mild: check_character_set check_white_space check_links \
check_name_lengths check_now \
check_slashed_abbrs check_sorted \
check_tables check_web check_ziguard check_zishrink check_tzs
check: check_mild back.ck
check_mild: check_web check_zishrink \
character-set.ck white-space.ck links.ck mainguard.ck \
name-lengths.ck now.ck slashed-abbrs.ck sorted.ck \
tables.ck ziguard.ck tzs.ck
# True if UTF8_LOCALE does not work;
# otherwise, false but with LC_ALL set to $(UTF8_LOCALE).
@ -865,9 +867,9 @@ UTF8_LOCALE_MISSING = \
{ test ! '$(UTF8_LOCALE)' \
|| ! printf 'A\304\200B\n' \
| LC_ALL='$(UTF8_LOCALE)' grep -q '^A.B$$' >/dev/null 2>&1 \
|| { LC_ALL='$(UTF8_LOCALE)'; export LC_ALL; false; }; }
|| { export LC_ALL='$(UTF8_LOCALE)'; false; }; }
check_character_set: $(ENCHILADA)
character-set.ck: $(ENCHILADA)
$(UTF8_LOCALE_MISSING) || { \
sharp='#' && \
! grep -Env $(SAFE_LINE) $(MANS) date.1 $(MANTXTS) \
@ -882,48 +884,55 @@ check_character_set: $(ENCHILADA)
}
touch $@
check_white_space: $(ENCHILADA)
white-space.ck: $(ENCHILADA)
$(UTF8_LOCALE_MISSING) || { \
patfmt=' \t|[\f\r\v]' && pat=`printf "$$patfmt\\n"` && \
enchilada='$(ENCHILADA)' && \
patfmt=' \t|[\f\r\v]' && pat=$$(printf "$$patfmt\\n") && \
! grep -En "$$pat|[$s]\$$" \
$$(ls $(ENCHILADA) | grep -Fvx leap-seconds.list); \
$${enchilada%leap-seconds.list*} \
$${enchilada#*leap-seconds.list}; \
}
touch $@
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)' \
name-lengths.ck: $(TDATA_TO_CHECK) backzone
:;! grep -En '$(FILE_NAME_COMPONENT_TOO_LONG)' \
$(TDATA_TO_CHECK) backzone
touch $@
mainguard.ck: main.zi
test '$(PACKRATLIST)' || \
cat $(TDATA) $(PACKRATDATA) | diff -u - main.zi
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)
slashed-abbrs.ck: $(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
sorted.ck: backward backzone
$(AWK) '/^Link/ {printf "%.5d %s\n", g, $$3} !/./ {g++}' \
backward | LC_ALL=C sort -cu
$(AWK) '/^Zone/ {print $$2}' backzone | LC_ALL=C sort -cu
$(AWK) '/^Zone.*\// {print $$2}' backzone | LC_ALL=C sort -cu
touch $@
check_back: checklinks.awk $(TDATA_TO_CHECK)
back.ck: checklinks.awk $(TDATA_TO_CHECK)
$(AWK) \
-v DATAFORM=$(DATAFORM) \
-v backcheck=backward \
-f checklinks.awk $(TDATA_TO_CHECK)
touch $@
check_links: checklinks.awk tzdata.zi
links.ck: checklinks.awk tzdata.zi
$(AWK) \
-v DATAFORM=$(DATAFORM) \
-f checklinks.awk tzdata.zi
@ -932,26 +941,36 @@ check_links: checklinks.awk tzdata.zi
# Check timestamps from now through 28 years from now, to make sure
# that zonenow.tab contains all sequences of planned timestamps,
# without any duplicate sequences. In theory this might require
# 2800 years but that would take a long time to check.
CHECK_NOW_TIMESTAMP = `./date +%s`
# 2800+ years but that would take a long time to check.
CHECK_NOW_TIMESTAMP = $$(./date +%s)
CHECK_NOW_FUTURE_YEARS = 28
CHECK_NOW_FUTURE_SECS = $(CHECK_NOW_FUTURE_YEARS) '*' 366 '*' 24 '*' 60 '*' 60
check_now: checknow.awk date tzdata.zi zdump zic zone1970.tab zonenow.tab
rm -fr $@.dir
mkdir $@.dir
./zic -d $@.dir tzdata.zi
CHECK_NOW_FUTURE_SECS = $(CHECK_NOW_FUTURE_YEARS) * 366 * 24 * 60 * 60
now.ck: checknow.awk date tzdata.zi zdump zic zone1970.tab zonenow.tab
rm -fr $@d
mkdir $@d
./zic -d $@d tzdata.zi
now=$(CHECK_NOW_TIMESTAMP) && \
future=`expr $(CHECK_NOW_FUTURE_SECS) + $$now` && \
future=$$(($(CHECK_NOW_FUTURE_SECS) + $$now)) && \
./zdump -i -t $$now,$$future \
$$(find $$PWD/$@.dir/????*/ -type f) \
>$@.dir/zdump.tab
$$(find "$$PWD/$@d"/????*/ -type f) \
>$@d/zdump-now.tab && \
./zdump -i -t 0,$$future \
$$(find "$$PWD/$@d" -name Etc -prune \
-o -type f ! -name '*.tab' -print) \
>$@d/zdump-1970.tab
$(AWK) \
-v zdump_table=$@.dir/zdump.tab \
-v zdump_table=$@d/zdump-now.tab \
-f checknow.awk zonenow.tab
rm -fr $@.dir
$(AWK) \
'BEGIN {print "-\t-\tUTC"} /^Zone/ {print "-\t-\t" $$2}' \
$(PRIMARY_YDATA) backward factory | \
$(AWK) \
-v zdump_table=$@d/zdump-1970.tab \
-f checknow.awk
rm -fr $@d
touch $@
check_tables: checktab.awk $(YDATA) backward zone.tab zone1970.tab
tables.ck: checktab.awk $(YDATA) backward zone.tab zone1970.tab
for tab in $(ZONETABLES); do \
test "$$tab" = zone.tab && links='$(BACKWARD)' || links=''; \
$(AWK) -f checktab.awk -v zone_table=$$tab $(YDATA) $$links \
@ -959,26 +978,24 @@ check_tables: checktab.awk $(YDATA) backward zone.tab zone1970.tab
done
touch $@
check_tzs: $(TZS) $(TZS_NEW)
tzs.ck: $(TZS) $(TZS_NEW)
if test -s $(TZS); then \
$(DIFF_TZS) $(TZS) $(TZS_NEW); \
$(SETUP_DIFF_TZS) && $$DIFF_TZS $(TZS) $(TZS_NEW); \
else \
cp $(TZS_NEW) $(TZS); \
fi
touch $@
check_web: $(CHECK_WEB_PAGES)
check_theory.html: theory.html
check_tz-art.html: tz-art.html
check_tz-how-to.html: tz-how-to.html
check_tz-link.html: tz-link.html
check_theory.html check_tz-art.html check_tz-how-to.html check_tz-link.html:
$(CURL) -sS --url https://validator.w3.org/nu/ -F out=gnu \
-F file=@$$(expr $@ : 'check_\(.*\)') -o $@.out && \
.SUFFIXES: .ck .html
.html.ck:
{ ! ($(CURL) --version) >/dev/null 2>&1 || \
$(CURL) -sS --url https://validator.w3.org/nu/ -F out=gnu \
-F file=@$<; } >$@.out && \
test ! -s $@.out || { cat $@.out; exit 1; }
mv $@.out $@
check_ziguard: rearguard.zi vanguard.zi ziguard.awk
ziguard.ck: 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 | \
@ -987,36 +1004,35 @@ check_ziguard: rearguard.zi vanguard.zi ziguard.awk
# 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: \
check_zishrink: zishrink-posix.ck zishrink-right.ck
zishrink-posix.ck zishrink-right.ck: \
zic leapseconds $(PACKRATDATA) $(PACKRATLIST) \
$(TDATA) $(DATAFORM).zi tzdata.zi
rm -fr $@.dir $@-t.dir $@-shrunk.dir
mkdir $@.dir $@-t.dir $@-shrunk.dir
rm -fr $@d t-$@d shrunk-$@d
mkdir $@d t-$@d shrunk-$@d
case $@ in \
*_right) leap='-L leapseconds';; \
*right*) leap='-L leapseconds';; \
*) leap=;; \
esac && \
$(ZIC) $$leap -d $@.dir $(DATAFORM).zi && \
$(ZIC) $$leap -d $@-shrunk.dir tzdata.zi && \
$(ZIC) $$leap -d $@d $(DATAFORM).zi && \
$(ZIC) $$leap -d shrunk-$@d tzdata.zi && \
case $(DATAFORM),$(PACKRATLIST) in \
main,) \
$(ZIC) $$leap -d $@-t.dir $(TDATA) && \
$(ZIC) $$leap -d t-$@d $(TDATA) && \
$(AWK) '/^Rule/' $(TDATA) | \
$(ZIC) $$leap -d $@-t.dir - $(PACKRATDATA) && \
diff -r $@.dir $@-t.dir;; \
$(ZIC) $$leap -d t-$@d - $(PACKRATDATA) && \
diff -r $@d t-$@d;; \
esac
diff -r $@.dir $@-shrunk.dir
rm -fr $@.dir $@-t.dir $@-shrunk.dir
diff -r $@d shrunk-$@d
rm -fr $@d t-$@d shrunk-$@d
touch $@
clean_misc:
rm -fr check_*.dir typecheck_*.dir
rm -f *.o *.out $(TIME_T_ALTERNATIVES) \
check_* core typecheck_* \
rm -fr *.ckd *.dir
rm -f *.ck *.core *.o *.out core core.* \
date tzdir.h tzselect version.h zdump zic libtz.a
clean: clean_misc
rm -fr *.dir tzdb-*/
rm -fr tzdb-*/
rm -f *.zi $(TZS_NEW)
maintainer-clean: clean
@ -1027,7 +1043,7 @@ maintainer-clean: clean
names:
@echo $(ENCHILADA)
public: check check_public $(CHECK_TIME_T_ALTERNATIVES) \
public: check public.ck $(CHECK_TIME_T_ALTERNATIVES) \
tarballs signatures
date.1.txt: date.1
@ -1041,7 +1057,7 @@ zdump.8.txt: zdump.8
zic.8.txt: zic.8
$(MANTXTS): workman.sh
LC_ALL=C sh workman.sh `expr $@ : '\(.*\)\.txt$$'` >$@.out
LC_ALL=C sh workman.sh $(@:.txt=) >$@.out
mv $@.out $@
# Set file timestamps deterministically if possible,
@ -1054,13 +1070,13 @@ SET_TIMESTAMP_N = sh -c '\
n=$$0 dest=$$1; shift; \
<"$$dest" && \
if test $$n != 0 && \
lsout=`ls -nt --time-style="+%s" "$$@" 2>/dev/null`; then \
lsout=$$(ls -nt --time-style="+%s" "$$@" 2>/dev/null); then \
set x $$lsout && \
timestamp=`expr $$7 + $$n` && \
timestamp=$$(($$7 + $$n)) && \
echo "+ touch -md @$$timestamp $$dest" && \
touch -md @$$timestamp "$$dest"; \
else \
newest=`ls -t "$$@" | sed 1q` && \
newest=$$(ls -t "$$@" | sed 1q) && \
echo "+ touch -mr $$newest $$dest" && \
touch -mr "$$newest" "$$dest"; \
fi'
@ -1083,15 +1099,15 @@ SET_TIMESTAMP_DEP = $(SET_TIMESTAMP_N) 1
set-timestamps.out: $(EIGHT_YARDS)
rm -f $@
if (type git) >/dev/null 2>&1 && \
files=`git ls-files $(EIGHT_YARDS)` && \
files=$$(git ls-files $(EIGHT_YARDS)) && \
touch -md @1 test.out; then \
rm -f test.out && \
for file in $$files; do \
if git diff --quiet $$file; then \
time=`TZ=UTC0 git log -1 \
time=$$(TZ=UTC0 git log -1 \
--format='tformat:%cd' \
--date='format:%Y-%m-%dT%H:%M:%SZ' \
$$file` && \
$$file) && \
echo "+ touch -md $$time $$file" && \
touch -md $$time $$file; \
else \
@ -1100,8 +1116,8 @@ set-timestamps.out: $(EIGHT_YARDS)
done; \
fi
$(SET_TIMESTAMP_DEP) leapseconds $(LEAP_DEPS)
for file in `ls $(MANTXTS) | sed 's/\.txt$$//'`; do \
$(SET_TIMESTAMP_DEP) $$file.txt $$file workman.sh || \
for file in $(MANTXTS); do \
$(SET_TIMESTAMP_DEP) $$file $${file%.txt} workman.sh || \
exit; \
done
$(SET_TIMESTAMP_DEP) version $(VERSION_DEPS)
@ -1114,30 +1130,29 @@ set-tzs-timestamp.out: $(TZS)
# The zics below ensure that each data file can stand on its own.
# We also do an all-files run to catch links to links.
check_public: $(VERSION_DEPS)
rm -fr public.dir
mkdir public.dir
ln $(VERSION_DEPS) public.dir
cd public.dir \
public.ck: $(VERSION_DEPS)
rm -fr $@d
mkdir $@d
ln $(VERSION_DEPS) $@d
cd $@d \
&& $(MAKE) CFLAGS='$(GCC_DEBUG_FLAGS)' TZDIR='$(TZDIR)' ALL
for i in $(TDATA_TO_CHECK) public.dir/tzdata.zi \
public.dir/vanguard.zi public.dir/main.zi \
public.dir/rearguard.zi; \
for i in $(TDATA_TO_CHECK) \
tzdata.zi vanguard.zi main.zi rearguard.zi; \
do \
public.dir/zic -v -d public.dir/zoneinfo $$i 2>&1 || exit; \
$@d/zic -v -d $@d/zoneinfo $@d/$$i || exit; \
done
public.dir/zic -v -d public.dir/zoneinfo-all $(TDATA_TO_CHECK)
$@d/zic -v -d $@d/zoneinfo-all $(TDATA_TO_CHECK)
:
: Also check 'backzone' syntax.
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 && \
rm $@d/main.zi
cd $@d && $(MAKE) PACKRATDATA=backzone main.zi
$@d/zic -d $@d/zoneinfo main.zi
rm $@d/main.zi
cd $@d && \
$(MAKE) PACKRATDATA=backzone PACKRATLIST=zone.tab main.zi
public.dir/zic -d public.dir/zoneinfo main.zi
$@d/zic -d $@d/zoneinfo main.zi
:
rm -fr public.dir
rm -fr $@d
touch $@
# Check that the code works under various alternative
@ -1145,46 +1160,47 @@ check_public: $(VERSION_DEPS)
check_time_t_alternatives: $(TIME_T_ALTERNATIVES)
$(TIME_T_ALTERNATIVES_TAIL): $(TIME_T_ALTERNATIVES_HEAD)
$(TIME_T_ALTERNATIVES): $(VERSION_DEPS)
rm -fr $@.dir
mkdir $@.dir
ln $(VERSION_DEPS) $@.dir
rm -fr $@d
mkdir $@d
ln $(VERSION_DEPS) $@d
case $@ in \
int*32_t) range=-2147483648,2147483648;; \
*32_t*) range=-2147483648,2147483648;; \
u*) range=0,4294967296;; \
*) range=-4294967296,4294967296;; \
esac && \
wd=`pwd` && \
zones=`$(AWK) '/^[^#]/ { print $$3 }' <zone1970.tab` && \
wd=$$PWD && \
zones=$$($(AWK) '/^[^#]/ { print $$3 }' <zone1970.tab) && \
if test $@ = $(TIME_T_ALTERNATIVES_HEAD); then \
range_target=; \
else \
range_target=to$$range.tzs; \
fi && \
(cd $@.dir && \
$(MAKE) TOPDIR="$$wd/$@.dir" \
CFLAGS='$(CFLAGS) -Dtime_tz='"'$@'" \
(cd $@d && \
$(MAKE) TOPDIR="$$wd/$@d" \
CFLAGS='$(CFLAGS) -Dtime_tz='"'$(@:.ck=)'" \
REDO='$(REDO)' \
D=$$wd/$@.dir \
D="$$wd/$@d" \
TZS_YEAR="$$range" TZS_CUTOFF_FLAG="-t $$range" \
install $$range_target) && \
test $@ = $(TIME_T_ALTERNATIVES_HEAD) || { \
(cd $(TIME_T_ALTERNATIVES_HEAD).dir && \
$(MAKE) TOPDIR="$$wd/$@.dir" \
(cd $(TIME_T_ALTERNATIVES_HEAD)d && \
$(MAKE) TOPDIR="$$wd/$@d" \
TZS_YEAR="$$range" TZS_CUTOFF_FLAG="-t $$range" \
D=$$wd/$@.dir \
D="$$wd/$@d" \
to$$range.tzs) && \
$(DIFF_TZS) $(TIME_T_ALTERNATIVES_HEAD).dir/to$$range.tzs \
$@.dir/to$$range.tzs && \
$(SETUP_DIFF_TZS) && \
$$DIFF_TZS $(TIME_T_ALTERNATIVES_HEAD)d/to$$range.tzs \
$@d/to$$range.tzs && \
if diff -q Makefile Makefile 2>/dev/null; then \
quiet_option='-q'; \
else \
quiet_option=''; \
fi && \
diff $$quiet_option -r $(TIME_T_ALTERNATIVES_HEAD).dir/etc \
$@.dir/etc && \
diff $$quiet_option -r $(TIME_T_ALTERNATIVES_HEAD)d/etc \
$@d/etc && \
diff $$quiet_option -r \
$(TIME_T_ALTERNATIVES_HEAD).dir/usr/share \
$@.dir/usr/share; \
$(TIME_T_ALTERNATIVES_HEAD)d/usr/share \
$@d/usr/share; \
}
touch $@
@ -1199,7 +1215,7 @@ ALL_ASC = $(TRADITIONAL_ASC) $(REARGUARD_ASC) \
tarballs rearguard_tarballs tailored_tarballs traditional_tarballs \
signatures rearguard_signatures traditional_signatures: \
version set-timestamps.out rearguard.zi vanguard.zi
VERSION=`cat version` && \
read -r VERSION <version && \
$(MAKE) AWK='$(AWK)' VERSION="$$VERSION" $@_version
# These *_version rules are intended for use if VERSION is set by some
@ -1218,15 +1234,15 @@ rearguard_signatures_version: $(REARGUARD_ASC)
traditional_signatures_version: $(TRADITIONAL_ASC)
tzcode$(VERSION).tar.gz: set-timestamps.out
LC_ALL=C && export LC_ALL && \
tar $(TARFLAGS) -cf - \
$(SETUP_TAR) && \
$$TAR -cf - \
$(COMMON) $(DOCS) $(SOURCES) | \
gzip $(GZIPFLAGS) >$@.out
mv $@.out $@
tzdata$(VERSION).tar.gz: set-timestamps.out
LC_ALL=C && export LC_ALL && \
tar $(TARFLAGS) -cf - $(TZDATA_DIST) | \
$(SETUP_TAR) && \
$$TAR -cf - $(TZDATA_DIST) | \
gzip $(GZIPFLAGS) >$@.out
mv $@.out $@
@ -1251,9 +1267,9 @@ tzdata$(VERSION)-rearguard.tar.gz: rearguard.zi set-timestamps.out
: The dummy pacificnew pacifies TZUpdater 2.3.1 and earlier.
$(CREATE_EMPTY) $@.dir/pacificnew
touch -mr version $@.dir/version
LC_ALL=C && export LC_ALL && \
$(SETUP_TAR) && \
(cd $@.dir && \
tar $(TARFLAGS) -cf - \
$$TAR -cf - \
$(TZDATA_DIST) pacificnew | \
gzip $(GZIPFLAGS)) >$@.out
mv $@.out $@
@ -1269,9 +1285,14 @@ tzdata$(VERSION)-tailored.tar.gz: set-timestamps.out
rm -fr $@.dir
mkdir $@.dir
: The dummy pacificnew pacifies TZUpdater 2.3.1 and earlier.
if test $(DATAFORM) = vanguard; then \
pacificnew=; \
else \
pacificnew=pacificnew; \
fi && \
cd $@.dir && \
$(CREATE_EMPTY) $(PRIMARY_YDATA) $(NDATA) backward \
`test $(DATAFORM) = vanguard || echo pacificnew`
$$pacificnew
(grep '^#' tzdata.zi && echo && cat $(DATAFORM).zi) \
>$@.dir/etcetera
touch -mr tzdata.zi $@.dir/etcetera
@ -1291,9 +1312,9 @@ tzdata$(VERSION)-tailored.tar.gz: set-timestamps.out
test -f $@.dir/$$file || links="$$links $$file"; \
done && \
ln $$links $@.dir
LC_ALL=C && export LC_ALL && \
$(SETUP_TAR) && \
(cd $@.dir && \
tar $(TARFLAGS) -cf - * | gzip $(GZIPFLAGS)) >$@.out
$$TAR -cf - * | gzip $(GZIPFLAGS)) >$@.out
mv $@.out $@
tzdb-$(VERSION).tar.lz: set-timestamps.out set-tzs-timestamp.out
@ -1301,8 +1322,8 @@ tzdb-$(VERSION).tar.lz: set-timestamps.out set-tzs-timestamp.out
mkdir tzdb-$(VERSION)
ln $(ENCHILADA) tzdb-$(VERSION)
$(SET_TIMESTAMP) tzdb-$(VERSION) tzdb-$(VERSION)/*
LC_ALL=C && export LC_ALL && \
tar $(TARFLAGS) -cf - tzdb-$(VERSION) | lzip -9 >$@.out
$(SETUP_TAR) && \
$$TAR -cf - tzdb-$(VERSION) | lzip -9 >$@.out
mv $@.out $@
tzcode$(VERSION).tar.gz.asc: tzcode$(VERSION).tar.gz
@ -1313,22 +1334,21 @@ $(ALL_ASC):
$(GPG) --armor --detach-sign $?
TYPECHECK_CFLAGS = $(CFLAGS) -DTYPECHECK -D__time_t_defined -D_TIME_T
typecheck: typecheck_long_long typecheck_unsigned
typecheck_long_long typecheck_unsigned: $(VERSION_DEPS)
rm -fr $@.dir
mkdir $@.dir
ln $(VERSION_DEPS) $@.dir
cd $@.dir && \
typecheck: long-long.ck unsigned.ck
long-long.ck unsigned.ck: $(VERSION_DEPS)
rm -fr $@d
mkdir $@d
ln $(VERSION_DEPS) $@d
cd $@d && \
case $@ in \
*_long_long) i="long long";; \
*_unsigned ) i="unsigned" ;; \
long-long.*) i="long long";; \
unsigned.* ) i="unsigned" ;; \
esac && \
typecheck_cflags='' && \
$(MAKE) \
CFLAGS="$(TYPECHECK_CFLAGS) \"-Dtime_t=$$i\"" \
TOPDIR="`pwd`" \
TOPDIR="$$PWD" \
install
$@.dir/zdump -i -c 1970,1971 Europe/Rome
$@d/zdump -i -c 1970,1971 Europe/Rome
touch $@
zonenames: tzdata.zi
@ -1347,7 +1367,7 @@ zic.o: private.h tzfile.h tzdir.h version.h
.PHONY: check_web check_zishrink
.PHONY: clean clean_misc commit-leap-seconds.list dummy.zd
.PHONY: fetch-leap-seconds.list force_tzs
.PHONY: install install_data maintainer-clean names
.PHONY: install maintainer-clean names
.PHONY: posix_only posix_right public
.PHONY: rearguard_signatures rearguard_signatures_version
.PHONY: rearguard_tarballs rearguard_tarballs_version

View File

@ -1,5 +1,125 @@
News for the tz database
Release 2024b - 2024-09-04 12:27:47 -0700
Briefly:
Improve historical data for Mexico, Mongolia, and Portugal.
System V names are now obsolescent.
The main data form now uses %z.
The code now conforms to RFC 8536 for early timestamps.
Support POSIX.1-2024, which removes asctime_r and ctime_r.
Assume POSIX.2-1992 or later for shell scripts.
SUPPORT_C89 now defaults to 1.
Changes to past timestamps
Asia/Choibalsan is now an alias for Asia/Ulaanbaatar rather than
being a separate Zone with differing behavior before April 2008.
This seems better given our wildly conflicting information about
Mongolia's time zone history. (Thanks to Heitor David Pinto.)
Historical transitions for Mexico have been updated based on
official Mexican decrees. The affected timestamps occur during
the years 1921-1927, 1931, 1945, 1949-1970, and 1981-1997.
The affected zones are America/Bahia_Banderas, America/Cancun,
America/Chihuahua, America/Ciudad_Juarez, America/Hermosillo,
America/Mazatlan, America/Merida, America/Mexico_City,
America/Monterrey, America/Ojinaga, and America/Tijuana.
(Thanks to Heitor David Pinto.)
Historical transitions for Portugal, represented by Europe/Lisbon,
Atlantic/Azores, and Atlantic/Madeira, have been updated based on a
close reading of old Portuguese legislation, replacing previous data
mainly originating from Whitman and Shanks & Pottenger. These
changes affect a few transitions in 1917-1921, 1924, and 1940
throughout these regions by a few hours or days, and various
timestamps between 1977 and 1993 depending on the region. In
particular, the Azores and Madeira did not observe DST from 1977 to
1981. Additionally, the adoption of standard zonal time in former
Portuguese colonies have been adjusted: Africa/Maputo in 1909, and
Asia/Dili by 22 minutes at the start of 1912.
(Thanks to Tim Parenti.)
Changes to past tm_isdst flags
The period from 1966-04-03 through 1966-10-02 in Portugal is now
modeled as DST, to more closely reflect how contemporaneous changes
in law entered into force.
Changes to data
Names present only for compatibility with UNIX System V
(last released in the 1990s) have been moved to 'backward'.
These names, which for post-1970 timestamps mostly just duplicate
data of geographical names, were confusing downstream uses.
Names moved to 'backward' are now links to geographical names.
This affects behavior for TZ='EET' for some pre-1981 timestamps,
for TZ='CET' for some pre-1947 timestamps, and for TZ='WET' for
some pre-1996 timestamps. Also, TZ='MET' now behaves like
TZ='CET' and so uses the abbreviation "CET" rather than "MET".
Those needing the previous TZDB behavior, which does not match any
real-world clocks, can find the old entries in 'backzone'.
(Problem reported by Justin Grant.)
The main source files' time zone abbreviations now use %z,
supported by zic since release 2015f and used in vanguard form
since release 2022b. For example, America/Sao_Paulo now contains
the zone continuation line "-3:00 Brazil %z", which is less error
prone than the old "-3:00 Brazil -03/-02". This does not change
the represented data: the generated TZif files are unchanged.
Rearguard form still avoids %z, to support obsolescent parsers.
Asia/Almaty has been removed from zonenow.tab as it now agrees
with Asia/Tashkent for future timestamps, due to Kazakhstan's
2024-02-29 time zone change. Similarly, America/Scoresbysund
has been removed, as it now agrees with America/Nuuk due to
its 2024-03-31 time zone change.
Changes to code
localtime.c now always uses a TZif file's time type 0 to handle
timestamps before the file's first transition. Formerly,
localtime.c sometimes inferred a different time type, in order to
handle problematic data generated by zic 2018e or earlier. As it
is now safe to assume more recent versions of zic, there is no
longer a pressing need to fail to conform RFC 8536 section 3.2,
which requires using time type 0 in this situation. This change
does not affect behavior when reading TZif files generated by zic
2018f and later.
POSIX.1-2024 removes asctime_r and ctime_r and does not let
libraries define them, so remove them except when needed to
conform to earlier POSIX. These functions are dangerous as they
can overrun user buffers. If you still need them, add
-DSUPPORT_POSIX2008 to CFLAGS.
The SUPPORT_C89 option now defaults to 1 instead of 0, fixing a
POSIX-conformance bug introduced in 2023a.
tzselect now supports POSIX.1-2024 proleptic TZ strings. Also, it
assumes POSIX.2-1992 or later, as practical porting targets now
all support that, and it uses some features from POSIX.1-2024 if
available.
Changes to build procedure
'make check' no longer requires curl and Internet access.
The build procedure now assumes POSIX.2-1992 or later, to simplify
maintenance. To build on Solaris 10, the only extant system still
defaulting to pre-POSIX, prepend /usr/xpg4/bin to PATH.
Changes to documentation
The documentation now reflects POSIX.1-2024.
Changes to commentary
Commentary about historical transitions in Portugal and her former
colonies has been expanded with links to many relevant legislation.
(Thanks to Tim Parenti.)
Release 2024a - 2024-02-01 09:28:56 -0800
Briefly:
@ -161,7 +281,7 @@ Release 2023d - 2023-12-21 20:02:24 -0800
* It uses the special .POSIX target.
* It quotes special characters more carefully.
* It no longer mishandles builds in an ISO 8859 locale.
Due to the CC changes, TZDIR is now #defined in a file tzfile.h
Due to the CC changes, TZDIR is now #defined in a file tzdir.h
built by 'make', not in a $(CC) -D option. Also, TZDEFAULT is
now treated like TZDIR as they have similar roles.
@ -283,7 +403,7 @@ Release 2023a - 2023-03-22 12:39:33 -0700
To improve tzselect diagnostics, zone1970.tab's comments column is
now limited to countries that have multiple timezones.
Note that leap seconds are planned to be discontinued by 2035.
Note that there are plans to discontinue leap seconds by 2035.
Release 2022g - 2022-11-29 08:58:31 -0800

View File

@ -1,4 +1,4 @@
/* asctime and asctime_r a la POSIX and ISO C, except pad years before 1000. */
/* asctime a la ISO C. */
/*
** This file is in the public domain, so clarified as of
@ -27,8 +27,8 @@
** leading zeroes to get the newline in the traditional place.
** The -4 ensures that we get four characters of output even if
** we call a strftime variant that produces fewer characters for some years.
** The ISO C and POSIX standards prohibit padding the year,
** but many implementations pad anyway; most likely the standards are buggy.
** This conforms to recent ISO C and POSIX standards, which say behavior
** is undefined when the year is less than 1000 or greater than 9999.
*/
static char const ASCTIME_FMT[] = "%s %s%3d %.2d:%.2d:%.2d %-4s\n";
/*
@ -62,6 +62,18 @@ static char buf_asctime[2*3 + 5*INT_STRLEN_MAXIMUM(int) + 7 + 2 + 1 + 1];
static char buf_ctime[sizeof buf_asctime];
#endif
/* Publish asctime_r and ctime_r only when supporting older POSIX. */
#if SUPPORT_POSIX2008
# define asctime_static
#else
# define asctime_static static
# undef asctime_r
# undef ctime_r
# define asctime_r static_asctime_r
# define ctime_r static_ctime_r
#endif
asctime_static
char *
asctime_r(struct tm const *restrict timeptr, char *restrict buf)
{
@ -118,6 +130,7 @@ asctime(register const struct tm *timeptr)
return asctime_r(timeptr, buf_asctime);
}
asctime_static
char *
ctime_r(const time_t *timep, char *buf)
{

View File

@ -125,7 +125,7 @@ static char const UNSPEC[] = "-00";
for ttunspecified to work without crashing. */
enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 };
/* Limit to time zone abbreviation length in POSIX.1-2017-style TZ strings.
/* Limit to time zone abbreviation length in proleptic TZ strings.
This is distinct from TZ_MAX_CHARS, which limits TZif file contents. */
#ifndef TZNAME_MAXIMUM
# define TZNAME_MAXIMUM 255
@ -149,11 +149,6 @@ struct state {
char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"),
2 * (TZNAME_MAXIMUM + 1))];
struct lsinfo lsis[TZ_MAX_LEAPS];
/* The time type to use for early times or if no transitions.
It is always zero for recent tzdb releases.
It might be nonzero for data from tzdb 2018e or earlier. */
int defaulttype;
};
enum r_type {
@ -217,8 +212,9 @@ static int localtime_key_error;
** objects: a broken-down time structure and an array of char.
** Thanks to Paul Eggert for noting this.
**
** This requirement was removed in C99, so support it only if requested,
** as support is more likely to lead to bugs in badly written programs.
** Although this requirement was removed in C99 it is still present in POSIX.
** Follow the requirement if SUPPORT_C89, even though this is more likely to
** trigger latent bugs in programs.
*/
#if SUPPORT_C89
@ -773,58 +769,6 @@ tzloadbody(char const *name, struct state *sp, bool doextend,
if (sp->typecnt == 0)
return EINVAL;
/* Infer sp->defaulttype from the data. Although this default
type is always zero for data from recent tzdb releases,
things are trickier for data from tzdb 2018e or earlier.
The first set of heuristics work around bugs in 32-bit data
generated by tzdb 2013c or earlier. The workaround is for
zones like Australia/Macquarie where timestamps before the
first transition have a time type that is not the earliest
standard-time type. See:
https://mm.icann.org/pipermail/tz/2013-May/019368.html */
/*
** If type 0 does not specify local time, or is unused in transitions,
** it's the type to use for early times.
*/
for (i = 0; i < sp->timecnt; ++i)
if (sp->types[i] == 0)
break;
i = i < sp->timecnt && ! ttunspecified(sp, 0) ? -1 : 0;
/*
** Absent the above,
** if there are transition times
** and the first transition is to a daylight time
** find the standard type less than and closest to
** the type of the first transition.
*/
if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) {
i = sp->types[0];
while (--i >= 0)
if (!sp->ttis[i].tt_isdst)
break;
}
/* The next heuristics are for data generated by tzdb 2018e or
earlier, for zones like EST5EDT where the first transition
is to DST. */
/*
** If no result yet, find the first standard type.
** If there is none, punt to type zero.
*/
if (i < 0) {
i = 0;
while (sp->ttis[i].tt_isdst)
if (++i >= sp->typecnt) {
i = 0;
break;
}
}
/* A simple 'sp->defaulttype = 0;' would suffice here if we
didn't have to worry about 2018e-or-earlier data. Even
simpler would be to remove the defaulttype member and just
use 0 in its place. */
sp->defaulttype = i;
return 0;
}
@ -870,7 +814,7 @@ is_digit(char c)
** Return a pointer to that character.
*/
ATTRIBUTE_REPRODUCIBLE static const char *
ATTRIBUTE_PURE_114833 static const char *
getzname(register const char *strp)
{
register char c;
@ -891,7 +835,7 @@ getzname(register const char *strp)
** We don't do any checking here; checking is done later in common-case code.
*/
ATTRIBUTE_REPRODUCIBLE static const char *
ATTRIBUTE_PURE_114833 static const char *
getqzname(register const char *strp, const int delim)
{
register int c;
@ -1143,7 +1087,7 @@ transtime(const int year, register const struct rule *const rulep,
}
/*
** Given a POSIX.1-2017-style TZ string, fill in the rule tables as
** Given a POSIX.1 proleptic TZ string, fill in the rule tables as
** appropriate.
*/
@ -1378,7 +1322,7 @@ tzparse(const char *name, struct state *sp, struct state const *basep)
/*
** Transitions from DST to DDST
** will effectively disappear since
** POSIX.1-2017 provides for only one
** proleptic TZ strings have only one
** DST offset.
*/
if (isdst && !sp->ttis[j].tt_ttisstd) {
@ -1407,7 +1351,6 @@ tzparse(const char *name, struct state *sp, struct state const *basep)
sp->timecnt = 0;
init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
}
sp->defaulttype = 0;
sp->charcnt = charcnt;
cp = sp->chars;
memcpy(cp, stdname, stdlen);
@ -1474,7 +1417,6 @@ zoneinit(struct state *sp, char const *name)
sp->goback = sp->goahead = false;
init_ttinfo(&sp->ttis[0], 0, false, 0);
strcpy(sp->chars, utc);
sp->defaulttype = 0;
return 0;
} else {
int err = tzload(name, sp, true);
@ -1579,8 +1521,8 @@ tzfree(timezone_t sp)
}
/*
** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and
** ctime_r are obsolescent and have potential security problems that
** NetBSD 6.1.4 has ctime_rz, but omit it because C23 deprecates ctime and
** POSIX.1-2024 removes ctime_r. Both have potential security problems that
** ctime_rz would share. Callers can instead use localtime_rz + strftime.
**
** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work
@ -1598,8 +1540,7 @@ tzfree(timezone_t sp)
**
** If successful and SETNAME is nonzero,
** set the applicable parts of tzname, timezone and altzone;
** however, it's OK to omit this step
** if the timezone is compatible with POSIX.1-2017
** however, it's OK to omit this step for proleptic TZ strings
** since in that case tzset should have already done this step correctly.
** 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.
@ -1667,7 +1608,7 @@ localsub(struct state const *sp, time_t const *timep, int_fast32_t setname,
return result;
}
if (sp->timecnt == 0 || t < sp->ats[0]) {
i = sp->defaulttype;
i = 0;
} else {
register int lo = 1;
register int hi = sp->timecnt;
@ -2482,7 +2423,7 @@ mktime(struct tm *tmp)
}
#if STD_INSPIRED
/* This function is obsolescent and may disapper in future releases.
/* This function is obsolescent and may disappear in future releases.
Callers can instead use mktime. */
time_t
timelocal(struct tm *tmp)
@ -2500,7 +2441,7 @@ timelocal(struct tm *tmp)
# define EXTERN_TIMEOFF static
#endif
/* This function is obsolescent and may disapper in future releases.
/* This function is obsolescent and may disappear in future releases.
Callers can instead use mktime_z with a fixed-offset zone. */
EXTERN_TIMEOFF time_t
timeoff(struct tm *tmp, long offset)

View File

@ -9,16 +9,16 @@ asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
.el .ds - \-
.B #include <time.h>
.PP
.BR "extern char *tzname[];" " /\(** (optional) \(**/"
.PP
.B [[deprecated]] char *ctime(time_t const *clock);
.PP
/* Only in POSIX.1-2017 and earlier. */
.B char *ctime_r(time_t const *clock, char *buf);
.PP
.B double difftime(time_t time1, time_t time0);
.PP
.B [[deprecated]] char *asctime(struct tm const *tm);
.PP
/* Only in POSIX.1-2017 and earlier. */
.B "char *asctime_r(struct tm const *restrict tm,"
.B " char *restrict result);"
.PP
@ -112,17 +112,6 @@ The
function
corrects for the time zone and any time zone adjustments
(such as Daylight Saving Time in the United States).
After filling in the
.q "tm"
structure,
.B localtime
sets the
.BR tm_isdst 'th
element of
.B tzname
to a pointer to a string that's the time zone abbreviation to be used with
.BR localtime 's
return value.
.PP
The
.B gmtime
@ -191,9 +180,19 @@ are determined.
The
.B mktime
function
returns the specified calendar time;
returns the specified calendar time.
If the calendar time cannot be represented,
it returns \-1.
it returns \-1 without updating the structure.
To distinguish failure from a valid \-1 return,
you can set
.B tm_wday
or
.B tm_yday
to a negative value before calling
.BR mktime ;
if that value is still negative when
.B mktime
returns, the calendar time could not be represented.
.PP
The
.B difftime
@ -213,6 +212,13 @@ and
functions
are like their unsuffixed counterparts, except that they accept an
additional argument specifying where to store the result if successful.
The
.B ctime_r
and
.B asctime_r
functions are present only on systems supporting POSIX.1-2017 and earlier,
as they are removed in POSIX.1-2024 and user code can define these
functions with other meanings.
.PP
The
.B localtime_rz
@ -275,21 +281,43 @@ from UT, with positive values indicating east
of the Prime Meridian.
The field's name is derived from Greenwich Mean Time, a precursor of UT.
.PP
In
In platforms conforming to POSIX.1-2024 the
.B "struct tm"
the
.B tm_zone
and
.B tm_gmtoff
fields exist, and are filled in, only if arrangements to do
so were made when the library containing these functions was
created.
Similarly, the
.B tzname
variable is optional; also, there is no guarantee that
.B tzname
will
continue to exist in this form in future releases of this code.
fields exist, and are filled in.
For
.B localtime_rz
and
.B mktime_rz
the storage lifetime of the strings addressed by
.B tm_zone
extends until the corresponding
.B timezone_t
object is freed via
.BR tzfree .
For the other functions the lifetime extends until the
.I TZ
environment variable changes state and
.B tzset
is then called.
.PP
As a side effect, the
.BR ctime ,
.B localtime
and
.B mktime
functions also behave as if
.B tzset
were called.
The
.B ctime_r
and
.B localtime_r
functions might (or might not) also behave this way.
This is for compatibility with older platforms, as required by POSIX.
.SH FILES
.ta \w'/usr/share/zoneinfo/posixrules\0\0'u
/etc/localtime local timezone file
@ -303,11 +331,11 @@ continue to exist in this form in future releases of this code.
If /usr/share/zoneinfo/GMT is absent,
UTC leap seconds are loaded from /usr/share/zoneinfo/GMT0 if present.
.SH SEE ALSO
getenv(3),
newstrftime(3),
newtzset(3),
time(2),
tzfile(5)
.BR getenv (3),
.BR newstrftime (3),
.BR newtzset (3),
.BR time (2),
.BR tzfile (5).
.SH NOTES
The return values of
.BR asctime ,
@ -317,20 +345,6 @@ and
.B localtime
point to static data
overwritten by each call.
The
.B tzname
variable (once set) and the
.B tm_zone
field of a returned
.B "struct tm"
both point to an array of characters that
can be freed or overwritten by later calls to the functions
.BR localtime ,
.BR tzfree ,
and
.BR tzset ,
if these functions affect the timezone information that specifies the
abbreviation in question.
The remaining functions and data are thread-safe.
.PP
The

View File

@ -91,11 +91,11 @@ as specified by brackets in the description.
If a bracketed member name is followed by
.q + ,
.B strftime
can use the named member even though POSIX.1-2017 does not list it;
can use the named member even though POSIX.1-2024 does not list it;
if the name is followed by
.q \*- ,
.B strftime
ignores the member even though POSIX.1-2017 lists it
ignores the member even though POSIX.1-2024 lists it
which means portable code should set it.
For portability,
.BI * timeptr
@ -137,8 +137,8 @@ is replaced by the locale's appropriate date and time representation.
.IR tm_hour ,
.IR tm_min ,
.IR tm_sec ,
.IR tm_gmtoff +,
.IR tm_zone +,
.IR tm_gmtoff ,
.IR tm_zone ,
.IR tm_isdst \*-].
.TP
%D
@ -326,8 +326,8 @@ is replaced by the locale's appropriate time representation.
.IR tm_hour ,
.IR tm_min ,
.IR tm_sec ,
.IR tm_gmtoff +,
.IR tm_zone +,
.IR tm_gmtoff ,
.IR tm_zone ,
.IR tm_isdst \*-].
.TP
%x
@ -355,7 +355,7 @@ is replaced by the year without century as a decimal number [00,99].
%Z
is replaced by the time zone abbreviation,
or by the empty string if this is not determinable.
.RI [ tm_zone +,
.RI [ tm_zone ,
.IR tm_isdst \*-]
.TP
%z
@ -369,7 +369,7 @@ but local time is indeterminate; by convention this is used for
locations while uninhabited, and corresponds to a zero offset when the
time zone abbreviation begins with
.q "\*-" .
.RI [ tm_gmtoff +,
.RI [ tm_gmtoff ,
.IR tm_zone +,
.IR tm_isdst \*-]
.TP
@ -398,7 +398,7 @@ also behaves as if
were called.
This is for compatibility with older platforms, as required by POSIX;
it is not needed for
.BR tzset 's
.BR strftime 's
own use.
.SH "RETURN VALUE"
If the conversion is successful,
@ -428,11 +428,11 @@ conversion and the number of seconds since the Epoch cannot be represented
in a
.c time_t .
.SH SEE ALSO
date(1),
getenv(3),
newctime(3),
newtzset(3),
time(2),
tzfile(5)
.BR date (1),
.BR getenv (3),
.BR newctime (3),
.BR newtzset (3),
.BR time (2),
.BR tzfile (5).
.SH BUGS
There is no conversion specification for the phase of the moon.

View File

@ -15,6 +15,14 @@ tzset \- initialize time conversion information
.PP
.B void tzset(void);
.PP
/\(** Optional and obsolescent: \(**/
.br
.B extern char *tzname[];
.br
.B extern long timezone;
.br
.B extern int daylight;
.PP
.B cc ... \*-ltz
.fi
.SH DESCRIPTION
@ -165,7 +173,7 @@ describes when the change back happens. Each
.I time
field describes when, in current local time, the change to the other
time is made.
As an extension to POSIX.1-2017, daylight saving is assumed to be in effect
Daylight saving is assumed to be in effect
all year if it begins January 1 at 00:00 and ends December 31 at
24:00 plus the difference between daylight saving and standard time,
leaving no room for standard time in the calendar.
@ -212,11 +220,7 @@ The
.I time
has the same format as
.I offset
except that POSIX.1-2017 does not allow a leading sign (\c
.q "\*-"
or
.q "+" ).
As an extension to POSIX.1-2017, the hours part of
except that the hours part of
.I time
can range from \-167 through 167; this allows for unusual rules such
as
@ -229,8 +233,7 @@ is not given, is
.LP
Here are some examples of
.I TZ
values that directly specify the timezone; they use some of the
extensions to POSIX.1-2017.
values that directly specify the timezone.
.TP
.B EST5
stands for US Eastern Standard
@ -346,6 +349,22 @@ if the implied call to
fails,
.B tzset
falls back on UT.
.PP
As a side effect, the
.B tzset
function sets some external variables if the platform defines them.
It sets
.BR tzname [0]
and
.BR tzname [1]
to pointers to strings that are time zone abbreviations to be used with
standard and daylight saving time, respectively.
It also sets
.B timezone
to be the number of seconds that standard time is west of the Prime Meridian,
and
.B daylight
to be zero if daylight saving time is never in effect, non-zero otherwise.
.SH "RETURN VALUE"
If successful, the
.B tzalloc
@ -384,8 +403,29 @@ and
If /usr/share/zoneinfo/GMT is absent,
UTC leap seconds are loaded from /usr/share/zoneinfo/GMT0 if present.
.SH SEE ALSO
getenv(3),
newctime(3),
newstrftime(3),
time(2),
tzfile(5)
.BR getenv (3),
.BR newctime (3),
.BR newstrftime (3),
.BR time (2),
.BR tzfile (5).
.SH NOTES
Portable code should not rely on the contents of the external variables
.BR tzname ,
.B timezone
and
.B daylight
as their contents are unspecified (and do not make sense in general)
when a geographical TZ is used.
In multithreaded applications behavior is undefined if one thread accesses
one of these variables while another thread invokes
.BR tzset .
A future version of POSIX is planned to remove these variables;
callers can instead use the
.I tm_gmtoff
and
.I tm_zone
members of
.B struct tm,
or use
.B strftime
with "%z" or "%Z".

View File

@ -19,19 +19,22 @@
/* PORT_TO_C89 means the code should work even if the underlying
compiler and library support only C89 plus C99's 'long long'
and perhaps a few other extensions to C89. SUPPORT_C89 means the
tzcode library should support C89 callers in addition to the usual
support for C99-and-later callers; however, C89 support can trigger
latent bugs in C99-and-later callers. These macros are obsolescent,
and the plan is to remove them along with any code needed only when
they are nonzero. A good time to do that might be in the year 2029
and perhaps a few other extensions to C89.
This macro is obsolescent, and the plan is to remove it along with
associated code. A good time to do that might be in the year 2029
because RHEL 7 (whose GCC defaults to C89) extended life cycle
support (ELS) is scheduled to end on 2028-06-30. */
#ifndef PORT_TO_C89
# define PORT_TO_C89 0
#endif
/* SUPPORT_C89 means the tzcode library should support C89 callers
in addition to the usual support for C99-and-later callers.
This defaults to 1 as POSIX requires, even though that can trigger
latent bugs in callers. */
#ifndef SUPPORT_C89
# define SUPPORT_C89 0
# define SUPPORT_C89 1
#endif
#ifndef __STDC_VERSION__
@ -69,10 +72,6 @@
** You can override these in your C compiler options, e.g. '-DHAVE_GETTEXT=1'.
*/
#ifndef HAVE_DECL_ASCTIME_R
# define HAVE_DECL_ASCTIME_R 1
#endif
#if !defined HAVE__GENERIC && defined __has_extension
# if !__has_extension(c_generic_selections)
# define HAVE__GENERIC 0
@ -236,6 +235,31 @@
# include <unistd.h> /* for R_OK, and other POSIX goodness */
#endif /* HAVE_UNISTD_H */
/* SUPPORT_POSIX2008 means the tzcode library should support
POSIX.1-2017-and-earlier callers in addition to the usual support for
POSIX.1-2024-and-later callers; however, this can be
incompatible with POSIX.1-2024-and-later callers.
This macro is obsolescent, and the plan is to remove it
along with any code needed only when it is nonzero.
A good time to do that might be in the year 2034.
This macro's name is SUPPORT_POSIX2008 because _POSIX_VERSION == 200809
in POSIX.1-2017, a minor revision of POSIX.1-2008. */
#ifndef SUPPORT_POSIX2008
# if defined _POSIX_VERSION && _POSIX_VERSION <= 200809
# define SUPPORT_POSIX2008 1
# else
# define SUPPORT_POSIX2008 0
# endif
#endif
#ifndef HAVE_DECL_ASCTIME_R
# if SUPPORT_POSIX2008
# define HAVE_DECL_ASCTIME_R 1
# else
# define HAVE_DECL_ASCTIME_R 0
# endif
#endif
#ifndef HAVE_STRFTIME_L
# if _POSIX_VERSION < 200809
# define HAVE_STRFTIME_L 0
@ -460,14 +484,6 @@ typedef unsigned long uintmax_t;
# define ckd_mul(r, a, b) __builtin_mul_overflow(a, b, r)
#endif
#if 3 <= __GNUC__
# define ATTRIBUTE_MALLOC __attribute__((malloc))
# define ATTRIBUTE_FORMAT(spec) __attribute__((format spec))
#else
# define ATTRIBUTE_MALLOC /* empty */
# define ATTRIBUTE_FORMAT(spec) /* empty */
#endif
#if (defined __has_c_attribute \
&& (202311 <= __STDC_VERSION__ || !defined __STRICT_ANSI__))
# define HAVE___HAS_C_ATTRIBUTE true
@ -535,24 +551,27 @@ typedef unsigned long uintmax_t;
# endif
#endif
#ifndef ATTRIBUTE_REPRODUCIBLE
# if 3 <= __GNUC__
# define ATTRIBUTE_REPRODUCIBLE __attribute__((pure))
# else
# define ATTRIBUTE_REPRODUCIBLE /* empty */
# endif
# define ATTRIBUTE_REPRODUCIBLE /* empty */
#endif
#if HAVE___HAS_C_ATTRIBUTE
# if __has_c_attribute(unsequenced)
# define ATTRIBUTE_UNSEQUENCED [[unsequenced]]
# endif
/* GCC attributes that are useful in tzcode.
__attribute__((pure)) is stricter than [[reproducible]],
so the latter is an adequate substitute in non-GCC C23 platforms. */
#if __GNUC__ < 3
# define ATTRIBUTE_FORMAT(spec) /* empty */
# define ATTRIBUTE_PURE ATTRIBUTE_REPRODUCIBLE
#else
# define ATTRIBUTE_FORMAT(spec) __attribute__((format spec))
# define ATTRIBUTE_PURE __attribute__((pure))
#endif
#ifndef ATTRIBUTE_UNSEQUENCED
# if 3 <= __GNUC__
# define ATTRIBUTE_UNSEQUENCED __attribute__((const))
# else
# define ATTRIBUTE_UNSEQUENCED /* empty */
# endif
/* Avoid GCC bug 114833 <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114833>.
Remove this macro and its uses when the bug is fixed in a GCC release,
because only the latest GCC matters for $(GCC_DEBUG_FLAGS). */
#ifdef GCC_LINT
# define ATTRIBUTE_PURE_114833 ATTRIBUTE_PURE
#else
# define ATTRIBUTE_PURE_114833 /* empty */
#endif
#if (__STDC_VERSION__ < 199901 && !defined restrict \
@ -604,12 +623,8 @@ typedef time_tz tz_time_t;
# undef asctime
# define asctime tz_asctime
# undef asctime_r
# define asctime_r tz_asctime_r
# undef ctime
# define ctime tz_ctime
# undef ctime_r
# define ctime_r tz_ctime_r
# undef difftime
# define difftime tz_difftime
# undef gmtime
@ -656,6 +671,12 @@ typedef time_tz tz_time_t;
# define tzfree tz_tzfree
# undef tzset
# define tzset tz_tzset
# if SUPPORT_POSIX2008
# undef asctime_r
# define asctime_r tz_asctime_r
# undef ctime_r
# define ctime_r tz_ctime_r
# endif
# if HAVE_STRFTIME_L
# undef strftime_l
# define strftime_l tz_strftime_l
@ -681,10 +702,12 @@ typedef time_tz tz_time_t;
# define DEPRECATED_IN_C23 ATTRIBUTE_DEPRECATED
# endif
DEPRECATED_IN_C23 char *asctime(struct tm const *);
char *asctime_r(struct tm const *restrict, char *restrict);
DEPRECATED_IN_C23 char *ctime(time_t const *);
#if SUPPORT_POSIX2008
char *asctime_r(struct tm const *restrict, char *restrict);
char *ctime_r(time_t const *, char *);
ATTRIBUTE_UNSEQUENCED double difftime(time_t, time_t);
#endif
double difftime(time_t, time_t);
size_t strftime(char *restrict, size_t, char const *restrict,
struct tm const *restrict);
# if HAVE_STRFTIME_L
@ -715,7 +738,7 @@ void tzset(void);
time_t timegm(struct tm *);
#endif
#if !HAVE_DECL_ASCTIME_R && !defined asctime_r
#if !HAVE_DECL_ASCTIME_R && !defined asctime_r && SUPPORT_POSIX2008
extern char *asctime_r(struct tm const *restrict, char *restrict);
#endif
@ -803,10 +826,10 @@ timezone_t tzalloc(char const *);
void tzfree(timezone_t);
# if STD_INSPIRED
# if TZ_TIME_T || !defined posix2time_z
ATTRIBUTE_REPRODUCIBLE time_t posix2time_z(timezone_t, time_t);
ATTRIBUTE_PURE time_t posix2time_z(timezone_t, time_t);
# endif
# if TZ_TIME_T || !defined time2posix_z
ATTRIBUTE_REPRODUCIBLE time_t time2posix_z(timezone_t, time_t);
ATTRIBUTE_PURE time_t time2posix_z(timezone_t, time_t);
# endif
# endif
#endif
@ -978,8 +1001,9 @@ enum {
/* How many years to generate (in zic.c) or search through (in localtime.c).
This is two years larger than the obvious 400, to avoid edge cases.
E.g., suppose a non-POSIX.1-2017 rule applies from 2012 on with transitions
in March and September, plus one-off transitions in November 2013.
E.g., suppose a rule applies from 2012 on with transitions
in March and September, plus one-off transitions in November 2013,
and suppose the rule cannot be expressed as a proleptic TZ string.
If zic looked only at the last 400 years, it would set max_year=2413,
with the intent that the 400 years 2014 through 2413 will be repeated.
The last transition listed in the tzfile would be in 2413-09,

View File

@ -89,13 +89,15 @@ The <code><abbr>tz</abbr></code> code is upwards compatible with <a
href="https://en.wikipedia.org/wiki/POSIX">POSIX</a>, an international
standard for <a
href="https://en.wikipedia.org/wiki/Unix">UNIX</a>-like systems.
As of this writing, the current edition of POSIX is: <a
As of this writing, the current edition of POSIX is POSIX.1-2024,
which has been published but not yet in HTML form.
Unlike its predecessor POSIX.1-2017 (<a
href="https://pubs.opengroup.org/onlinepubs/9699919799/"> The Open
Group Base Specifications Issue 7</a>, IEEE Std 1003.1-2017, 2018
Edition.
Because the database's scope encompasses real-world changes to civil
timekeeping, its model for describing time is more complex than the
standard and daylight saving times supported by POSIX.1-2017.
Edition), POSIX.1-2024 requires support for the
<code><abbr>tz</abbr></code> database, which has a
model for describing civil time that is more complex than the
standard and daylight saving times required by POSIX.1-2017.
A <code><abbr>tz</abbr></code> timezone corresponds to a ruleset that can
have more than two changes per year, these changes need not merely
flip back and forth between two alternatives, and the rules themselves
@ -159,7 +161,7 @@ among the following goals:
</ul>
<p>
Names normally have the form
Names normally have the format
<var>AREA</var><code>/</code><var>LOCATION</var>, where
<var>AREA</var> is a continent or ocean, and
<var>LOCATION</var> is a specific location within the area.
@ -187,7 +189,7 @@ in decreasing order of importance:
href="https://en.wikipedia.org/wiki/ASCII">ASCII</a> letters,
'<code>.</code>', '<code>-</code>' and '<code>_</code>'.
Do not use digits, as that might create an ambiguity with <a
href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03">POSIX.1-2017
href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03">POSIX's proleptic
<code>TZ</code> strings</a>.
A file name component must not exceed 14 characters or start with
'<code>-</code>'.
@ -378,7 +380,8 @@ nowadays distributions typically use it
and no great weight should be attached to whether a link
is defined in <code>backward</code> or in some other file.
The source file <code>etcetera</code> defines names that may be useful
on platforms that do not support POSIX.1-2017-style <code>TZ</code> strings;
on platforms that do not support proleptic <code>TZ</code> strings
like <code>&lt;+08&gt;-8</code>;
no other source file other than <code>backward</code>
contains links to its zones.
One of <code>etcetera</code>'s names is <code>Etc/UTC</code>,
@ -425,8 +428,8 @@ in decreasing order of importance:
In other words, in the C locale the POSIX extended regular
expression <code>[-+[:alnum:]]{3,6}</code> should match the
abbreviation.
This guarantees that all abbreviations could have been specified by a
POSIX.1-2017 <code>TZ</code> string.
This guarantees that all abbreviations could have been specified
explicitly by a POSIX proleptic <code>TZ</code> string.
</p>
</li>
<li>
@ -578,6 +581,11 @@ in decreasing order of importance:
some sense undefined; this notation is derived
from <a href="https://datatracker.ietf.org/doc/html/rfc3339">Internet
<abbr title="Request For Comments">RFC</abbr> 3339</a>.
(The abbreviation 'Z' that
<a href="https://datatracker.ietf.org/doc/html/rfc9557">Internet
<abbr>RFC</abbr> 9557</a> uses for this concept
would violate the POSIX requirement
of at least three characters in an abbreviation.)
</li>
</ul>
@ -775,7 +783,7 @@ href="https://www.dissentmagazine.org/blog/booked-a-global-history-of-time-vanes
the Western 06:00 to be 12:00. These practices are largely outside
the scope of the <code><abbr>tz</abbr></code> code and data, which
provide only limited support for date and time localization
such as that required by POSIX.1-2017.
such as that required by POSIX.
If <abbr>DST</abbr> is not used a different time zone
can often do the trick; for example, in Kenya a <code>TZ</code> setting
like <code>&lt;-03&gt;3</code> or <code>America/Cayenne</code> starts
@ -866,29 +874,62 @@ Code compatible with this package is already
<a href="tz-link.html#tzdb">part of many platforms</a>, where the
primary use of this package is to update obsolete time-related files.
To do this, you may need to compile the time zone compiler
'<code>zic</code>' supplied with this package instead of using the
system '<code>zic</code>', since the format of <code>zic</code>'s
<code>zic</code> supplied with this package instead of using the
system <code>zic</code>, since the format of <code>zic</code>'s
input is occasionally extended, and a platform may still be shipping
an older <code>zic</code>.
</p>
<h3 id="POSIX">POSIX.1-2017 properties and limitations</h3>
<p>
In POSIX, time display in a process is controlled by the
environment variable <code>TZ</code>, which can have two forms:
</p>
<ul>
<li>
A <dfn>proleptic <code>TZ</code></dfn> value
like <code>CET-1CEST,M3.5.0,M10.5.0/3</code> uses a complex
notation that specifies a single standard time along with daylight
saving rules that apply to all years past, present, and future.
</li>
<li>
A <dfn>geographical <code>TZ</code></dfn> value
like <code>Europe/Berlin</code> names a location that stands for
civil time near that location, which can have more than
one standard time and more than one set of daylight saving rules,
to record timekeeping practice more accurately.
These names are defined by the <code><abbr>tz</abbr></code> database.
</li>
</ul>
<h3 id="POSIX.1-2017">POSIX.1-2017 properties and limitations</h3>
<p>
Some platforms support only the features required by POSIX.1-2017,
and have not yet upgraded to POSIX.1-2024.
Code intended to be portable to these platforms must deal
with problems that were fixed in later POSIX editions.
</p>
<ul>
<li>
POSIX.1-2017 does not require support for geographical <code>TZ</code>,
and there is no convenient and efficient way to determine
the <abbr>UT</abbr> offset and time zone abbreviation of arbitrary
timestamps, particularly for timezones
that do not fit into the POSIX model.
</li>
<li>
<p>
In POSIX.1-2017, time display in a process is controlled by the
environment variable <code>TZ</code>.
Unfortunately, the POSIX.1-2017
<code>TZ</code> string takes a form that is hard to describe and
is error-prone in practice.
Also, POSIX.1-2017 <code>TZ</code> strings cannot deal with daylight
The proleptic <code>TZ</code> string,
which is all that POSIX.1-2017 requires,
has a format that is hard to describe and is error-prone in practice.
Also, proleptic <code>TZ</code> strings cannot deal with daylight
saving time rules not based on the Gregorian calendar (as in
Morocco), or with situations where more than two time zone
abbreviations or <abbr>UT</abbr> offsets are used in an area.
</p>
<p>
The POSIX.1-2017 <code>TZ</code> string takes the following form:
A proleptic <code>TZ</code> string has the following format:
</p>
<p>
@ -955,7 +996,7 @@ an older <code>zic</code>.
</dl>
<p>
Here is an example POSIX.1-2017 <code>TZ</code> string for New
Here is an example proleptic <code>TZ</code> string for New
Zealand after 2007.
It says that standard time (<abbr>NZST</abbr>) is 12 hours ahead
of <abbr>UT</abbr>, and that daylight saving time
@ -966,26 +1007,46 @@ an older <code>zic</code>.
<pre><code>TZ='NZST-12NZDT,M9.5.0,M4.1.0/3'</code></pre>
<p>
This POSIX.1-2017 <code>TZ</code> string is hard to remember, and
This proleptic <code>TZ</code> string is hard to remember, and
mishandles some timestamps before 2008.
With this package you can use this instead:
With this package you can use a geographical <code>TZ</code> instead:
</p>
<pre><code>TZ='Pacific/Auckland'</code></pre>
</li>
</ul>
<p>
POSIX.1-2017 also has the limitations of POSIX.1-2024,
discussed in the next section.
</p>
<h3 id="POSIX.1-2024">POSIX.1-2024 properties and limitations</h3>
<p>
POSIX.1-2024 extends POSIX.1-2017 in the following significant ways:
</p>
<ul>
<li>
POSIX does not define the <abbr>DST</abbr> transitions
for <code>TZ</code> values like
"<code>EST5EDT</code>".
Traditionally the current <abbr>US</abbr> <abbr>DST</abbr> rules
were used to interpret such values, but this meant that the
<abbr>US</abbr> <abbr>DST</abbr> rules were compiled into each
time conversion package, and when
<abbr>US</abbr> time conversion rules changed (as in the United
States in 1987 and again in 2007), all packages that
interpreted <code>TZ</code> values had to be updated
to ensure proper results.
POSIX.1-2024 requires support for geographical <code>TZ</code>.
Earlier POSIX editions require support only for proleptic <code>TZ</code>.
</li>
<li>
POSIX.1-2024 requires <code>struct tm</code>
to have a <abbr>UT</abbr> offset member <code>tm_gmtoff</code>
and a time zone abbreviation member <code>tm_zone</code>.
Earlier POSIX editions lack this requirement.
</li>
<li>
DST transition times can range from &minus;167:59:59
to 167:59:59 instead of merely from 00:00:00 to 24:59:59.
This allows for proleptic TZ strings
like <code>"&lt;-02&gt;2&lt;-01&gt;,M3.5.0/-1,M10.5.0/0"</code>
where the transition time &minus;1:00 means 23:00 the previous day.
</li>
</ul>
<p>
However POSIX.1-2024, like earlier POSIX editions, has some limitations:
<ul>
<li>
The <code>TZ</code> environment variable is process-global, which
makes it hard to write efficient, thread-safe applications that
@ -1003,16 +1064,34 @@ an older <code>zic</code>.
handling daylight saving time shifts &ndash; as might be required to
limit phone calls to off-peak hours.
</li>
<li>
POSIX.1-2017 provides no convenient and efficient way to determine
the <abbr>UT</abbr> offset and time zone abbreviation of arbitrary
timestamps, particularly for timezones
that do not fit into the POSIX model.
</li>
<li>
POSIX requires that <code>time_t</code> clock counts exclude leap
seconds.
</li>
<li>
POSIX does not define the <abbr>DST</abbr> transitions
for <code>TZ</code> values like
"<code>EST5EDT</code>".
Traditionally the current <abbr>US</abbr> <abbr>DST</abbr> rules
were used to interpret such values, but this meant that the
<abbr>US</abbr> <abbr>DST</abbr> rules were compiled into each
time conversion package, and when
<abbr>US</abbr> time conversion rules changed (as in the United
States in 1987 and again in 2007), all packages that
interpreted <code>TZ</code> values had to be updated
to ensure proper results.
</li>
</ul>
<h3 id="POSIX-extensions">Extensions to POSIX in the
<code><abbr>tz</abbr></code> code</h3>
<p>
The <code><abbr>tz</abbr></code> code defines some properties
left unspecified by POSIX, and attempts to support some
extensions to POSIX.
</p>
<ul>
<li>
The <code><abbr>tz</abbr></code> code attempts to support all the
<code>time_t</code> implementations allowed by POSIX.
@ -1026,21 +1105,14 @@ an older <code>zic</code>.
and 40-bit integers are also used occasionally.
Although earlier POSIX versions allowed <code>time_t</code> to be a
floating-point type, this was not supported by any practical system,
and POSIX.1-2013 and the <code><abbr>tz</abbr></code> code both
and POSIX.1-2013+ and the <code><abbr>tz</abbr></code> code both
require <code>time_t</code> to be an integer type.
</li>
</ul>
<h3 id="POSIX-extensions">Extensions to POSIX.1-2017 in the
<code><abbr>tz</abbr></code> code</h3>
<ul>
<li>
<p>
The <code>TZ</code> environment variable is used in generating
the name of a file from which time-related information is read
(or is interpreted à la POSIX.1-2017); <code>TZ</code> is no longer
constrained to be a string containing abbreviations
and numeric data as described <a href="#POSIX">above</a>.
If the <code>TZ</code> environment variable uses the geographical format,
it is used in generating
the name of a file from which time-related information is read.
The file's format is <dfn><abbr>TZif</abbr></dfn>,
a timezone information format that contains binary data; see
<a href="https://datatracker.ietf.org/doc/html/8536">Internet
@ -1053,10 +1125,11 @@ an older <code>zic</code>.
abbreviations are used.
</p>
<p>
It was recognized that allowing the <code>TZ</code> environment
When the <code><abbr>tz</abbr></code> code was developed in the 1980s,
it was recognized that allowing the <code>TZ</code> environment
variable to take on values such as '<code>America/New_York</code>'
might cause "old" programs (that expect <code>TZ</code> to have a
certain form) to operate incorrectly; consideration was given to using
certain format) to operate incorrectly; consideration was given to using
some other environment variable (for example, <code>TIMEZONE</code>)
to hold the string used to generate the <abbr>TZif</abbr> file's name.
In the end, however, it was decided to continue using
@ -1069,15 +1142,6 @@ an older <code>zic</code>.
assume pre-POSIX <code>TZ</code> values.
</p>
</li>
<li>
The code supports platforms with a <abbr>UT</abbr> offset member
in <code>struct tm</code>, e.g., <code>tm_gmtoff</code>,
or with a time zone abbreviation member in
<code>struct tm</code>, e.g., <code>tm_zone</code>. As noted
in <a href="https://austingroupbugs.net/view.php?id=1533">Austin
Group defect 1533</a>, a future version of POSIX is planned to
require <code>tm_gmtoff</code> and <code>tm_zone</code>.
</li>
<li>
Functions <code>tzalloc</code>, <code>tzfree</code>,
<code>localtime_rz</code>, and <code>mktime_z</code> for
@ -1088,7 +1152,7 @@ an older <code>zic</code>.
and <code>localtime_rz</code> and <code>mktime_z</code> are
like <code>localtime_r</code> and <code>mktime</code> with an
extra <code>timezone_t</code> argument.
The functions were inspired by <a href="https://netbsd.org/">NetBSD</a>.
The functions were inspired by <a href="https://netbsd.org">NetBSD</a>.
</li>
<li>
Negative <code>time_t</code> values are supported, on systems
@ -1116,6 +1180,7 @@ The vestigial <abbr>API</abbr>s are:
<li>
The POSIX <code>tzname</code> variable does not suffice and is no
longer needed.
It is planned to be removed in a future edition of POSIX.
To get a timestamp's time zone abbreviation, consult
the <code>tm_zone</code> member if available; otherwise,
use <code>strftime</code>'s <code>"%Z"</code> conversion
@ -1124,6 +1189,7 @@ The vestigial <abbr>API</abbr>s are:
<li>
The POSIX <code>daylight</code> and <code>timezone</code>
variables do not suffice and are no longer needed.
They are planned to be removed in a future edition of POSIX.
To get a timestamp's <abbr>UT</abbr> offset, consult
the <code>tm_gmtoff</code> member if available; otherwise,
subtract values returned by <code>localtime</code>
@ -1278,13 +1344,13 @@ between now and the future time.
<p>
Leap seconds were introduced in 1972 to accommodate the
difference between atomic time and the less regular rotation of the earth.
Unfortunately they caused so many problems with civil
timekeeping that they
are <a href="https://www.bipm.org/en/cgpm-2022/resolution-4">planned
to be discontinued by 2035</a>, with some as-yet-undetermined
mechanism replacing them, perhaps after the year 2135.
Despite their impending obsolescence, a record of leap seconds is still
needed to resolve timestamps from 1972 through 2035.
Unfortunately they have caused so many problems with civil
timekeeping that there are
<a href="https://www.bipm.org/en/cgpm-2022/resolution-4">plans
to discontinue them by 2035</a>.
Even if these plans come to fruition, a record of leap seconds will still be
needed to resolve timestamps from 1972 through 2035,
and there may also be a need to record whatever mechanism replaces them.
</p>
<p>
@ -1374,6 +1440,12 @@ href='https://www.esa.int/Applications/Navigation/Telling_time_on_the_Moon'>cons
the establishment of a reference timescale for the Moon, which has
days roughly equivalent to 29.5 Earth days, and where relativistic
effects cause clocks to tick slightly faster than on Earth.
Also, <abbr title="National Aeronautics and Space Administration">NASA</abbr>
has been <a
href='https://www.whitehouse.gov/wp-content/uploads/2024/04/Celestial-Time-Standardization-Policy.pdf'>ordered</a>
to consider the establishment of Coordinated Lunar Time (<abbr>LTC</abbr>).
It is not yet known whether the US and European efforts will result in
multiple timescales on the Moon.
</p>
<p>

View File

@ -228,6 +228,11 @@ of the 1999-11 <em>Atlantic Monthly</em>.
magazine's 2002-11-11 issue; among other things, it proposed
year-round <abbr>DST</abbr> as a way of lessening wintertime despair.
</li>
<li>
Cory Doctorow, <a
href="https://craphound.com/est/download/"><em>Eastern Standard Tribe</em></a>,
2004. The world splinters into tribes characterized by their timezones.
</li>
</ul>
<h2>Music</h2>
<ul>

View File

@ -81,10 +81,11 @@ C Library</a> (used in
title="Berkeley Software Distribution">BSD</abbr></a>,
<a href="https://netbsd.org">Net<abbr>BSD</abbr></a>,
<a href="https://www.openbsd.org">Open<abbr>BSD</abbr></a>,
<a href="https://www.chromium.org/chromium-os/">Chromium OS</a>,
<a href="https://www.chromium.org/chromium-os/">ChromiumOS</a>,
<a href="https://cygwin.com">Cygwin</a>,
<a href="https://mariadb.org">MariaDB</a>,
<a href="https://en.wikipedia.org/wiki/MINIX">MINIX</a>,
<a href="https://musl.libc.org">musl libc</a>,
<a href="https://www.mysql.com">MySQL</a>,
<a href="https://en.wikipedia.org/wiki/WebOS"><abbr
title="Web Operating System">webOS</abbr></a>,
@ -112,9 +113,9 @@ eastern time but with different <abbr>DST</abbr> rules in 1975;
and other entries represent smaller regions like Starke County,
Indiana, which switched from central to eastern time in 1991
and switched back in 2006.
To use the database on an extended <a
To use the database on a <a
href="https://en.wikipedia.org/wiki/POSIX"><abbr
title="Portable Operating System Interface">POSIX</abbr>.1-2017</a>
title="Portable Operating System Interface">POSIX</abbr>.1-2024</a>
implementation set the <code><abbr>TZ</abbr></code>
environment variable to the location's full name,
e.g., <code><abbr>TZ</abbr>="America/New_York"</code>.</p>
@ -192,9 +193,10 @@ After obtaining the code and data files, see the
<code>README</code> file for what to do next.
The code lets you compile the <code><abbr>tz</abbr></code> source files into
machine-readable binary files, one for each location. The binary files
are in a special timezone information format (<dfn><abbr>TZif</abbr></dfn>)
specified by <a href="https://datatracker.ietf.org/doc/html/8536">Internet
<abbr>RFC</abbr> 8536</a>.
are in a special format specified by
<a href="https://datatracker.ietf.org/doc/html/8536">The
Time Zone Information Format (<abbr>TZif</abbr>)</a>
(Internet <abbr title="Request For Comments">RFC</abbr> 8536).
The code also lets
you read a <abbr>TZif</abbr> file and interpret timestamps for that
location.</p>
@ -205,13 +207,11 @@ location.</p>
<p>
The <code><abbr>tz</abbr></code> code and data
are by no means authoritative. If you find errors, please
send changes to <a href="mailto:tz@iana.org"><code>tz@iana.org</code></a>,
the time zone mailing list. You can also <a
href="https://mm.icann.org/mailman/listinfo/tz">subscribe</a> to it
and browse the <a
href="https://mm.icann.org/pipermail/tz/">archive of old
messages</a>.
<a href="https://tzdata-meta.timtimeonline.com/">Metadata for mailing list
email changes to <a href="mailto:tz@iana.org"><code>tz@iana.org</code></a>,
the time zone mailing list. See
<a href="https://lists.iana.org/postorius/lists/tz.iana.org/">the mailing
list's main page</a> to subscribe or to browse its archive of old messages.
<a href="https://tzdata-meta.timtimeonline.com">Metadata for mailing list
discussions</a> and corresponding data changes can be
generated <a href="https://github.com/timparenti/tzdata-meta">automatically</a>.
</p>
@ -226,7 +226,7 @@ the process by tailoring the generic instructions in
the <code><abbr>tz</abbr> README</code> file and installing the latest
data yourself. System-specific instructions for installing the
latest <code><abbr>tz</abbr></code> data have also been published
for <a href="https://developer.ibm.com/articles/au-aix-olson-time-zone/"><abbr>AIX</abbr></a>,
for <a href="https://www.ibm.com/support/pages/aix-time-zone-olson-tzdata-updates"><abbr>AIX</abbr></a>,
<a
href="https://source.android.com/devices/tech/config/timezone-rules">Android</a>,
<a
@ -248,7 +248,7 @@ with lines terminated by <a href="https://en.wikipedia.org/wiki/Newline"><abbr
title="linefeed">LF</abbr></a>,
which can be modified by common text editors such
as <a href="https://www.gnu.org/software/emacs/">GNU Emacs</a>,
<a href="https://wiki.gnome.org/Apps/Gedit">gedit</a>, and
<a href="https://gedit-technology.github.io/apps/gedit/">gedit</a>, and
<a href="https://www.vim.org">vim</a>.
Specialized source-file editing can be done via the
<a href="https://packagecontrol.io/packages/zoneinfo">Sublime
@ -261,8 +261,8 @@ Studio Code</a>.
<p>
For further information about updates, please see
<a href="https://datatracker.ietf.org/doc/html/rfc6557">Procedures for
Maintaining the Time Zone Database</a> (Internet <abbr
title="Request For Comments">RFC</abbr> 6557). More detail can be
Maintaining the Time Zone Database</a> (Internet <abbr>RFC</abbr> 6557).
More detail can be
found in <a href="theory.html">Theory and pragmatics of the
<code><abbr>tz</abbr></code> code and data</a>.
<a href="https://a0.github.io/a0-tzmigration/">A0 TimeZone Migration</a>
@ -400,7 +400,7 @@ variant <a href="https://datatracker.ietf.org/doc/html/rfc6321">xCal</a>
title="Extensible Markup Language">XML</abbr></a> format, and a variant
<a href="https://datatracker.ietf.org/doc/html/rfc7265">jCal</a>
(Internet <abbr>RFC</abbr> 7265)
uses <a href="https://www.json.org"><abbr
uses <a href="https://www.json.org/json-en.html"><abbr
title="JavaScript Object Notation">JSON</abbr></a> format.</li>
</ul>
</section>
@ -413,7 +413,7 @@ distributions you can generally work around compatibility problems by
running the command <code>make rearguard_tarballs</code> and compiling
from the resulting tarballs instead.</p>
<ul>
<li><a href="https://sourceforge.net/projects/vzic/">Vzic</a> is a <a
<li><a href="https://github.com/libical/vzic">Vzic</a> is a <a
href="https://en.wikipedia.org/wiki/C_(programming_language)">C</a>
program that compiles
<code><abbr>tz</abbr></code> source into iCalendar-compatible VTIMEZONE files.
@ -440,11 +440,9 @@ transition in the <code><abbr>tz</abbr></code> database.</li>
<li>The <a href="https://howardhinnant.github.io/date/tz.html">Time Zone
Database Parser</a> is a
<a href="https://en.wikipedia.org/wiki/C++">C++</a> parser and
runtime library with <a
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0355r7.html">API</a>
adopted by
<a href="https://en.wikipedia.org/wiki/C++20">C++20</a>,
the current iteration of the C++ standard.
runtime library with a <a
href="https://en.cppreference.com/w/cpp/chrono"><code>std::chrono</code> API</a>
that is a standard part of C++.
It is freely available under the
<abbr title="Massachusetts Institute of Technology">MIT</abbr> license.</li>
<li><a id="ICU" href="https://icu.unicode.org">International Components for
@ -467,8 +465,8 @@ freely available under the <abbr>MIT</abbr> license.</li>
<li>The <a
href="https://www.oracle.com/java/technologies/javase/tzupdater-readme.html">TZUpdater
tool</a> compiles <code><abbr>tz</abbr></code> source into the format used by
<a href="https://openjdk.java.net/">OpenJDK</a> and
<a href="https://jdk.java.net/">Oracle JDK</a>.
<a href="https://openjdk.org">OpenJDK</a> and
<a href="https://jdk.java.net">Oracle JDK</a>.
Although its source code is proprietary, its executable is available under the
<a href="https://www.oracle.com/a/tech/docs/tzupdater-lic.html">Java SE
Timezone Updater License Agreement</a>.</li>
@ -490,7 +488,7 @@ are alternatives to TZUpdater. IANA Updater's license is unclear;
ZIUpdater is licensed under the <abbr>GPL</abbr>.</li>
<li><a href="https://github.com/MenoData/Time4A">Time4A: Advanced date and
time library for Android</a> and
<a href="https://github.com/MenoData/Time4J/">Time4J: Advanced date,
<a href="https://github.com/MenoData/Time4J">Time4J: Advanced date,
time and interval library for Java</a> compile
<code><abbr>tz</abbr></code> source into a binary format.
Time4A is available under the Apache License and Time4J is
@ -516,7 +514,7 @@ many of which also support runtimes lacking the <code>timeZone</code> option.
href="https://github.com/formatjs/date-time-format-timezone"><code>Intl.DateTimeFormat</code>
timezone polyfill</a>
is freely available under a <abbr>BSD</abbr>-style license.</li>
<li>The <a href="https://date-fns.org/">date-fns</a>
<li>The <a href="https://date-fns.org">date-fns</a>
library manipulates timezone-aware timestamps in browsers and
in <a href="https://nodejs.org/en/">Node.js</a>.
It is freely available under the <abbr>MIT</abbr> license.</li>
@ -552,9 +550,9 @@ objects</a> let programs access an abstract view of
<code><abbr>tzdb</abbr></code> data, and are designed to replace <a
href="https://codeofmatt.com/javascript-date-type-is-horribly-broken/">JavaScript's
problematic <code>Date</code> objects</a> when working with dates and times.
<li><a href="https://github.com/JuliaTime/">JuliaTime</a> contains a
<li><a href="https://github.com/JuliaTime">JuliaTime</a> contains a
compiler from <code><abbr>tz</abbr></code> source into
<a href="https://julialang.org/">Julia</a>. It is freely available
<a href="https://julialang.org">Julia</a>. It is freely available
under the <abbr>MIT</abbr> license.</li>
<li><a href="https://github.com/pavkam/tzdb"><abbr>TZDB</abbr> &ndash;
<abbr>IANA</abbr> Time Zone Database for Delphi/<abbr
@ -565,7 +563,7 @@ as compiled by <a href="https://en.wikipedia.org/wiki/Delphi_(IDE)">Delphi</a>
and <a
href="https://en.wikipedia.org/wiki/Free_Pascal"><abbr>FPC</abbr></a>.
It is freely available under a <abbr>BSD</abbr>-style license.</li>
<li><a href="http://pytz.sourceforge.net">pytz &ndash; World Timezone
<li><a href="https://pythonhosted.org/pytz/">pytz &ndash; World Timezone
Definitions for Python</a> compiles <code><abbr>tz</abbr></code> source into
<a href="https://www.python.org">Python</a>.
It is freely available under a <abbr>BSD</abbr>-style license.
@ -621,11 +619,11 @@ License.</li>
<a href="https://github.com/nayarsystems/posix_tz_db"><code>posix_tz_db</code>
package</a> contains Python code
to generate <abbr>CSV</abbr> and <abbr>JSON</abbr> tables that map
<code><abbr>tz</abbr></code> settings to POSIX.1-2017-like approximations.
<code><abbr>tz</abbr></code> settings to proleptic TZ approximations.
For example, it maps <code>"Africa/Cairo"</code>
to <code>"EET-2EEST,M4.5.5/0,M10.5.4/24"</code>,
an approximation valid for Cairo timestamps from 2023 on.
This can help porting to platforms that support only POSIX.1-2017.
This can help porting to platforms that support only proleptic TZ.
The package is freely available under the MIT license.</li>
<li><a href="https://github.com/derickr/timelib">Timelib</a> is a C
library that reads <abbr>TZif</abbr> files and converts
@ -649,7 +647,7 @@ that represent <code><abbr>tzdb</abbr></code> timezones.
Python is freely available under the
<a href="https://docs.python.org/3/license.html">Python Software Foundation
License</a>.
A companion <a id="pypi-tzdata" href="https://pypi.org/">PyPI</a> module
A companion <a id="pypi-tzdata" href="https://pypi.org">PyPI</a> module
<a href="https://pypi.org/project/tzdata/"><code>tzdata</code></a>
supplies TZif data if the underlying system data cannot be found;
it is freely available under the Apache License.</li>
@ -897,9 +895,10 @@ summarizes and cites historical <abbr>DST</abbr> regulations.</dd>
href="https://www.ptb.de/cms/en/fachabteilungen/abt4/fb-44/ag-441/realisation-of-legal-time-in-germany.html">Realisation
of Legal Time in Germany</a>.</dd>
<dt>Israel</dt>
<dd>The Interior Ministry periodically issues <a
href="ftp://ftp.cs.huji.ac.il/pub/tz/announcements"
hreflang="he">announcements (in Hebrew)</a>.</dd>
<dd><a
href="https://tz.cs.huji.ac.il">Israel Timezone Files</a>
lists official time-change announcements and laws since 1940,
almost all in Hebrew.</dd>
<dt>Malaysia</dt>
<dd>See Singapore <a href="#Singapore">below</a>.</dd>
<dt>Mexico</dt>
@ -1081,6 +1080,20 @@ In practice the two configurations also agree for timestamps before
1972 even though the historical situation is messy, partly because
neither <abbr>UTC</abbr> nor <abbr>TAI</abbr>
is well-defined for sufficiently old timestamps.</li>
<li><a href="https://kb.meinbergglobal.com/kb/time_sync/ntp/configuration/ntp_leap_second_file">The
<abbr>NTP</abbr> Leap Second File</a> covers the text file
<code>leap-seconds.list</code>, which lists the currently known leap seconds.
The <abbr>IERS</abbr> maintains this file, and a copy is distributed by
<code><abbr>tzdb</abbr></code> for use by <abbr>NTP</abbr> implementations like
<a href="https://www.ntp.org">classic
<code><abbr title="Network Time Protocol Daemon">ntpd</abbr></code></a>
and <a href="https://ntpsec.org">NTPsec</a>.
The <code><abbr>tz</abbr></code> database also distributes leap second
information in a differently-formatted <code>leapseconds</code> text file,
as well as in the "<code>right</code>" configuration in binary form; for
example, <code>right/UTC</code> can be used
by <a href="https://chrony-project.org"><code>chrony</code></a>,
another <abbr>NTP</abbr> implementation.</li>
<li><a href="https://developers.google.com/time/smear">Leap Smear</a>
discusses how to gradually adjust <abbr>POSIX</abbr> clocks near a
leap second so that they disagree with <abbr>UTC</abbr> by at most a
@ -1088,7 +1101,7 @@ 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, <a
the abovementioned <abbr>NTP</abbr> implementations, <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
@ -1111,11 +1124,18 @@ without Leap Seconds</a> gives pointers on this
contentious issue.
The General Conference on Weights and Measures
<a href="https://www.bipm.org/en/cgpm-2022/resolution-4">decided in 2022</a>
to discontinue the use of leap seconds by 2035, replacing them with an
as-yet-undetermined scheme some time after the year 2135.
to discontinue the use of leap seconds by 2035, and requested that no
discontinuous adjustments be made to UTC for at least a century.
The World Radiocommunication Conference <a
href="https://www.itu.int/dms_pub/itu-r/opb/act/R-ACT-WRC.15-2023-PDF-E.pdf">resolved
in 2023</a> to cooperate with this process.
<a href="https://www.preprints.org/manuscript/202406.0043/v1">A proposal
to change the leap-second adjustments to Coordinated Universal Time</a>
(doi:<a href="https://doi.org/10.1088/1681-7575/ad6266">10.1088/1681-7575/ad6266</a>)
would replace leap seconds with 13-second leap smears occurring once per
decade until 2100, with leap smears after that gradually increasing in size.
However, there is still no consensus on whether this is the best way
to replace leap seconds.
</li>
</ul>
</section>
@ -1153,9 +1173,12 @@ headers.</li>
<li>
<a href="https://datatracker.ietf.org/doc/html/rfc3339">Date and Time
on the Internet: Timestamps</a> (Internet <abbr>RFC</abbr> 3339)
specifies an <abbr>ISO</abbr> 8601
profile for use in new Internet
protocols.</li>
specifies an <abbr>ISO</abbr> 8601 profile for use in new Internet protocols.
An extension, <a href="https://datatracker.ietf.org/doc/html/rfc9557">Date
and Time on the Internet: Timestamps with Additional Information</a>
(Internet <abbr>RFC</abbr> 9557) extends this profile
to let you specify the <code><abbr>tzdb</abbr></code> timezone of a timestamp
via suffixes like "<code>[Asia/Tokyo]</code>".
<li>
<a href="https://web.archive.org/web/20190130042457/https://www.hackcraft.net/web/datetime/">Date &amp; Time
Formats on the Web</a> surveys web- and Internet-oriented date and time
@ -1173,8 +1196,8 @@ unfortunately some of these abbreviations were merely the database maintainers'
inventions, and these have been removed when possible.</li>
<li>Numeric time zone abbreviations typically count hours east of
<abbr>UT</abbr>, e.g., +09 for Japan and
&minus;10 for Hawaii. However, the <abbr>POSIX</abbr>
<code><abbr>TZ</abbr></code> environment variable uses the opposite convention.
&minus;10 for Hawaii. However, <abbr>POSIX</abbr> proleptic
<code><abbr>TZ</abbr></code> settings use the opposite convention.
For example, one might use <code><abbr>TZ</abbr>="<abbr
title="Japan Standard Time">JST</abbr>-9"</code> and
<code><abbr>TZ</abbr>="<abbr title="Hawaii Standard Time">HST</abbr>10"</code>

View File

@ -74,7 +74,7 @@ described in the file is associated with the time period
starting with the same-indexed transition time
and continuing up to but not including the next transition time.
(The last time type is present only for consistency checking with the
POSIX.1-2017-style TZ string described below.)
proleptic TZ string described below.)
These values serve as indices into the next field.
.It Va tzh_typecnt
.Vt ttinfo
@ -167,12 +167,12 @@ must also be set.
The standard/wall and UT/local indicators were designed for
transforming a TZif file's transition times into transitions appropriate
for another time zone specified via
a POSIX.1-2017-style TZ string that lacks rules.
a proleptic TZ string that lacks rules.
For example, when TZ="EET\*-2EEST" and there is no TZif file "EET\*-2EEST",
the idea was to adapt the transition times from a TZif file with the
well-known name "posixrules" that is present only for this purpose and
is a copy of the file "Europe/Brussels", a file with a different UT offset.
POSIX does not specify this obsolete transformational behavior,
POSIX does not specify the details of this obsolete transformational behavior,
the default rules are installation-dependent, and no implementation
is known to support this feature for timestamps past 2037,
so users desiring (say) Greek time should instead specify
@ -197,12 +197,12 @@ identical in format except that
eight bytes are used for each transition time or leap second time.
(Leap second counts remain four bytes.)
After the second header and data comes a newline-enclosed string
in the style of the contents of a POSIX.1-2017 TZ environment variable,
in the style of the contents of a proleptic TZ,
for use in handling instants
after the last transition time stored in the file
or for all instants if the file has no transitions.
The TZ string is empty (i.e., nothing between the newlines)
if there is no POSIX.1-2017-style representation for such instants.
if there is no proleptic representation for such instants.
If nonempty, the TZ string must agree with the local time
type after the last transition time if present in the eight-byte data;
for example, given the string
@ -215,13 +215,14 @@ Also, if there is at least one transition, time type 0 is associated
with the time period from the indefinite past up to but not including
the earliest transition time.
.Ss Version 3 format
For version-3-format timezone files, the TZ string may
use two minor extensions to the POSIX.1-2017 TZ format, as described in
.Xr newtzset 3 .
First, the hours part of its transition times may be signed and range from
\-167 through 167 instead of the POSIX-required unsigned values
For version-3-format timezone files, a TZ string (see
.Xr newtzset 3 )
may use the following POSIX.1-2024 extensions to POSIX.1-2017:
First, as in TZ="<\*-02>2<\*-01>,M3.5.0/\*-1,M10.5.0/0",
the hours part of its transition times may be signed and range from
\-167 through 167 instead of being limited to unsigned values
from 0 through 24.
Second, DST is in effect all year if it starts
Second, as in TZ="XXX3EDT4,0/0,J365/23", DST is in effect all year if it starts
January 1 at 00:00 and ends December 31 at 24:00 plus the difference
between daylight saving and standard time.
.Ss Version 4 format
@ -336,7 +337,8 @@ version 2+ data even if the reader's native timestamps have only
.It
Some readers designed for version 2 might mishandle
timestamps after a version 3 or higher file's last transition, because
they cannot parse extensions to POSIX.1-2017 in the TZ-like string.
they cannot parse the POSIX.1-2024 extensions to POSIX.1-2017
in the proleptic TZ string.
As a partial workaround, a writer can output more transitions
than necessary, so that only far-future timestamps are
mishandled by version 2 readers.
@ -368,6 +370,18 @@ timestamps from the time type of the last transition.
As a partial workaround, a writer can output more transitions
than necessary.
.It
Some stripped-down readers ignore everything but the footer,
and use its proleptic TZ string to calculate all timestamps.
Although this approach often works for current and future timestamps,
it obviously has problems with past timestamps,
and even for current timestamps it can fail for settings like
TZ="Africa/Casablanca". This corresponds to a TZif file
containing explicit transitions through the year 2087,
followed by a footer containing the TZ string
.Dq <+01>\*-1 ,
which should be used only for timestamps after the last
explicit transition.
.It
Some readers do not use time type 0 for timestamps before
the first transition, in that they infer a time type using a
heuristic that does not always select time type 0.

View File

@ -78,14 +78,16 @@ struct tzhead {
** If tzh_version is '2' or greater, the above is followed by a second instance
** of tzhead and a second instance of the data in which each coded transition
** time uses 8 rather than 4 chars,
** then a POSIX-TZ-environment-variable-style string for use in handling
** then a POSIX.1-2017 proleptic TZ string for use in handling
** instants after the last transition time stored in the file
** (with nothing between the newlines if there is no POSIX.1-2017
** representation for such instants).
**
** If tz_version is '3' or greater, the above is extended as follows.
** If tz_version is '3' or greater, the TZ string can be any POSIX.1-2024
** proleptic TZ string, which means the above is extended as follows.
** First, the TZ string's hour offset may range from -167
** through 167 as compared to the POSIX-required 0 through 24.
** through 167 as compared to the range 0 through 24 required
** by POSIX.1-2017 and earlier.
** Second, its DST start time may be January 1 at 00:00 and its stop
** time December 31 at 24:00 plus the difference between DST and
** standard time, indicating DST all year.

View File

@ -20,12 +20,6 @@ REPORT_BUGS_TO=tz@iana.org
# Korn Shell <http://www.kornshell.com/>
# MirBSD Korn Shell <http://www.mirbsd.org/mksh.htm>
#
# For portability to Solaris 10 /bin/sh (supported by Oracle through
# January 2027) this script avoids some POSIX features and common
# extensions, such as $(...), $((...)), ! CMD, unquoted ^, ${#ID},
# ${ID##PAT}, ${ID%%PAT}, and $10. Although some of these constructs
# work sometimes, it's simpler to avoid them entirely.
#
# This script also uses several features of POSIX awk.
# If your host lacks awk, or has an old awk that does not conform to POSIX,
# you can use any of the following free programs instead:
@ -45,7 +39,6 @@ set -f
# Specify default values for environment variables if they are unset.
: ${AWK=awk}
: ${PWD=`pwd`}
: ${TZDIR=$PWD}
# Output one argument as-is to standard output, with trailing newline.
@ -54,13 +47,6 @@ say() {
printf '%s\n' "$1"
}
# Check for awk POSIX compliance.
($AWK -v x=y 'BEGIN { exit 123 }') <>/dev/null >&0 2>&0
[ $? = 123 ] || {
say >&2 "$0: Sorry, your '$AWK' program is not POSIX compatible."
exit 1
}
coord=
location_limit=10
zonetabtype=zone1970
@ -117,8 +103,7 @@ then
else
doselect() {
# Field width of the prompt numbers.
print_nargs_length="BEGIN {print length(\"$#\");}"
select_width=`$AWK "$print_nargs_length"`
select_width=${##}
select_i=
@ -129,14 +114,14 @@ else
select_i=0
for select_word
do
select_i=`$AWK "BEGIN { print $select_i + 1 }"`
select_i=$(($select_i + 1))
printf >&2 "%${select_width}d) %s\\n" $select_i "$select_word"
done;;
*[!0-9]*)
echo >&2 'Please enter a number in range.';;
*)
if test 1 -le $select_i && test $select_i -le $#; then
shift `$AWK "BEGIN { print $select_i - 1 }"`
shift $(($select_i - 1))
select_result=$1
break
fi
@ -170,7 +155,7 @@ do
esac
done
shift `$AWK "BEGIN { print $OPTIND - 1 }"`
shift $(($OPTIND - 1))
case $# in
0) ;;
*) say >&2 "$0: $1: unknown argument"; exit 1
@ -178,11 +163,13 @@ esac
# translit=true to try transliteration.
# This is false if U+12345 CUNEIFORM SIGN URU TIMES KI has length 1
# which means awk (and presumably the shell) do not need transliteration.
if $AWK 'BEGIN { u12345 = "\360\222\215\205"; exit length(u12345) == 1 }'; then
translit=true
else
translit=false
# which means the shell and (presumably) awk do not need transliteration.
# It is true if the byte string has some other length in characters, or
# if this is a POSIX.1-2017 or earlier shell that does not support $'...'.
CUNEIFORM_SIGN_URU_TIMES_KI=$'\360\222\215\205'
if test ${#CUNEIFORM_SIGN_URU_TIMES_KI} = 1
then translit=false
else translit=true
fi
# Read into shell variable $1 the contents of file $2.
@ -192,10 +179,10 @@ fi
# if that does not work, fall back on 'cat'.
read_file() {
{ $translit && {
eval "$1=\`(iconv -f UTF-8 -t //TRANSLIT) 2>/dev/null <\"\$2\"\`" ||
eval "$1=\`(iconv -f UTF-8) 2>/dev/null <\"\$2\"\`"
eval "$1=\$( (iconv -f UTF-8 -t //TRANSLIT) 2>/dev/null <\"\$2\")" ||
eval "$1=\$( (iconv -f UTF-8) 2>/dev/null <\"\$2\")"
}; } ||
eval "$1=\`cat <\"\$2\"\`" || {
eval "$1=\$(cat <\"\$2\")" || {
say >&2 "$0: time zone files are not set up correctly"
exit 1
}
@ -403,7 +390,7 @@ while
echo >&2 \
'Please select a continent, ocean, "coord", "TZ", "time", or "now".'
quoted_continents=`
quoted_continents=$(
$AWK '
function handle_entry(entry) {
entry = substr(entry, 1, index(entry, "/") - 1)
@ -433,12 +420,12 @@ while
sort -u |
tr '\n' ' '
echo ''
`
)
eval '
doselect '"$quoted_continents"' \
"coord - I want to use geographical coordinates." \
"TZ - I want to specify the timezone using a POSIX.1-2017 TZ string." \
"TZ - I want to specify the timezone using a proleptic TZ string." \
"time - I know local time already." \
"now - Like \"time\", but configure only for timestamps from now on."
continent=$select_result
@ -462,16 +449,17 @@ while
case $continent in
TZ)
# Ask the user for a POSIX.1-2017 TZ string. Check that it conforms.
# Ask the user for a proleptic TZ string. Check that it conforms.
check_POSIX_TZ_string='
BEGIN {
tz = substr(ARGV[1], 2)
ARGV[1] = ""
tzname = ("(<[[:alnum:]+-][[:alnum:]+-][[:alnum:]+-]+>" \
"|[[:alpha:]][[:alpha:]][[:alpha:]]+)")
time = ("(2[0-4]|[0-1]?[0-9])" \
"(:[0-5][0-9](:[0-5][0-9])?)?")
offset = "[-+]?" time
sign = "[-+]?"
hhmm = "(:[0-5][0-9](:[0-5][0-9])?)?"
offset = sign "(2[0-4]|[0-1]?[0-9])" hhmm
time = sign "(16[0-7]|(1[0-5]|[0-9]?)[0-9])" hhmm
mdate = "M([1-9]|1[0-2])\\.[1-5]\\.[0-6]"
jdate = ("((J[1-9]|[0-9]|J?[1-9][0-9]" \
"|J?[1-2][0-9][0-9])|J?3[0-5][0-9]|J?36[0-5])")
@ -492,7 +480,7 @@ while
read tz
$AWK "$check_POSIX_TZ_string" ="$tz"
do
say >&2 "'$tz' is not a conforming POSIX.1-2017 timezone string."
say >&2 "'$tz' is not a conforming POSIX proleptic TZ string."
done
TZ_for_date=$tz;;
*)
@ -507,14 +495,14 @@ while
'74 degrees 3 minutes west.'
read coord
esac
distance_table=`
distance_table=$(
$AWK \
"$output_distances_or_times" \
="$coord" ="$TZ_COUNTRY_TABLE" ="$TZ_ZONE_TABLE" |
sort -n |
$AWK "{print} NR == $location_limit { exit }"
`
regions=`
)
regions=$(
$AWK '
BEGIN {
distance_table = substr(ARGV[1], 2)
@ -526,13 +514,13 @@ while
}
}
' ="$distance_table"
`
)
echo >&2 'Please select one of the following timezones,'
echo >&2 'listed roughly in increasing order' \
"of distance from $coord".
doselect $regions
region=$select_result
tz=`
tz=$(
$AWK '
BEGIN {
distance_table = substr(ARGV[1], 2)
@ -546,22 +534,22 @@ while
}
}
' ="$distance_table" ="$region"
`;;
);;
*)
case $continent in
now|time)
minute_format='%a %b %d %H:%M'
old_minute=`TZ=UTC0 date +"$minute_format"`
old_minute=$(TZ=UTC0 date +"$minute_format")
for i in 1 2 3
do
time_table_command=`
time_table_command=$(
$AWK \
-v output_times=1 \
"$output_distances_or_times" \
= = ="$TZ_ZONE_TABLE"
`
time_table=`eval "$time_table_command"`
new_minute=`TZ=UTC0 date +"$minute_format"`
)
time_table=$(eval "$time_table_command")
new_minute=$(TZ=UTC0 date +"$minute_format")
case $old_minute in
"$new_minute") break
esac
@ -569,11 +557,11 @@ while
done
echo >&2 "The system says Universal Time is $new_minute."
echo >&2 "Assuming that's correct, what is the local time?"
sorted_table=`say "$time_table" | sort -k2n -k2,5 -k1n` || {
sorted_table=$(say "$time_table" | sort -k2n -k2,5 -k1n) || {
say >&2 "$0: cannot sort time table"
exit 1
}
eval doselect `
eval doselect $(
$AWK '
BEGIN {
sorted_table = substr(ARGV[1], 2)
@ -590,10 +578,10 @@ while
}
}
' ="$sorted_table"
`
)
time=$select_result
continent_re='^'
zone_table=`
zone_table=$(
$AWK '
BEGIN {
time = substr(ARGV[1], 2)
@ -609,13 +597,13 @@ while
}
}
' ="$time" ="$time_table"
`
countries=`
)
countries=$(
$AWK \
"$output_country_list" \
="$continent_re" ="$TZ_COUNTRY_TABLE" ="$zone_table" |
sort -f
`
)
;;
*)
continent_re="^$continent/"
@ -623,16 +611,16 @@ while
esac
# Get list of names of countries in the continent or ocean.
countries=`
countries=$(
$AWK \
"$output_country_list" \
="$continent_re" ="$TZ_COUNTRY_TABLE" ="$zone_table" |
sort -f
`
)
# If all zone table entries have comments, and there are
# at most 22 entries, asked based on those comments.
# This fits the prompt onto old-fashioned 24-line screens.
regions=`
regions=$(
$AWK '
BEGIN {
TZ_ZONE_TABLE = substr(ARGV[1], 2)
@ -653,7 +641,7 @@ while
print comment[i]
}
' ="$zone_table"
`
)
# If there's more than one country, ask the user which one.
case $countries in
@ -669,7 +657,7 @@ while
# Get list of timezones in the country.
regions=`
regions=$(
$AWK '
BEGIN {
country = substr(ARGV[1], 2)
@ -696,7 +684,7 @@ while
}
}
' ="$country" ="$TZ_COUNTRY_TABLE" ="$zone_table"
`
)
# If there's more than one region, ask the user which one.
case $regions in
@ -707,7 +695,7 @@ while
esac
# Determine tz from country and region.
tz=`
tz=$(
$AWK '
BEGIN {
country = substr(ARGV[1], 2)
@ -735,7 +723,7 @@ while
}
}
' ="$country" ="$region" ="$TZ_COUNTRY_TABLE" ="$zone_table"
`
)
esac
# Make sure the corresponding zoneinfo file exists.
@ -754,14 +742,11 @@ while
extra_info=
for i in 1 2 3 4 5 6 7 8
do
TZdate=`LANG=C TZ="$TZ_for_date" date`
UTdate=`LANG=C TZ=UTC0 date`
if $AWK '
function getsecs(d) {
return match(d, /.*:[0-5][0-9]/) ? substr(d, RLENGTH - 1, 2) : ""
}
BEGIN { exit getsecs(ARGV[1]) != getsecs(ARGV[2]) }
' ="$TZdate" ="$UTdate"
TZdate=$(LANG=C TZ="$TZ_for_date" date)
UTdate=$(LANG=C TZ=UTC0 date)
TZsecsetc=${TZdate##*[0-5][0-9]:}
UTsecsetc=${UTdate##*[0-5][0-9]:}
if test "${TZsecsetc%%[!0-9]*}" = "${UTsecsetc%%[!0-9]*}"
then
extra_info="
Selected time is now: $TZdate.
@ -801,7 +786,7 @@ done
case $SHELL in
*csh) file=.login line="setenv TZ '$tz'";;
*) file=.profile line="TZ='$tz'; export TZ"
*) file=.profile line="export TZ='$tz'"
esac
test -t 1 && say >&2 "

View File

@ -1 +1 @@
2024a
2024b

View File

@ -7,8 +7,7 @@
if (type nroff && type perl) >/dev/null 2>&1; then
# Tell groff not to emit SGR escape sequences (ANSI color escapes).
GROFF_NO_SGR=1
export GROFF_NO_SGR
export GROFF_NO_SGR=1
echo ".am TH
.hy 0

View File

@ -89,7 +89,7 @@ static bool warned;
static bool errout;
static char const *abbr(struct tm const *);
ATTRIBUTE_REPRODUCIBLE static intmax_t delta(struct tm *, struct tm *);
static intmax_t delta(struct tm *, struct tm *);
static void dumptime(struct tm const *);
static time_t hunt(timezone_t, time_t, time_t, bool);
static void show(timezone_t, char *, time_t, bool);
@ -97,7 +97,7 @@ static void showextrema(timezone_t, char *, time_t, struct tm *, time_t);
static void showtrans(char const *, struct tm const *, time_t, char const *,
char const *);
static const char *tformat(void);
ATTRIBUTE_REPRODUCIBLE static time_t yeartot(intmax_t);
ATTRIBUTE_PURE_114833 static time_t yeartot(intmax_t);
/* Is C an ASCII digit? */
static bool
@ -134,7 +134,7 @@ size_overflow(void)
/* Return A + B, exiting if the result would overflow either ptrdiff_t
or size_t. A and B are both nonnegative. */
ATTRIBUTE_REPRODUCIBLE static ptrdiff_t
ATTRIBUTE_PURE_114833 static ptrdiff_t
sumsize(ptrdiff_t a, ptrdiff_t b)
{
#ifdef ckd_add
@ -162,7 +162,7 @@ xstrsize(char const *str)
/* Return a pointer to a newly allocated buffer of size SIZE, exiting
on failure. SIZE should be positive. */
ATTRIBUTE_MALLOC static void *
static void *
xmalloc(ptrdiff_t size)
{
void *p = malloc(size);
@ -934,7 +934,7 @@ showextrema(timezone_t tz, char *zone, time_t lo, struct tm *lotmp, time_t hi)
# include <stdarg.h>
/* A substitute for snprintf that is good enough for zdump. */
ATTRIBUTE_FORMAT((printf, 3, 4)) static int
static int
my_snprintf(char *s, size_t size, char const *format, ...)
{
int n;

View File

@ -156,7 +156,7 @@ causes a TZif file to contain explicit entries for
.Em pre-
.Ar hi
transitions rather than concisely representing them
with an extended POSIX.1-2017 TZ string.
with a proleptic TZ string.
Also see the
.Fl b Cm slim
option for another way to shrink output size.
@ -165,10 +165,10 @@ 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.1-2017 TZ string.
more concisely represented via the proleptic TZ string.
This option does not affect the represented timestamps.
Although it accommodates nonstandard TZif readers
that ignore the extended POSIX.1-2017 TZ string,
that ignore the proleptic 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
@ -227,11 +227,10 @@ for
.It
The output file does not contain all the information about the
long-term future of a timezone, because the future cannot be summarized as
an extended POSIX.1-2017 TZ string.
For example, as of 2023 this problem
a proleptic TZ string. For example, as of 2023 this problem
occurs for Morocco's daylight-saving rules, as these rules are based
on predictions for when Ramadan will be observed, something that
an extended POSIX.1-2017 TZ string cannot represent.
a proleptic TZ string cannot represent.
.It
The output contains data that may not be handled properly by client
code designed for older
@ -535,21 +534,27 @@ 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,
alternatively, a field in the same format as a rule-line SAVE column,
alternatively, a field in the same format as a rule-line
.Ar SAVE
field,
giving the amount of time to be added to local standard time
and whether the resulting time is standard or daylight saving.
If this field is
.Ql \-
then standard time always applies.
Standard time applies if this field is
.Ql \*-
or for timestamps occurring before any rule takes effect.
When an amount of time is given, only the sum of standard time and
this amount matters.
.It FORMAT
The format for time zone abbreviations.
The pair of characters
.Ql %s
is used to show where the
.Dq "variable part"
of the time zone abbreviation goes.
shows where to put the time zone abbreviation's variable part,
which is taken from the
.Ar LETTER/S
field of the corresponding rule;
any timestamps that precede the earliest rule use the
.Ar LETTER/S
of the earliest standard-time rule (which in this case must exist).
Alternatively, a format can use the pair of characters
.Ql %z
to stand for the UT offset in the form
@ -633,13 +638,12 @@ that would otherwise take effect in the next
seconds is instead assumed to take effect simultaneously.
For example:
.Bd -literal -offset indent
# Rule NAME FROM TO \*- IN ON AT SAVE LETTER/S
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule US 1967 2006 - Oct lastSun 2:00 0 S
Rule US 1967 1973 - Apr lastSun 2:00 1:00 D
# Zone\0\0NAME STDOFF RULES FORMAT [UNTIL]
Zone\0\0America/Menominee \*-5:00 \*- EST 1973 Apr 29 2:00
\*-6:00 US C%sT
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Menominee -5:00 - EST 1973 Apr 29 2:00
-6:00 US C%sT
.Ed
Here, an incorrect reading would be there were two clock changes on 1973-04-29,
the first from 02:00 EST (\-05) to 01:00 CST (\-06),
@ -730,16 +734,16 @@ or
if the leap second time given by the other fields should be interpreted as
local (wall clock) time.
.Pp
Rolling leap seconds were implemented back when it was not
clear whether common practice was rolling or stationary,
with concerns that one would see
Rolling leap seconds would let one see
Times Square ball drops where there'd be a
.Dq "3... 2... 1... leap... Happy New Year"
countdown, placing the leap second at
midnight New York time rather than midnight UTC.
However, this countdown style does not seem to have caught on,
which means rolling leap seconds are not used in practice;
also, they are not supported if the
Although stationary leap seconds are the common practice,
rolling leap seconds can be useful in specialized applications
like SMPTE timecodes that may prefer to put leap second
discontinuities at the end of a local broadcast day.
However, rolling leap seconds are not supported if the
.Fl r
option is used.
.Pp

View File

@ -472,7 +472,7 @@ size_overflow(void)
memory_exhausted(_("size overflow"));
}
ATTRIBUTE_REPRODUCIBLE static ptrdiff_t
ATTRIBUTE_PURE_114833 static ptrdiff_t
size_sum(size_t a, size_t b)
{
#ifdef ckd_add
@ -486,7 +486,7 @@ size_sum(size_t a, size_t b)
size_overflow();
}
ATTRIBUTE_REPRODUCIBLE static ptrdiff_t
ATTRIBUTE_PURE_114833 static ptrdiff_t
size_product(ptrdiff_t nitems, ptrdiff_t itemsize)
{
#ifdef ckd_mul
@ -501,7 +501,7 @@ size_product(ptrdiff_t nitems, ptrdiff_t itemsize)
size_overflow();
}
ATTRIBUTE_REPRODUCIBLE static ptrdiff_t
ATTRIBUTE_PURE_114833 static ptrdiff_t
align_to(ptrdiff_t size, ptrdiff_t alignment)
{
size_t lo_bits = alignment - 1, sum = size_sum(size, lo_bits);
@ -525,7 +525,7 @@ memcheck(void *ptr)
return ptr;
}
ATTRIBUTE_MALLOC static void *
static void *
emalloc(size_t size)
{
return memcheck(malloc(size));
@ -537,7 +537,7 @@ erealloc(void *ptr, size_t size)
return memcheck(realloc(ptr, size));
}
ATTRIBUTE_MALLOC static char *
static char *
estrdup(char const *str)
{
return memcheck(strdup(str));
@ -1475,7 +1475,7 @@ relname(char const *target, char const *linkname)
/* Return true if A and B must have the same parent dir if A and B exist.
Return false if this is not necessarily true (though it might be true).
Keep it simple, and do not inspect the file system. */
static bool
ATTRIBUTE_PURE_114833 static bool
same_parent_dirs(char const *a, char const *b)
{
for (; *a == *b; a++, b++)
@ -3034,10 +3034,10 @@ rule_cmp(struct rule const *a, struct rule const *b)
return a->r_dayofmonth - b->r_dayofmonth;
}
/* Store into RESULT a POSIX.1-2017 TZ string that represent the future
/* Store into RESULT a proleptic TZ string that represent the future
predictions for the zone ZPFIRST with ZONECOUNT entries. Return a
compatibility indicator (a TZDB release year) if successful, a
negative integer if no such TZ string exissts. */
negative integer if no such TZ string exists. */
static int
stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
{
@ -3229,8 +3229,7 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
if (noise) {
if (!*envvar)
warning("%s %s",
_("no POSIX.1-2017 environment variable"
" for zone"),
_("no proleptic TZ string for zone"),
zpfirst->z_name);
else if (compat != 0) {
/* Circa-COMPAT clients, and earlier clients, might
@ -3494,7 +3493,7 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
if (do_extend) {
/*
** If we're extending the explicitly listed observations for
** 400 years because we can't fill the POSIX.1-2017 TZ field,
** 400 years because we can't fill the proleptic TZ field,
** check whether we actually ended up explicitly listing
** observations through that period. If there aren't any
** near the end of the 400-year period, add a redundant
@ -3679,7 +3678,7 @@ lowerit(char a)
}
/* case-insensitive equality */
ATTRIBUTE_REPRODUCIBLE static bool
ATTRIBUTE_PURE_114833 static bool
ciequal(register const char *ap, register const char *bp)
{
while (lowerit(*ap) == lowerit(*bp++))
@ -3688,7 +3687,7 @@ ciequal(register const char *ap, register const char *bp)
return false;
}
ATTRIBUTE_REPRODUCIBLE static bool
ATTRIBUTE_PURE_114833 static bool
itsabbr(register const char *abbr, register const char *word)
{
if (lowerit(*abbr) != lowerit(*word))
@ -3704,7 +3703,7 @@ itsabbr(register const char *abbr, register const char *word)
/* Return true if ABBR is an initial prefix of WORD, ignoring ASCII case. */
ATTRIBUTE_REPRODUCIBLE static bool
ATTRIBUTE_PURE_114833 static bool
ciprefix(char const *abbr, char const *word)
{
do
@ -3814,7 +3813,7 @@ time_overflow(void)
exit(EXIT_FAILURE);
}
ATTRIBUTE_REPRODUCIBLE static zic_t
ATTRIBUTE_PURE_114833 static zic_t
oadd(zic_t t1, zic_t t2)
{
#ifdef ckd_add
@ -3828,7 +3827,7 @@ oadd(zic_t t1, zic_t t2)
time_overflow();
}
ATTRIBUTE_REPRODUCIBLE static zic_t
ATTRIBUTE_PURE_114833 static zic_t
tadd(zic_t t1, zic_t t2)
{
#ifdef ckd_add