Update tzcode to 2024a.

MFC after:	3 weeks
Sponsored by:	Klara, Inc.

(cherry picked from commit 46c599340f)
This commit is contained in:
Dag-Erling Smørgrav 2024-02-13 21:20:44 +01:00
parent bfafc6a86d
commit 16349f296b
24 changed files with 1765 additions and 1187 deletions

View File

@ -1,7 +1,25 @@
# Make and install tzdb code and data.
# This file is in the public domain, so clarified as of
# 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.
# To affect how this Makefile works, you can run a shell script like this:
#
# #!/bin/sh
# make CC='gcc -std=gnu11' "$@"
#
# 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.
#
# Alternatively, you can simply edit this Makefile to tailor the following
# macro definitions.
###############################################################################
# Start of macros that one plausibly might want to tailor.
# Package name for the code distribution.
PACKAGE= tzcode
@ -35,7 +53,7 @@ DATAFORM= main
LOCALTIME= Factory
# The POSIXRULES macro controls interpretation of POSIX-like TZ
# The POSIXRULES macro controls interpretation of POSIX-2017.1-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:
@ -191,8 +209,9 @@ UTF8_LOCALE= en_US.utf8
# On some hosts, this should have -lintl unless CFLAGS has -DHAVE_GETTEXT=0.
LDLIBS=
# Add the following to the end of the "CFLAGS=" line as needed to override
# defaults specified in the source code. "-DFOO" is equivalent to "-DFOO=1".
# Add the following to an uncommented "CFLAGS=" line as needed
# to override defaults specified in the source code or by the system.
# "-DFOO" is equivalent to "-DFOO=1".
# -DDEPRECATE_TWO_DIGIT_YEARS for optional runtime warnings about strftime
# formats that generate only the last two digits of year numbers
# -DEPOCH_LOCAL if the 'time' function returns local time not UT
@ -234,11 +253,16 @@ LDLIBS=
# -DHAVE_UNISTD_H=0 if <unistd.h> does not work*
# -DHAVE_UTMPX_H=0 if <utmpx.h> does not work*
# -Dlocale_t=XXX if your system uses XXX instead of locale_t
# -DPORT_TO_C89 if tzcode should also run on C89 platforms+
# -DPORT_TO_C89 if tzcode should also run on mostly-C89 platforms+
# Typically it is better to use a later standard. For example,
# with GCC 4.9.4 (2016), prefer '-std=gnu11' to '-DPORT_TO_C89'.
# Even with -DPORT_TO_C89, the code needs at least one C99
# feature (integers at least 64 bits wide) and maybe more.
# -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.
# -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;
@ -250,7 +274,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-style TZ strings lacking them,
# DST transitions for POSIX.1-2017-style 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.
@ -270,11 +294,15 @@ LDLIBS=
# -DZIC_MAX_ABBR_LEN_WO_WARN=3
# (or some other number) to set the maximum time zone abbreviation length
# that zic will accept without a warning (the default is 6)
# -g to generate symbolic debugging info
# -Idir to include from directory 'dir'
# -O0 to disable optimization; other -O options to enable more optimization
# -Uname to remove any definition of the macro 'name'
# $(GCC_DEBUG_FLAGS) if you are using recent GCC and want lots of checking
#
# * 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.
# once the code assumes C99 or later, say in the year 2029.
#
# Select instrumentation via "make GCC_INSTRUMENT='whatever'".
GCC_INSTRUMENT = \
@ -312,9 +340,10 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
# guess TM_GMTOFF from other macros; define NO_TM_GMTOFF to suppress this.
# 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
# not required by POSIX, a future version of POSIX is planned to require them
# and they are widely available on GNU/Linux and BSD systems.
# 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.
#
# The next batch of options control support for external variables
# exported by tzcode. In practice these variables are less useful
@ -324,7 +353,7 @@ 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 1988 and later.
# # to the "CFLAGS=" line. "tzname" is required by POSIX.1-1988 and later.
# # 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,
@ -334,8 +363,8 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
# # -DUSG_COMPAT=0 # do not support
# # -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 2008 (with XSI) and later.
# # 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).
# # If not defined, the code attempts to guess USG_COMPAT from other macros.
# #
# # To support the external variable "altzone", add
@ -353,10 +382,11 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
# functions to be added to the time conversion library.
# "offtime" is like "gmtime" except that it accepts a second (long) argument
# that gives an offset to add to the time_t when converting it.
# "offtime_r" is to "offtime" what "gmtime_r" is to "gmtime".
# "timelocal" is equivalent to "mktime".
# I.e., "offtime" is like calling "localtime_rz" with a fixed-offset zone.
# "timelocal" is nearly equivalent to "mktime".
# "timeoff" is like "timegm" except that it accepts a second (long) argument
# that gives an offset to use when converting to a time_t.
# I.e., "timeoff" is like calling "mktime_z" with a fixed-offset zone.
# "posix2time" and "time2posix" are described in an included manual page.
# X3J11's work does not describe any of these functions.
# These functions may well disappear in future releases of the time
@ -379,7 +409,7 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
#
# NIST-PCTS:151-2, Version 1.4, (1993-12-03) is a test suite put
# out by the National Institute of Standards and Technology
# which claims to test C and Posix conformance. If you want to pass PCTS, add
# which claims to test C and POSIX conformance. If you want to pass PCTS, add
# -DPCTS
# to the end of the "CFLAGS=" line.
#
@ -389,19 +419,33 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
# 53 as a week number (rather than 52 or 53) for January days before
# January's first Monday when a "%V" format is used and January 1
# falls on a Friday, Saturday, or Sunday.
#
# POSIX says CFLAGS defaults to "-O 1".
# Uncomment the following line and edit its contents as needed.
CFLAGS=
#CFLAGS= -O 1
# Linker flags. Default to $(LFLAGS) for backwards compatibility
# to release 2012h and earlier.
LDFLAGS= $(LFLAGS)
# 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.
#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
# The file is generated by the IERS Earth Orientation Centre, in Paris.
leaplist_TZ = Europe/Paris
# The zic command and its arguments.
zic= ./zic
@ -419,22 +463,23 @@ ZFLAGS=
ZIC_INSTALL= $(ZIC) -d '$(DESTDIR)$(TZDIR)' $(LEAPSECONDS)
# The name of a Posix-compliant 'awk' on your system.
# The name of a POSIX-compliant 'awk' on your system.
# mawk 1.3.3 and Solaris 10 /usr/bin/awk do not work.
# Also, it is better (though not essential) if 'awk' supports UTF-8,
# and unfortunately mawk and busybox awk do not support UTF-8.
# Try AWK=gawk or AWK=nawk if your awk has the abovementioned problems.
AWK= awk
# The full path name of a Posix-compliant shell, preferably one that supports
# The full path name of a POSIX-compliant shell, preferably one that supports
# the Korn shell's 'select' statement as an extension.
# These days, Bash is the most popular.
# It should be OK to set this to /bin/sh, on platforms where /bin/sh
# lacks 'select' or doesn't completely conform to Posix, but /bin/bash
# lacks 'select' or doesn't completely conform to POSIX, but /bin/bash
# is typically nicer if it works.
KSHELL= /bin/bash
# Name of curl <https://curl.haxx.se/>, used for HTML validation.
# Name of curl <https://curl.haxx.se/>, used for HTML validation
# and to fetch leap-seconds.list from upstream.
CURL= curl
# Name of GNU Privacy Guard <https://gnupg.org/>, used to sign distributions.
@ -504,18 +549,17 @@ GZIPFLAGS= -9n
DIFF_TZS= diff -u$$(! diff -u -F'^TZ=' - - <>/dev/null >&0 2>&1 \
|| echo ' -F^TZ=')
###############################################################################
#MAKE= make
cc= cc
CC= $(cc) -DTZDIR='"$(TZDIR)"'
AR= ar
# ':' on typical hosts; 'ranlib' on the ancient hosts that still need ranlib.
RANLIB= :
# POSIX prohibits defining or using SHELL. However, csh users on systems
# that use the user shell for Makefile commands may need to define SHELL.
#SHELL= /bin/sh
# End of macros that one plausibly might want to tailor.
###############################################################################
TZCOBJS= zic.o
TZDOBJS= zdump.o localtime.o asctime.o strftime.o
DATEOBJS= date.o localtime.o strftime.o asctime.o
@ -544,7 +588,7 @@ YDATA= $(PRIMARY_YDATA) etcetera
NDATA= factory
TDATA_TO_CHECK= $(YDATA) $(NDATA) backward
TDATA= $(YDATA) $(NDATA) $(BACKWARD)
ZONETABLES= zone1970.tab zone.tab
ZONETABLES= zone.tab zone1970.tab zonenow.tab
TABDATA= iso3166.tab $(TZDATA_TEXT) $(ZONETABLES)
LEAP_DEPS= leapseconds.awk leap-seconds.list
TZDATA_ZI_DEPS= ziguard.awk zishrink.awk version $(TDATA) \
@ -552,7 +596,7 @@ TZDATA_ZI_DEPS= ziguard.awk zishrink.awk version $(TDATA) \
DSTDATA_ZI_DEPS= ziguard.awk $(TDATA) $(PACKRATDATA) $(PACKRATLIST)
DATA= $(TDATA_TO_CHECK) backzone iso3166.tab leap-seconds.list \
leapseconds $(ZONETABLES)
AWK_SCRIPTS= checklinks.awk checktab.awk leapseconds.awk \
AWK_SCRIPTS= checklinks.awk checknow.awk checktab.awk leapseconds.awk \
ziguard.awk zishrink.awk
MISC= $(AWK_SCRIPTS)
TZS_YEAR= 2050
@ -573,7 +617,7 @@ VERSION_DEPS= \
calendars CONTRIBUTING LICENSE Makefile NEWS README SECURITY \
africa antarctica asctime.c asia australasia \
backward backzone \
checklinks.awk checktab.awk \
checklinks.awk checknow.awk checktab.awk \
date.1 date.c difftime.c \
etcetera europe factory iso3166.tab \
leap-seconds.list leapseconds.awk localtime.c \
@ -583,12 +627,7 @@ VERSION_DEPS= \
tzfile.5 tzfile.h tzselect.8 tzselect.ksh \
workman.sh zdump.8 zdump.c zic.8 zic.c \
ziguard.awk zishrink.awk \
zone.tab zone1970.tab
# And for the benefit of csh users on systems that assume the user
# shell should be used to handle commands in Makefiles. . .
SHELL= /bin/sh
zone.tab zone1970.tab zonenow.tab
all: tzselect zic zdump libtz.a $(TABDATA) \
vanguard.zi main.zi rearguard.zi
@ -658,6 +697,16 @@ tzdata.zi: $(DATAFORM).zi version zishrink.awk
$(DATAFORM).zi >$@.out
mv $@.out $@
tzdir.h:
printf '%s\n' >$@.out \
'#ifndef TZDEFAULT' \
'# define TZDEFAULT "$(TZDEFAULT)" /* default zone */' \
'#endif' \
'#ifndef TZDIR' \
'# define TZDIR "$(TZDIR)" /* TZif directory */' \
'#endif'
mv $@.out $@
version.h: version
VERSION=`cat version` && printf '%s\n' \
'static char const PKGVERSION[]="($(PACKAGE)) ";' \
@ -677,6 +726,28 @@ leapseconds: $(LEAP_DEPS)
-f leapseconds.awk leap-seconds.list >$@.out
mv $@.out $@
# Awk script to extract a Git-style author from leap-seconds.list comments.
EXTRACT_AUTHOR = \
author_line { sub(/^.[[:space:]]*/, ""); \
sub(/:[[:space:]]*/, " <"); \
printf "%s>\n", $$0; \
success = 1; \
exit \
} \
/Questions or comments to:/ { author_line = 1 } \
END { exit !success }
# Fetch leap-seconds.list from upstream.
fetch-leap-seconds.list:
$(CURL) -OR $(leaplist_URI)
# Fetch leap-seconds.list from upstream and commit it to the local repository.
commit-leap-seconds.list: fetch-leap-seconds.list
author=$$($(AWK) '$(EXTRACT_AUTHOR)' leap-seconds.list) && \
date=$$(TZ=$(leaplist_TZ) stat -c%y leap-seconds.list) && \
git commit --author="$$author" --date="$$date" -m'make $@' \
leap-seconds.list
# Arguments to pass to submakes of install_data.
# They can be overridden by later submake arguments.
INSTALLARGS = \
@ -764,7 +835,7 @@ force_tzs: $(TZS_NEW)
libtz.a: $(LIBOBJS)
rm -f $@
$(AR) -rc $@ $(LIBOBJS)
$(AR) $(ARFLAGS) $@ $(LIBOBJS)
$(RANLIB) $@
date: $(DATEOBJS)
@ -772,26 +843,32 @@ date: $(DATEOBJS)
tzselect: tzselect.ksh version
VERSION=`cat version` && sed \
-e 's|#!/bin/bash|#!$(KSHELL)|g' \
-e 's|AWK=[^}]*|AWK='\''$(AWK)'\''|g' \
-e 's|\(PKGVERSION\)=.*|\1='\''($(PACKAGE)) '\''|' \
-e 's|\(REPORT_BUGS_TO\)=.*|\1=$(BUGEMAIL)|' \
-e 's|TZDIR=[^}]*|TZDIR=$(TZDIR)|' \
-e 's|\(TZVERSION\)=.*|\1='"$$VERSION"'|' \
<$@.ksh >$@.out
-e "s'#!/bin/bash'#!"'$(KSHELL)'\' \
-e s\''\(AWK\)=[^}]*'\''\1=\'\''$(AWK)\'\'\' \
-e s\''\(PKGVERSION\)=.*'\''\1=\'\''($(PACKAGE)) \'\'\' \
-e s\''\(REPORT_BUGS_TO\)=.*'\''\1=\'\''$(BUGEMAIL)\'\'\' \
-e s\''\(TZDIR\)=[^}]*'\''\1=\'\''$(TZDIR)\'\'\' \
-e s\''\(TZVERSION\)=.*'\''\1=\'"'$$VERSION\\''" \
<$@.ksh >$@.out
chmod +x $@.out
mv $@.out $@
check: check_back check_mild
check_mild: check_character_set check_white_space check_links \
check_name_lengths check_slashed_abbrs check_sorted \
check_name_lengths check_now \
check_slashed_abbrs check_sorted \
check_tables check_web check_ziguard check_zishrink check_tzs
# True if UTF8_LOCALE does not work;
# otherwise, false but with LC_ALL set to $(UTF8_LOCALE).
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; }; }
check_character_set: $(ENCHILADA)
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 && \
$(UTF8_LOCALE_MISSING) || { \
sharp='#' && \
! grep -Env $(SAFE_LINE) $(MANS) date.1 $(MANTXTS) \
$(MISC) $(SOURCES) $(WEB_PAGES) \
@ -806,12 +883,12 @@ check_character_set: $(ENCHILADA)
touch $@
check_white_space: $(ENCHILADA)
$(UTF8_LOCALE_MISSING) || { \
patfmt=' \t|[\f\r\v]' && pat=`printf "$$patfmt\\n"` && \
! grep -En "$$pat" \
$$(ls $(ENCHILADA) | grep -Fvx leap-seconds.list)
! grep -n '[$s]$$' \
$$(ls $(ENCHILADA) | grep -Fvx leap-seconds.list)
touch $@
! grep -En "$$pat|[$s]\$$" \
$$(ls $(ENCHILADA) | grep -Fvx leap-seconds.list); \
}
touch $@
PRECEDES_FILE_NAME = ^(Zone|Link[$s]+[^$s]+)[$s]+
FILE_NAME_COMPONENT_TOO_LONG = $(PRECEDES_FILE_NAME)[^$s]*[^/$s]{15}
@ -852,7 +929,29 @@ check_links: checklinks.awk tzdata.zi
-f checklinks.awk tzdata.zi
touch $@
check_tables: checktab.awk $(YDATA) backward $(ZONETABLES)
# 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`
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
now=$(CHECK_NOW_TIMESTAMP) && \
future=`expr $(CHECK_NOW_FUTURE_SECS) + $$now` && \
./zdump -i -t $$now,$$future \
$$(find $$PWD/$@.dir/????*/ -type f) \
>$@.dir/zdump.tab
$(AWK) \
-v zdump_table=$@.dir/zdump.tab \
-f checknow.awk zonenow.tab
rm -fr $@.dir
touch $@
check_tables: 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 \
@ -912,10 +1011,10 @@ check_zishrink_posix check_zishrink_right: \
touch $@
clean_misc:
rm -fr check_*.dir
rm -fr check_*.dir typecheck_*.dir
rm -f *.o *.out $(TIME_T_ALTERNATIVES) \
check_* core typecheck_* \
date tzselect version.h zdump zic libtz.a
date tzdir.h tzselect version.h zdump zic libtz.a
clean: clean_misc
rm -fr *.dir tzdb-*/
rm -f *.zi $(TZS_NEW)
@ -953,12 +1052,18 @@ $(MANTXTS): workman.sh
# plus N if GNU ls and touch are available.
SET_TIMESTAMP_N = sh -c '\
n=$$0 dest=$$1; shift; \
touch -cmr `ls -t "$$@" | sed 1q` "$$dest" && \
<"$$dest" && \
if test $$n != 0 && \
lsout=`ls -n --time-style="+%s" "$$dest" 2>/dev/null`; then \
lsout=`ls -nt --time-style="+%s" "$$@" 2>/dev/null`; then \
set x $$lsout && \
touch -cmd @`expr $$7 + $$n` "$$dest"; \
else :; fi'
timestamp=`expr $$7 + $$n` && \
echo "+ touch -md @$$timestamp $$dest" && \
touch -md @$$timestamp "$$dest"; \
else \
newest=`ls -t "$$@" | sed 1q` && \
echo "+ touch -mr $$newest $$dest" && \
touch -mr "$$newest" "$$dest"; \
fi'
# If DEST depends on A B C ... in this Makefile, callers should use
# $(SET_TIMESTAMP_DEP) DEST A B C ..., for the benefit of any
# downstream 'make' that considers equal timestamps to be out of date.
@ -983,8 +1088,12 @@ set-timestamps.out: $(EIGHT_YARDS)
rm -f test.out && \
for file in $$files; do \
if git diff --quiet $$file; then \
time=`git log -1 --format='tformat:%ct' $$file` && \
touch -cmd @$$time $$file; \
time=`TZ=UTC0 git log -1 \
--format='tformat:%cd' \
--date='format:%Y-%m-%dT%H:%M:%SZ' \
$$file` && \
echo "+ touch -md $$time $$file" && \
touch -md $$time $$file; \
else \
echo >&2 "$$file: warning: does not match repository"; \
fi || exit; \
@ -1009,7 +1118,8 @@ check_public: $(VERSION_DEPS)
rm -fr public.dir
mkdir public.dir
ln $(VERSION_DEPS) public.dir
cd public.dir && $(MAKE) CFLAGS='$(GCC_DEBUG_FLAGS)' ALL
cd public.dir \
&& $(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; \
@ -1140,7 +1250,7 @@ tzdata$(VERSION)-rearguard.tar.gz: rearguard.zi set-timestamps.out
sed '1s/$$/-rearguard/' <version >$@.dir/version
: The dummy pacificnew pacifies TZUpdater 2.3.1 and earlier.
$(CREATE_EMPTY) $@.dir/pacificnew
touch -cmr version $@.dir/version
touch -mr version $@.dir/version
LC_ALL=C && export LC_ALL && \
(cd $@.dir && \
tar $(TARFLAGS) -cf - \
@ -1164,7 +1274,7 @@ tzdata$(VERSION)-tailored.tar.gz: set-timestamps.out
`test $(DATAFORM) = vanguard || echo pacificnew`
(grep '^#' tzdata.zi && echo && cat $(DATAFORM).zi) \
>$@.dir/etcetera
touch -cmr tzdata.zi $@.dir/etcetera
touch -mr tzdata.zi $@.dir/etcetera
sed -n \
-e '/^# *version *\(.*\)/h' \
-e '/^# *ddeps */H' \
@ -1175,7 +1285,7 @@ tzdata$(VERSION)-tailored.tar.gz: set-timestamps.out
-e 's/ /-/g' \
-e 'p' \
<tzdata.zi >$@.dir/version
touch -cmr version $@.dir/version
touch -mr version $@.dir/version
links= && \
for file in $(TZDATA_DIST); do \
test -f $@.dir/$$file || links="$$links $$file"; \
@ -1227,15 +1337,16 @@ zonenames: tzdata.zi
asctime.o: private.h tzfile.h
date.o: private.h
difftime.o: private.h
localtime.o: private.h tzfile.h
localtime.o: private.h tzfile.h tzdir.h
strftime.o: private.h tzfile.h
zdump.o: version.h
zic.o: private.h tzfile.h version.h
zic.o: private.h tzfile.h tzdir.h version.h
.PHONY: ALL INSTALL all
.PHONY: check check_mild check_time_t_alternatives
.PHONY: check_web check_zishrink
.PHONY: clean clean_misc dummy.zd force_tzs
.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: posix_only posix_right public
.PHONY: rearguard_signatures rearguard_signatures_version

View File

@ -1,5 +1,177 @@
News for the tz database
Release 2024a - 2024-02-01 09:28:56 -0800
Briefly:
Kazakhstan unifies on UTC+5 beginning 2024-03-01.
Palestine springs forward a week later after Ramadan.
zic no longer pretends to support indefinite-past DST.
localtime no longer mishandles Ciudad Juárez in 2422.
Changes to future timestamps
Kazakhstan unifies on UTC+5. This affects Asia/Almaty and
Asia/Qostanay which together represent the eastern portion of the
country that will transition from UTC+6 on 2024-03-01 at 00:00 to
join the western portion. (Thanks to Zhanbolat Raimbekov.)
Palestine springs forward a week later than previously predicted
in 2024 and 2025. (Thanks to Heba Hamad.) Change spring-forward
predictions to the second Saturday after Ramadan, not the first;
this also affects other predictions starting in 2039.
Changes to past timestamps
Asia/Ho_Chi_Minh's 1955-07-01 transition occurred at 01:00
not 00:00. (Thanks to Đoàn Trần Công Danh.)
From 1947 through 1949, Toronto's transitions occurred at 02:00
not 00:00. (Thanks to Chris Walton.)
In 1911 Miquelon adopted standard time on June 15, not May 15.
Changes to code
The FROM and TO columns of Rule lines can no longer be "minimum"
or an abbreviation of "minimum", because TZif files do not support
DST rules that extend into the indefinite past - although these
rules were supported when TZif files had only 32-bit data, this
stopped working when 64-bit TZif files were introduced in 1995.
This should not be a problem for realistic data, since DST was
first used in the 20th century. As a transition aid, FROM columns
like "minimum" are now diagnosed and then treated as if they were
the year 1900; this should suffice for TZif files on old systems
with only 32-bit time_t, and it is more compatible with bugs in
2023c-and-earlier localtime.c. (Problem reported by Yoshito
Umaoka.)
localtime and related functions no longer mishandle some
timestamps that occur about 400 years after a switch to a time
zone with a DST schedule. In 2023d data this problem was visible
for some timestamps in November 2422, November 2822, etc. in
America/Ciudad_Juarez. (Problem reported by Gilmore Davidson.)
strftime %s now uses tm_gmtoff if available. (Problem and draft
patch reported by Dag-Erling Smørgrav.)
Changes to build procedure
The leap-seconds.list file is now copied from the IERS instead of
from its downstream counterpart at NIST, as the IERS version is
now in the public domain too and tends to be more up-to-date.
(Thanks to Martin Burnicki for liaisoning with the IERS.)
Changes to documentation
The strftime man page documents which struct tm members affect
which conversion specs, and that tzset is called. (Problems
reported by Robert Elz and Steve Summit.)
Release 2023d - 2023-12-21 20:02:24 -0800
Briefly:
Ittoqqortoormiit, Greenland changes time zones on 2024-03-31.
Vostok, Antarctica changed time zones on 2023-12-18.
Casey, Antarctica changed time zones five times since 2020.
Code and data fixes for Palestine timestamps starting in 2072.
A new data file zonenow.tab for timestamps starting now.
Changes to future timestamps
Ittoqqortoormiit, Greenland (America/Scoresbysund) joins most of
the rest of Greenland's timekeeping practice on 2024-03-31, by
changing its time zone from -01/+00 to -02/-01 at the same moment
as the spring-forward transition. Its clocks will therefore not
spring forward as previously scheduled. The time zone change
reverts to its common practice before 1981.
Fix predictions for DST transitions in Palestine in 2072-2075,
correcting a typo introduced in 2023a.
Changes to past and future timestamps
Vostok, Antarctica changed to +05 on 2023-12-18. It had been at
+07 (not +06) for years. (Thanks to Zakhary V. Akulov.)
Change data for Casey, Antarctica to agree with timeanddate.com,
by adding five time zone changes since 2020. Casey is now at +08
instead of +11.
Changes to past tm_isdst flags
Much of Greenland, represented by America/Nuuk, changed its
standard time from -03 to -02 on 2023-03-25, not on 2023-10-28.
This does not affect UTC offsets, only the tm_isdst flag.
(Thanks to Thomas M. Steenholdt.)
New data file
A new data file zonenow.tab helps configure applications that use
timestamps dated from now on. This simplifies configuration,
since users choose from a smaller Zone set. The file's format is
experimental and subject to change.
Changes to code
localtime.c no longer mishandles TZif files that contain a single
transition into a DST regime. Previously, it incorrectly assumed
DST was in effect before the transition too. (Thanks to Alois
Treindl for debugging help.)
localtime.c's timeoff no longer collides with OpenBSD 7.4.
The C code now uses _Generic only if __STDC_VERSION__ says the
compiler is C11 or later.
tzselect now optionally reads zonenow.tab, to simplify when
configuring only for timestamps dated from now on.
tzselect no longer creates temporary files.
tzselect no longer mishandles the following:
Spaces and most other special characters in BUGEMAIL, PACKAGE,
TZDIR, and VERSION.
TZ strings when using mawk 1.4.3, which mishandles regular
expressions of the form /X{2,}/.
ISO 6709 coordinates when using an awk that lacks the GNU
extension of newlines in -v option-arguments.
Non UTF-8 locales when using an iconv command that lacks the GNU
//TRANSLIT extension.
zic no longer mishandles data for Palestine after the year 2075.
Previously, it incorrectly omitted post-2075 transitions that are
predicted for just before and just after Ramadan. (Thanks to Ken
Murchison for debugging help.)
zic now works again on Linux 2.6.16 and 2.6.17 (2006).
(Problem reported by Rune Torgersen.)
Changes to build procedure
The Makefile is now more compatible with POSIX:
* It no longer defines AR, CC, CFLAGS, LDFLAGS, and SHELL.
* It no longer uses its own 'cc' in place of CC.
* It now uses ARFLAGS, with default specified by POSIX.
* It does not use LFLAGS incompatibly with POSIX.
* 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
built by 'make', not in a $(CC) -D option. Also, TZDEFAULT is
now treated like TZDIR as they have similar roles.
Changes to commentary
Limitations and hazards of the optional support for obsolescent
C89 platforms are documented better, along with a tentative
schedule for removing this support.
Release 2023c - 2023-03-28 12:42:14 -0700
Changes to past and future timestamps
@ -76,11 +248,14 @@ Release 2023a - 2023-03-22 12:39:33 -0700
platform dependent and abbreviations were silently truncated to
16 bytes even when the limit was greater than 16.
The code by default is now designed for C99 or later. To build in
a C89 environment, compile with -DPORT_TO_C89. To support C89
callers of the tzcode library, compile with -DSUPPORT_C89. The
two new macros are transitional aids planned to be removed in a
future version, when C99 or later will be required.
The code by default is now designed for C99 or later. To build on
a mostly-C89 platform, compile with -DPORT_TO_C89; this should
work on C89 platforms that also support C99 'long long' and
perhaps a few other extensions to C89. To support C89 callers of
tzcode's library, compile with -DSUPPORT_C89; however, this could
trigger latent bugs in C99-or-later callers. The two new macros
are transitional aids planned to be removed in a future version
(say, in 2029), when C99 or later will be required.
The code now builds again on pre-C99 platforms, if you compile
with -DPORT_TO_C89. This fixes a bug introduced in 2022f.
@ -723,6 +898,8 @@ Release 2021b - 2021-09-24 16:23:00 -0700
them, set the EXPIRES_LINE Makefile variable. If a TZif file uses
this new feature it is marked with a new TZif version number 4,
a format intended to be documented in a successor to RFC 8536.
The old-format "#expires" comments are now treated solely as
comments and have no effect on the TZif files.
zic -L LEAPFILE -r @LO no longer generates an invalid TZif file
that omits leap second information for the range LO..B when LO
@ -4302,7 +4479,7 @@ Release 2012j - 2012-11-12 18:34:49 -0800
now uses tz@iana.org rather than the old elsie address.
zic -v now complains about abbreviations that are less than 3
or more than 6 characters, as per Posix. Formerly, it checked
or more than 6 characters, as per POSIX. Formerly, it checked
for abbreviations that were more than 3.
'make public' no longer puts its temporary directory under /tmp,
@ -4467,8 +4644,8 @@ Release data2011m - 2011-10-24 21:42:16 +0700
In particular, the typos in comments in the data (2011-11-17 should have
been 2011-10-17 as Alan Barrett noted, and spelling of Tiraspol that
Tim Parenti noted) have been fixed, and the change for Ukraine has been
made in all 4 Ukrainian zones, rather than just Kiev (again, thanks to
Tim Parenti, and also Denys Gavrysh)
made in all 4 Ukrainian zones, rather than just Europe/Kiev
(again, thanks to Tim Parenti, and also Denys Gavrysh).
In addition, I added Europe/Tiraspol to zone.tab.

View File

@ -11,14 +11,17 @@ changes made by political bodies to time zone boundaries, UTC offsets,
and daylight-saving rules.
See <https://www.iana.org/time-zones/repository/tz-link.html> or the
file tz-link.html for how to acquire the code and data. Once acquired,
read the comments in the file 'Makefile' and make any changes needed
to make things right for your system, especially if you are using some
platform other than GNU/Linux. Then run the following commands,
substituting your desired installation directory for "$HOME/tzdir":
file tz-link.html for how to acquire the code and data.
make TOPDIR=$HOME/tzdir install
$HOME/tzdir/usr/bin/zdump -v America/Los_Angeles
Once acquired, read the leading comments in the file "Makefile"
and make any changes needed to make things right for your system,
especially when using a platform other than current GNU/Linux.
Then run the following commands, substituting your desired
installation directory for "$HOME/tzdir":
make TOPDIR="$HOME/tzdir" install
"$HOME/tzdir/usr/bin/zdump" -v America/Los_Angeles
See the file tz-how-to.html for examples of how to read the data files.

View File

@ -154,15 +154,11 @@ hexadecimal (leading 0x), preceded by an optional sign.
.br
/usr/lib/locale/\f2L\fP/LC_TIME description of time locale \f2L\fP
.br
/usr/share/zoneinfo timezone information directory
/usr/share/zoneinfo timezone directory
.br
/usr/share/zoneinfo/posixrules default DST rules (obsolete,
and can cause bugs if present)
/usr/share/zoneinfo/posixrules default DST rules (obsolete)
.br
/usr/share/zoneinfo/GMT for UTC leap seconds
.sp
If
.B /usr/share/zoneinfo/GMT
is absent,
UTC leap seconds are loaded from
.BR /usr/share/zoneinfo/posixrules .
.PP
If /usr/share/zoneinfo/GMT is absent,
UTC leap seconds are loaded from /usr/share/zoneinfo/GMT0 if present.

View File

@ -7,7 +7,7 @@
/*
** Leap second handling from Bradley White.
** POSIX-style TZ environment variable handling from Guy Harris.
** POSIX.1-1988 style TZ environment variable handling from Guy Harris.
*/
/*LINTLIBRARY*/
@ -27,6 +27,7 @@
#include "private.h"
#include "un-namespace.h"
#include "tzdir.h"
#include "tzfile.h"
#include "libc_private.h"
@ -124,12 +125,17 @@ 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-style TZ strings.
/* Limit to time zone abbreviation length in POSIX.1-2017-style TZ strings.
This is distinct from TZ_MAX_CHARS, which limits TZif file contents. */
#ifndef TZNAME_MAXIMUM
# define TZNAME_MAXIMUM 255
#endif
/* A representation of the contents of a TZif file. Ideally this
would have no size limits; the following sizes should suffice for
practical use. This struct should not be too large, as instances
are put on the stack and stacks are relatively small on some platforms.
See tzfile.h for more about the sizes. */
struct state {
int leapcnt;
int timecnt;
@ -172,8 +178,7 @@ static int_fast32_t leapcorr(struct state const *, time_t);
static bool normalize_overflow32(int_fast32_t *, int *, int);
static struct tm *timesub(time_t const *, int_fast32_t, struct state const *,
struct tm *);
static bool typesequiv(struct state const *, int, int);
static bool tzparse(char const *, struct state *, struct state *);
static bool tzparse(char const *, struct state *, struct state const *);
#ifdef ALL_STATE
static struct state * lclptr;
@ -438,7 +443,8 @@ union input_buffer {
/* The first part of the buffer, interpreted as a header. */
struct tzhead tzhead;
/* The entire buffer. */
/* The entire buffer. Ideally this would have no size limits;
the following should suffice for practical use. */
char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state)
+ 4 * TZ_MAX_TIMES];
};
@ -457,7 +463,12 @@ union local_storage {
struct state st;
} u;
/* The file name to be opened. */
/* The name of the file to be opened. Ideally this would have no
size limits, to support arbitrarily long Zone names.
Limiting Zone names to 1024 bytes should suffice for practical use.
However, there is no need for this to be smaller than struct
file_analysis as that struct is allocated anyway, as the other
union member. */
char fullname[max(sizeof(struct file_analysis), sizeof tzdirslash + 1024)];
};
@ -737,14 +748,18 @@ tzloadbody(char const *name, struct state *sp, bool doextend,
== sp->types[sp->timecnt - 2]))
sp->timecnt--;
for (i = 0;
i < ts->timecnt && sp->timecnt < TZ_MAX_TIMES;
i++) {
sp->goahead = ts->goahead;
for (i = 0; i < ts->timecnt; i++) {
time_t t = ts->ats[i];
if (increment_overflow_time(&t, leapcorr(sp, t))
|| (0 < sp->timecnt
&& t <= sp->ats[sp->timecnt - 1]))
continue;
if (TZ_MAX_TIMES <= sp->timecnt) {
sp->goahead = false;
break;
}
sp->ats[sp->timecnt] = t;
sp->types[sp->timecnt] = (sp->typecnt
+ ts->types[i]);
@ -757,28 +772,6 @@ tzloadbody(char const *name, struct state *sp, bool doextend,
}
if (sp->typecnt == 0)
return EINVAL;
if (sp->timecnt > 1) {
if (sp->ats[0] <= TIME_T_MAX - SECSPERREPEAT) {
time_t repeatat = sp->ats[0] + SECSPERREPEAT;
int repeattype = sp->types[0];
for (i = 1; i < sp->timecnt; ++i)
if (sp->ats[i] == repeatat
&& typesequiv(sp, sp->types[i], repeattype)) {
sp->goback = true;
break;
}
}
if (TIME_T_MIN + SECSPERREPEAT <= sp->ats[sp->timecnt - 1]) {
time_t repeatat = sp->ats[sp->timecnt - 1] - SECSPERREPEAT;
int repeattype = sp->types[sp->timecnt - 1];
for (i = sp->timecnt - 2; i >= 0; --i)
if (sp->ats[i] == repeatat
&& typesequiv(sp, sp->types[i], repeattype)) {
sp->goahead = true;
break;
}
}
}
/* Infer sp->defaulttype from the data. Although this default
type is always zero for data from recent tzdb releases,
@ -855,31 +848,6 @@ tzload(char const *name, struct state *sp, bool doextend)
#endif
}
static bool
typesequiv(const struct state *sp, int a, int b)
{
register bool result;
if (sp == NULL ||
a < 0 || a >= sp->typecnt ||
b < 0 || b >= sp->typecnt)
result = false;
else {
/* Compare the relevant members of *AP and *BP.
Ignore tt_ttisstd and tt_ttisut, as they are
irrelevant now and counting them could cause
sp->goahead to mistakenly remain false. */
register const struct ttinfo * ap = &sp->ttis[a];
register const struct ttinfo * bp = &sp->ttis[b];
result = (ap->tt_utoff == bp->tt_utoff
&& ap->tt_isdst == bp->tt_isdst
&& (strcmp(&sp->chars[ap->tt_desigidx],
&sp->chars[bp->tt_desigidx])
== 0));
}
return result;
}
static const int mon_lengths[2][MONSPERYEAR] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
@ -976,8 +944,8 @@ getsecs(register const char *strp, int_fast32_t *const secsp)
int_fast32_t secsperhour = SECSPERHOUR;
/*
** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
** "M10.4.6/26", which does not conform to Posix,
** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like
** "M10.4.6/26", which does not conform to POSIX,
** but which specifies the equivalent of
** "02:00 on the first Sunday on or after 23 Oct".
*/
@ -1030,7 +998,8 @@ getoffset(register const char *strp, int_fast32_t *const offsetp)
/*
** Given a pointer into a timezone string, extract a rule in the form
** date[/time]. See POSIX section 8 for the format of "date" and "time".
** date[/time]. See POSIX Base Definitions section 8.3 variable TZ
** for the format of "date" and "time".
** If a valid rule is not found, return NULL.
** Otherwise, return a pointer to the first character not part of the rule.
*/
@ -1174,12 +1143,12 @@ transtime(const int year, register const struct rule *const rulep,
}
/*
** Given a POSIX section 8-style TZ string, fill in the rule tables as
** Given a POSIX.1-2017-style TZ string, fill in the rule tables as
** appropriate.
*/
static bool
tzparse(const char *name, struct state *sp, struct state *basep)
tzparse(const char *name, struct state *sp, struct state const *basep)
{
const char * stdname;
const char * dstname;
@ -1222,6 +1191,7 @@ tzparse(const char *name, struct state *sp, struct state *basep)
}
if (0 < sp->leapcnt)
leaplo = sp->lsis[sp->leapcnt - 1].ls_trans;
sp->goback = sp->goahead = false;
if (*name != '\0') {
if (*name == '<') {
dstname = ++name;
@ -1269,7 +1239,6 @@ tzparse(const char *name, struct state *sp, struct state *basep)
*/
init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
sp->defaulttype = 0;
timecnt = 0;
janfirst = 0;
yearbeg = EPOCH_YEAR;
@ -1301,7 +1270,7 @@ tzparse(const char *name, struct state *sp, struct state *basep)
}
yearlim = yearbeg;
if (increment_overflow(&yearlim, YEARSPERREPEAT + 1))
if (increment_overflow(&yearlim, years_of_observations))
yearlim = INT_MAX;
for (year = yearbeg; year < yearlim; year++) {
int_fast32_t
@ -1338,7 +1307,7 @@ tzparse(const char *name, struct state *sp, struct state *basep)
if (endtime < leaplo) {
yearlim = year;
if (increment_overflow(&yearlim,
YEARSPERREPEAT + 1))
years_of_observations))
yearlim = INT_MAX;
}
if (increment_overflow_time
@ -1350,7 +1319,7 @@ tzparse(const char *name, struct state *sp, struct state *basep)
if (! timecnt) {
sp->ttis[0] = sp->ttis[1];
sp->typecnt = 1; /* Perpetual DST. */
} else if (YEARSPERREPEAT < year - yearbeg)
} else if (years_of_observations <= year - yearbeg)
sp->goback = sp->goahead = true;
} else {
register int_fast32_t theirstdoffset;
@ -1409,8 +1378,8 @@ tzparse(const char *name, struct state *sp, struct state *basep)
/*
** Transitions from DST to DDST
** will effectively disappear since
** POSIX provides for only one DST
** offset.
** POSIX.1-2017 provides for only one
** DST offset.
*/
if (isdst && !sp->ttis[j].tt_ttisstd) {
sp->ats[i] += dstoffset -
@ -1431,15 +1400,14 @@ tzparse(const char *name, struct state *sp, struct state *basep)
init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
sp->typecnt = 2;
sp->defaulttype = 0;
}
} else {
dstlen = 0;
sp->typecnt = 1; /* only standard time */
sp->timecnt = 0;
init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
sp->defaulttype = 0;
}
sp->defaulttype = 0;
sp->charcnt = charcnt;
cp = sp->chars;
memcpy(cp, stdname, stdlen);
@ -1630,7 +1598,8 @@ 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 POSIX-compatible,
** however, it's OK to omit this step
** if the timezone is compatible with POSIX.1-2017
** 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.
@ -1869,6 +1838,9 @@ gmtime(const time_t *timep)
#if STD_INSPIRED
/* This function is obsolescent and may disappear in future releases.
Callers can instead use localtime_rz with a fixed-offset zone. */
struct tm *
offtime_r(time_t const *restrict timep, long offset, struct tm *restrict tmp)
{
@ -2510,6 +2482,8 @@ mktime(struct tm *tmp)
}
#if STD_INSPIRED
/* This function is obsolescent and may disapper in future releases.
Callers can instead use mktime. */
time_t
timelocal(struct tm *tmp)
{
@ -2517,10 +2491,18 @@ timelocal(struct tm *tmp)
tmp->tm_isdst = -1; /* in case it wasn't initialized */
return mktime(tmp);
}
#else
static
#endif
time_t
#ifndef EXTERN_TIMEOFF
# ifndef timeoff
# define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 <time.h>. */
# endif
# define EXTERN_TIMEOFF static
#endif
/* This function is obsolescent and may disapper in future releases.
Callers can instead use mktime_z with a fixed-offset zone. */
EXTERN_TIMEOFF time_t
timeoff(struct tm *tmp, long offset)
{
if (tmp)

View File

@ -292,20 +292,16 @@ will
continue to exist in this form in future releases of this code.
.SH FILES
.ta \w'/usr/share/zoneinfo/posixrules\0\0'u
/usr/share/zoneinfo timezone information directory
/etc/localtime local timezone file
.br
/usr/share/zoneinfo/localtime local timezone file
/usr/share/zoneinfo timezone directory
.br
/usr/share/zoneinfo/posixrules default DST rules (obsolete,
and can cause bugs if present)
/usr/share/zoneinfo/posixrules default DST rules (obsolete)
.br
/usr/share/zoneinfo/GMT for UTC leap seconds
.sp
If
.B /usr/share/zoneinfo/GMT
is absent,
UTC leap seconds are loaded from
.BR /usr/share/zoneinfo/posixrules .
.PP
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),

View File

@ -64,7 +64,7 @@ strftime \- format date and time
The
.B strftime
function formats the information from
.I timeptr
.BI * timeptr
into the array pointed to by
.I buf
according to the string pointed to by
@ -85,47 +85,94 @@ bytes are placed into the array.
.PP
Each conversion specification is replaced by the characters as
follows which are then copied into the array.
The characters depend on the values of zero or more members of
.BI * timeptr
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;
if the name is followed by
.q \*- ,
.B strftime
ignores the member even though POSIX.1-2017 lists it
which means portable code should set it.
For portability,
.BI * timeptr
should be initialized as if by a successful call to
.BR gmtime ,
.BR localtime ,
.BR mktime ,
.BR timegm ,
or similar functions.
.TP
%A
is replaced by the locale's full weekday name.
.RI [ tm_wday ]
.TP
%a
is replaced by the locale's abbreviated weekday name.
.RI [ tm_wday ]
.TP
%B
is replaced by the locale's full month name.
.RI [ tm_mon ]
.TP
%b or %h
is replaced by the locale's abbreviated month name.
.RI [ tm_mon ]
.TP
%C
is replaced by the century (a year divided by 100 and truncated to an integer)
as a decimal number [00,99].
as a decimal number, with at least two digits by default.
.RI [ tm_year ]
.TP
%c
is replaced by the locale's appropriate date and time representation.
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_mon ,
.IR tm_mday ,
.IR tm_wday ,
.IR tm_hour ,
.IR tm_min ,
.IR tm_sec ,
.IR tm_gmtoff +,
.IR tm_zone +,
.IR tm_isdst \*-].
.TP
%D
is equivalent to
.c %m/%d/%y .
.RI [ tm_year ,
.IR tm_mon ,
.IR tm_mday ]
.TP
%d
is replaced by the day of the month as a decimal number [01,31].
.RI [ tm_mday ]
.TP
%e
is replaced by the day of month as a decimal number [1,31];
single digits are preceded by a blank.
.RI [ tm_mday ]
.TP
%F
is equivalent to
.c %Y-%m-%d
(the ISO 8601 date format).
.RI [ tm_year ,
.IR tm_mon ,
.IR tm_mday ]
.TP
%G
is replaced by the ISO 8601 year with century as a decimal number.
See also the
.c %V
conversion specification.
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_wday ]
.TP
%g
is replaced by the ISO 8601 year without century as a decimal number [00,99].
@ -134,29 +181,39 @@ This is the year that includes the greater part of the week.
See also the
.c %V
conversion specification.
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_wday ]
.TP
%H
is replaced by the hour (24-hour clock) as a decimal number [00,23].
.RI [ tm_hour ]
.TP
%I
is replaced by the hour (12-hour clock) as a decimal number [01,12].
.RI [ tm_hour ]
.TP
%j
is replaced by the day of the year as a decimal number [001,366].
.RI [ tm_yday ]
.TP
%k
is replaced by the hour (24-hour clock) as a decimal number [0,23];
single digits are preceded by a blank.
.RI [ tm_hour ]
.TP
%l
is replaced by the hour (12-hour clock) as a decimal number [1,12];
single digits are preceded by a blank.
.RI [ tm_hour ]
.TP
%M
is replaced by the minute as a decimal number [00,59].
.RI [ tm_min ]
.TP
%m
is replaced by the month as a decimal number [01,12].
.RI [ tm_mon ]
.TP
%n
is replaced by a newline.
@ -166,28 +223,58 @@ is replaced by the locale's equivalent of either
.q AM
or
.q PM .
.RI [ tm_hour ]
.TP
%R
is replaced by the time in the format
.c %H:%M .
.RI [ tm_hour ,
.IR tm_min ]
.TP
%r
is replaced by the locale's representation of 12-hour clock time
using AM/PM notation.
.RI [ tm_hour ,
.IR tm_min ,
.IR tm_sec ]
.TP
%S
is replaced by the second as a decimal number [00,60].
The range of
seconds is [00,60] instead of [00,59] to allow for the periodic occurrence
of leap seconds.
.RI [ tm_sec ]
.TP
%s
is replaced by the number of seconds since the Epoch (see
.BR ctime (3)).
Although %s is reliable in this implementation,
it can have glitches on other platforms (notably platforms lacking
.IR tm_gmtoff ),
so portable code should format a
.B time_t
value directly via something like
.B sprintf
instead of via
.B localtime
followed by
.B strftime
with "%s".
.RI [ tm_year ,
.IR tm_mon ,
.IR tm_mday ,
.IR tm_hour ,
.IR tm_min ,
.IR tm_sec ,
.IR tm_gmtoff +,
.IR tm_isdst \*-].
.TP
%T
is replaced by the time in the format
.c %H:%M:%S .
.RI [ tm_hour ,
.IR tm_min ,
.IR tm_sec ]
.TP
%t
is replaced by a tab.
@ -195,10 +282,14 @@ is replaced by a tab.
%U
is replaced by the week number of the year (Sunday as the first day of
the week) as a decimal number [00,53].
.RI [ tm_wday ,
.IR tm_yday ,
.IR tm_year \*-]
.TP
%u
is replaced by the weekday (Monday as the first day of the week)
as a decimal number [1,7].
.RI [ tm_wday ]
.TP
%V
is replaced by the week number of the year (Monday as the first day of
@ -208,30 +299,64 @@ it is week 53 of the previous year, and the next week is week 1.
The year is given by the
.c %G
conversion specification.
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_wday ]
.TP
%W
is replaced by the week number of the year (Monday as the first day of
the week) as a decimal number [00,53].
.RI [ tm_yday ,
.IR tm_wday ]
.TP
%w
is replaced by the weekday (Sunday as the first day of the week)
as a decimal number [0,6].
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_wday ]
.TP
%X
is replaced by the locale's appropriate time representation.
.RI [ tm_year \*-,
.IR tm_yday \*-,
.IR tm_mon \*-,
.IR tm_mday \*-,
.IR tm_wday \*-,
.IR tm_hour ,
.IR tm_min ,
.IR tm_sec ,
.IR tm_gmtoff +,
.IR tm_zone +,
.IR tm_isdst \*-].
.TP
%x
is replaced by the locale's appropriate date representation.
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_mon ,
.IR tm_mday ,
.IR tm_wday ,
.IR tm_hour \*-,
.IR tm_min \*-,
.IR tm_sec \*-,
.IR tm_gmtoff \*-,
.IR tm_zone \*-,
.IR tm_isdst \*-].
.TP
%Y
is replaced by the year with century as a decimal number.
.RI [ tm_year ]
.TP
%y
is replaced by the year without century as a decimal number [00,99].
.RI [ tm_year ]
.TP
%Z
is replaced by the time zone abbreviation,
or by the empty string if this is not determinable.
.RI [ tm_zone +,
.IR tm_isdst \*-]
.TP
%z
is replaced by the offset from the Prime Meridian
@ -244,6 +369,9 @@ 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 +,
.IR tm_zone +,
.IR tm_isdst \*-]
.TP
%%
is replaced by a single %.
@ -252,6 +380,26 @@ is replaced by a single %.
is replaced by the locale's date and time in
.BR date (1)
format.
.RI [ tm_year ,
.IR tm_yday ,
.IR tm_mon ,
.IR tm_mday ,
.IR tm_wday ,
.IR tm_hour ,
.IR tm_min ,
.IR tm_sec ,
.IR tm_gmtoff ,
.IR tm_zone ]
.PP
As a side effect,
.B strftime
also behaves as if
.B tzset
were called.
This is for compatibility with older platforms, as required by POSIX;
it is not needed for
.BR tzset 's
own use.
.SH "RETURN VALUE"
If the conversion is successful,
.B strftime

View File

@ -9,9 +9,9 @@ tzset \- initialize time conversion information
.el .ds - \-
.B #include <time.h>
.PP
.B timezone_t tzalloc(char const *TZ);
.BI "timezone_t tzalloc(char const *" TZ );
.PP
.B void tzfree(timezone_t tz);
.BI "void tzfree(timezone_t " tz );
.PP
.B void tzset(void);
.PP
@ -31,62 +31,30 @@ The
.B tzalloc
function
allocates and returns a timezone object described by
.BR TZ .
If
.B TZ
is not a valid timezone description, or if the object cannot be allocated,
.B tzalloc
returns a null pointer and sets
.BR errno .
.PP
The
.B tzfree
function
frees a timezone object
.BR tz ,
which should have been successfully allocated by
.BR tzalloc .
This invalidates any
.B tm_zone
pointers that
.B tz
was used to set.
.PP
The
.B tzset
function
acts like
.BR tzalloc(getenv("TZ")) ,
except it saves any resulting timezone object into internal
storage that is accessed by
.BR localtime ,
.BR localtime_r ,
and
.BR mktime .
The anonymous shared timezone object is freed by the next call to
.BR tzset .
If the implied call to
.B tzalloc
fails,
.B tzset
falls back on Universal Time (UT).
.IR TZ .
.PP
If
.B TZ
is null, the best available approximation to local (wall
.I TZ
is a null pointer,
.B tzalloc
uses the best available approximation to local (wall
clock) time, as specified by the
.BR tzfile (5)-format
file
.B localtime
in the system time conversion information directory, is used.
in the system time conversion information directory.
.PP
If
.B TZ
.I TZ
is the empty string,
UT is used, with the abbreviation "UTC"
.B tzalloc
uses Universal Time (UT), with the abbreviation "UTC"
and without leap second correction; please see
.BR newctime (3)
for more about UT, UTC, and leap seconds. If
.B TZ
for more about UT, UTC, and leap seconds.
.PP
If
.I TZ
is nonnull and nonempty:
.IP
if the value begins with a colon, it is used as a pathname of a file
@ -98,24 +66,25 @@ and, if that file cannot be read, is used directly as a specification of
the time conversion information.
.PP
When
.B TZ
is used as a pathname, if it begins with a slash,
it is used as an absolute pathname; otherwise,
it is used as a pathname relative to a system time conversion information
.I TZ
contents are used as a pathname, a pathname beginning with
.q "/"
is used as-is; otherwise
the pathname is relative to a system time conversion information
directory.
The file must be in the format specified in
.BR tzfile (5).
.PP
When
.B TZ
.I TZ
is used directly as a specification of the time conversion information,
it must have the following syntax (spaces inserted for clarity):
it must have the following syntax:
.IP
\fIstd\|offset\fR[\fIdst\fR[\fIoffset\fR][\fB,\fIrule\fR]]
.PP
Where:
.RS
.TP 15
.TP
.IR std " and " dst
Three or more bytes that are the designation for the standard
.RI ( std )
@ -196,7 +165,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, daylight saving is assumed to be in effect
As an extension to POSIX.1-2017, 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.
@ -205,7 +174,7 @@ The format of
.I date
is one of the following:
.RS
.TP 10
.TP
.BI J n
The Julian day
.I n
@ -238,16 +207,16 @@ first week in which the
.IR d' th
day occurs. Day zero is Sunday.
.RE
.IP "" 15
.IP
The
.I time
has the same format as
.I offset
except that POSIX does not allow a leading sign (\c
except that POSIX.1-2017 does not allow a leading sign (\c
.q "\*-"
or
.q "+" ).
As an extension to POSIX, the hours part of
As an extension to POSIX.1-2017, the hours part of
.I time
can range from \-167 through 167; this allows for unusual rules such
as
@ -259,9 +228,9 @@ is not given, is
.RE
.LP
Here are some examples of
.B TZ
.I TZ
values that directly specify the timezone; they use some of the
extensions to POSIX.
extensions to POSIX.1-2017.
.TP
.B EST5
stands for US Eastern Standard
@ -306,43 +275,114 @@ The abbreviations for standard and daylight saving time are
and
.q "\*-02".
.PP
If no
.I rule
is present in
.BR TZ ,
the rules specified
by the
If
.I TZ
specifies daylight saving time but does not specify a
.IR rule ,
and the optional
.BR tzfile (5)-format
file
.B posixrules
in the system time conversion information directory are used, with the
standard and daylight saving time offsets from UT replaced by those specified by
the
is present in the system time conversion information directory, the
rules in
.B posixrules
are used, with the
.B posixrules
standard and daylight saving time offsets from UT
replaced by those specified by the
.I offset
values in
.BR TZ .
.IR TZ .
However, the
.B posixrules
file is obsolete: if it is present it is only for backward compatibility,
and it does not work reliably.
Therefore, if a
.I TZ
string directly specifies a timezone with daylight saving time,
it should specify the daylight saving rules explicitly.
.PP
For compatibility with System V Release 3.1, a semicolon
.RB ( ; )
may be used to separate the
.I rule
from the rest of the specification.
from the rest of the specification;
this is an extension to POSIX.
.PP
The
.B tzfree
function
frees a timezone object
.IR tz ,
which should have been successfully allocated by
.BR tzalloc .
This invalidates any
.B tm_zone
pointers that
.I tz
was used to set.
.PP
The
.B tzset
function
acts like
.BR tzalloc(getenv("TZ")) ,
except it saves any resulting timezone object into internal
storage that is accessed by
.BR localtime ,
.BR localtime_r ,
and
.BR mktime .
The anonymous shared timezone object is freed by the next call to
.BR tzset .
If the implied call to
.B getenv
fails,
.B tzset
acts like
.BR tzalloc(nullptr) ;
if the implied call to
.B tzalloc
fails,
.B tzset
falls back on UT.
.SH "RETURN VALUE"
If successful, the
.B tzalloc
function returns a nonnull pointer to the newly allocated object.
Otherwise, it returns a null pointer and sets
.IR errno .
.SH ERRORS
.TP
.B EOVERFLOW
.I TZ
directly specifies time conversion information,
and contains an integer out of machine range
or a time zone abbreviation that is too long for this platform.
.PP
The
.B tzalloc
function may also fail and set
.I errno
for any of the errors specified for the routines
.BR access (2),
.BR close (2),
.BR malloc (3),
.BR open (2),
and
.BR read (2).
.SH FILES
.ta \w'/usr/share/zoneinfo/posixrules\0\0'u
/usr/share/zoneinfo timezone information directory
/etc/localtime local timezone file
.br
/usr/share/zoneinfo/localtime local timezone file
/usr/share/zoneinfo timezone directory
.br
/usr/share/zoneinfo/posixrules default DST rules (obsolete,
and can cause bugs if present)
/usr/share/zoneinfo/posixrules default DST rules (obsolete)
.br
/usr/share/zoneinfo/GMT for UTC leap seconds
.sp
If
.B /usr/share/zoneinfo/GMT
is absent,
UTC leap seconds are loaded from
.BR /usr/share/zoneinfo/posixrules .
.PP
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),

View File

@ -18,11 +18,15 @@
*/
/* PORT_TO_C89 means the code should work even if the underlying
compiler and library support only C89. SUPPORT_C89 means the
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. These macros are obsolescent,
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. */
they are nonzero. 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
@ -70,9 +74,7 @@
#endif
#if !defined HAVE__GENERIC && defined __has_extension
# if __has_extension(c_generic_selections)
# define HAVE__GENERIC 1
# else
# if !__has_extension(c_generic_selections)
# define HAVE__GENERIC 0
# endif
#endif
@ -759,7 +761,7 @@ struct tm *offtime_r(time_t const *, long, struct tm *);
time_t timelocal(struct tm *);
# endif
# if TZ_TIME_T || !defined timeoff
time_t timeoff(struct tm *, long);
# define EXTERN_TIMEOFF
# endif
# if TZ_TIME_T || !defined time2posix
time_t time2posix(time_t);
@ -771,7 +773,8 @@ time_t posix2time(time_t);
/* Infer TM_ZONE on systems where this information is known, but suppress
guessing if NO_TM_ZONE is defined. Similarly for TM_GMTOFF. */
#if (defined __GLIBC__ \
#if (200809 < _POSIX_VERSION \
|| defined __GLIBC__ \
|| defined __tm_zone /* musl */ \
|| defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
|| (defined __APPLE__ && defined __MACH__))
@ -901,6 +904,19 @@ static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED
# define UNINIT_TRAP 0
#endif
/* localtime.c sometimes needs access to timeoff if it is not already public.
tz_private_timeoff should be used only by localtime.c. */
#if (!defined EXTERN_TIMEOFF \
&& defined TM_GMTOFF && (200809 < _POSIX_VERSION || ! UNINIT_TRAP))
# ifndef timeoff
# define timeoff tz_private_timeoff
# endif
# define EXTERN_TIMEOFF
#endif
#ifdef EXTERN_TIMEOFF
time_t timeoff(struct tm *, long);
#endif
#ifdef DEBUG
# undef unreachable
# define unreachable() abort()
@ -960,6 +976,18 @@ enum {
#define SECSPERREPEAT ((int_fast64_t) DAYSPERREPEAT * SECSPERDAY)
#define AVGSECSPERYEAR (SECSPERREPEAT / YEARSPERREPEAT)
/* 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.
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,
less than 400 years after the last one-off transition in 2013-11.
Two years is not overkill for localtime.c, as a one-year bump
would mishandle 2023d's America/Ciudad_Juarez for November 2422. */
enum { years_of_observations = YEARSPERREPEAT + 2 };
enum {
TM_SUNDAY,
TM_MONDAY,

View File

@ -327,11 +327,12 @@ _fmt(const char *format, const struct tm *t, char *pt,
tm.tm_mday = t->tm_mday;
tm.tm_mon = t->tm_mon;
tm.tm_year = t->tm_year;
#ifdef TM_GMTOFF
mkt = timeoff(&tm, t->TM_GMTOFF);
#else
tm.tm_isdst = t->tm_isdst;
#if defined TM_GMTOFF && ! UNINIT_TRAP
tm.TM_GMTOFF = t->TM_GMTOFF;
#endif
mkt = mktime(&tm);
#endif
/* If mktime fails, %s expands to the
value of (time_t) -1 as a failure
marker; this is better in practice

View File

@ -95,7 +95,7 @@ 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.
standard and daylight saving times supported 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
@ -187,7 +187,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
href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03">POSIX.1-2017
<code>TZ</code> strings</a>.
A file name component must not exceed 14 characters or start with
'<code>-</code>'.
@ -362,6 +362,11 @@ The backward-compatibility file <code>zone.tab</code> is similar
but conforms to the older-version guidelines related to <abbr>ISO</abbr> 3166-1;
it lists only one country code per entry and unlike <code>zone1970.tab</code>
it can list names defined in <code>backward</code>.
Applications that process only timestamps from now on can instead use the file
<code>zonenow.tab</code>, which partitions the world more coarsely,
into regions where clocks agree now and in the predicted future;
this file is smaller and simpler than <code>zone1970.tab</code>
and <code>zone.tab</code>.
</p>
<p>
@ -373,7 +378,7 @@ 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-style <code>TZ</code> strings;
on platforms that do not support POSIX.1-2017-style <code>TZ</code> strings;
no other source file other than <code>backward</code>
contains links to its zones.
One of <code>etcetera</code>'s names is <code>Etc/UTC</code>,
@ -421,7 +426,7 @@ in decreasing order of importance:
expression <code>[-+[:alnum:]]{3,6}</code> should match the
abbreviation.
This guarantees that all abbreviations could have been specified by a
POSIX <code>TZ</code> string.
POSIX.1-2017 <code>TZ</code> string.
</p>
</li>
<li>
@ -765,12 +770,12 @@ href="https://www.dissentmagazine.org/blog/booked-a-global-history-of-time-vanes
calendar with 24-hour days. These divergences range from
relatively minor, such as Japanese bars giving times like "24:30" for the
wee hours of the morning, to more-significant differences such as <a
href="https://www.pri.org/stories/2015-01-30/if-you-have-meeting-ethiopia-you-better-double-check-time">the
href="https://theworld.org/stories/2015-01-30/if-you-have-meeting-ethiopia-you-better-double-check-time">the
east African practice of starting the day at dawn</a>, renumbering
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.
such as that required by POSIX.1-2017.
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
@ -867,23 +872,23 @@ input is occasionally extended, and a platform may still be shipping
an older <code>zic</code>.
</p>
<h3 id="POSIX">POSIX properties and limitations</h3>
<h3 id="POSIX">POSIX.1-2017 properties and limitations</h3>
<ul>
<li>
<p>
In POSIX, time display in a process is controlled by the
In POSIX.1-2017, time display in a process is controlled by the
environment variable <code>TZ</code>.
Unfortunately, the POSIX
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 <code>TZ</code> strings cannot deal with daylight
Also, POSIX.1-2017 <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 <code>TZ</code> string takes the following form:
The POSIX.1-2017 <code>TZ</code> string takes the following form:
</p>
<p>
@ -950,7 +955,7 @@ an older <code>zic</code>.
</dl>
<p>
Here is an example POSIX <code>TZ</code> string for New
Here is an example POSIX.1-2017 <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
@ -961,7 +966,7 @@ an older <code>zic</code>.
<pre><code>TZ='NZST-12NZDT,M9.5.0,M4.1.0/3'</code></pre>
<p>
This POSIX <code>TZ</code> string is hard to remember, and
This POSIX.1-2017 <code>TZ</code> string is hard to remember, and
mishandles some timestamps before 2008.
With this package you can use this instead:
</p>
@ -999,7 +1004,7 @@ an older <code>zic</code>.
limit phone calls to off-peak hours.
</li>
<li>
POSIX provides no convenient and efficient way to determine
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.
@ -1026,14 +1031,14 @@ an older <code>zic</code>.
</li>
</ul>
<h3 id="POSIX-extensions">Extensions to POSIX in the
<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); <code>TZ</code> is no longer
(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>.
The file's format is <dfn><abbr>TZif</abbr></dfn>,

View File

@ -22,9 +22,10 @@ into problems that programmers have with timekeeping.</li>
Explaining The Mysteries Of Time Zones</a>" (2017; 2:15)
briefly says why France has more time zones than Russia.
<li>
"<a href="https://www.youtube.com/watch?v=yRz-Dl60Lfc">Why Denmark is
.17 Seconds Behind The World</a>" (2019; 6:29) explains why Denmark and
the United Kingdom don't exactly follow their own law about civil time.
"<a href="https://www.youtube.com/watch?v=yRz-Dl60Lfc">Why Denmark used to be
.04 seconds behind the world</a>" (2019; 6:29) explains why the United Kingdom
&mdash; and, once, Denmark &mdash; haven't always exactly followed their own
laws about civil time.
<li>
"About Time" (1962; 59 minutes) is part of the
Bell Science extravaganza, with Frank Baxter, Richard Deacon, and Les Tremayne.
@ -209,7 +210,7 @@ Umberto Eco,
Island of the Day Before</em></a>
(<em>L'isola del giorno prima</em>), 1994.
"...the story of a 17th century Italian nobleman trapped near an island
on the International Date Line. Time and time zones play an integral
on the International Date Line. Time and time zones play an integral
part in the novel." (Paul Eggert, 2006-04-22)
</li>
<li>
@ -229,94 +230,73 @@ year-round <abbr>DST</abbr> as a way of lessening wintertime despair.
</li>
</ul>
<h2>Music</h2>
<p>
Data on recordings of "Save That Time," Russ Long, Serrob Publishing, BMI:</p>
<table>
<tr><td>Artist</td><td>Karrin Allyson</td></tr>
<tr><td>CD</td><td>I Didn't Know About You</td></tr>
<tr><td>Copyright Date</td><td>1993</td></tr>
<tr><td>Label</td><td>Concord Jazz, Inc.</td></tr>
<tr><td>ID</td><td>CCD-4543</td></tr>
<tr><td>Track Time</td><td>3:44</td></tr>
<tr><td>Personnel</td><td>Karrin Allyson, vocal;
<ul>
<li>
Recordings of "Save That Time," Russ Long, Serrob Publishing, BMI:
<ul>
<li>
Karrin Allyson, <em>I Didn't Know About You</em> (1993), track 11, 3:44.
Concord Jazz CCD-4543.
Karrin Allyson, vocal;
Russ Long, piano;
Gerald Spaits, bass;
Todd Strait, drums</td></tr>
<tr><td>Notes</td><td>CD notes "additional lyric by Karrin Allyson;
arranged by Russ Long and Karrin Allyson"</td></tr>
<tr><td>ADO Rating</td><td>1 star</td></tr>
<tr><td><a href="https://www.allmusic.com/album/i-didnt-know-about-you-mw0000618657">AMG Rating</a></td><td>4 stars</td></tr>
<tr><td>Penguin Rating</td><td>3.5 stars</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Kevin Mahogany</td></tr>
<tr><td>CD</td><td>Double Rainbow</td></tr>
<tr><td>Copyright Date</td><td>1993</td></tr>
<tr><td>Label</td><td>Enja Records</td></tr>
<tr><td>ID</td><td>ENJ-7097 2</td></tr>
<tr><td>Track Time</td><td>6:27</td></tr>
<tr><td>Personnel</td><td>Kevin Mahogany, vocal;
Todd Strait, drums.
CD notes "additional lyric by Karrin Allyson;
arranged by Russ Long and Karrin Allyson".
ADO &#x2605;,
<a href="https://www.allmusic.com/album/i-didnt-know-about-you-mw0000618657">AMG</a>
&#x2605;&#x2605;&#x2605;&#x2605;, Penguin &#x2605;&#x2605;&#x2605;&#x2BEA;.
</li>
<li>
Kevin Mahogany, <em>Double Rainbow</em> (1993), track 3, 6:27. Enja ENJ-7097 2.
Kevin Mahogany, vocal;
Kenny Barron, piano;
Ray Drummond, bass;
Ralph Moore, tenor saxophone;
Lewis Nash, drums</td></tr>
<tr><td>ADO Rating</td><td>1.5 stars</td></tr>
<tr><td><a href="https://www.allmusic.com/album/double-rainbow-mw0000620371">AMG Rating</a></td><td>3 stars</td></tr>
<tr><td>Penguin Rating</td><td>3 stars</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Joe Williams</td></tr>
<tr><td>CD</td><td>Here's to Life</td></tr>
<tr><td>Copyright Date</td><td>1994</td></tr>
<tr><td>Label</td><td>Telarc International Corporation</td></tr>
<tr><td>ID</td><td>CD-83357</td></tr>
<tr><td>Track Time</td><td>3:58</td></tr>
<tr><td>Personnel</td><td>Joe Williams, vocal
The Robert Farnon [39 piece] Orchestra</td></tr>
<tr><td>Notes</td><td>This CD is also available as part of a 3-CD package from
Telarc, "Triple Play" (CD-83461)</td></tr>
<tr><td>ADO Rating</td><td>black dot</td></tr>
<tr><td><a href="https://www.allmusic.com/album/heres-to-life-mw0000623648">AMG Rating</a></td><td>2 stars</td></tr>
<tr><td>Penguin Rating</td><td>3 stars</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Charles Fambrough</td></tr>
<tr><td>CD</td><td>Keeper of the Spirit</td></tr>
<tr><td>Copyright Date</td><td>1995</td></tr>
<tr><td>Label</td><td>AudioQuest Music</td></tr>
<tr><td>ID</td><td>AQ-CD1033</td></tr>
<tr><td>Track Time</td><td>7:07</td></tr>
<tr><td>Personnel</td><td>Charles Fambrough, bass;
Lewis Nash, drums.
ADO &#x2605;&#x2BEA;,
<a href="https://www.allmusic.com/album/double-rainbow-mw0000620371">AMG</a>
&#x2605;&#x2605;&#x2605;, Penguin &#x2605;&#x2605;&#x2605;.
</li>
<li>
Joe Williams, <em>Here's to Life</em> (1994), track 7, 3:58.
Telarc Jazz CD-83357.
Joe Williams, vocal; The Robert Farnon [39 piece] Orchestra.
Also in a 3-CD package "Triple Play", Telarc CD-83461.
ADO &#x2022;,
<a href="https://www.allmusic.com/album/heres-to-life-mw0000623648">AMG</a>
&#x2605;&#x2605;, Penguin &#x2605;&#x2605;&#x2605;.
</li>
<li>
Charles Fambrough, <em>Keeper of the Spirit</em> (1995), track 7, 7:07.
AudioQuest AQ-CD1033.
Charles Fambrough, bass;
Joel Levine, tenor recorder;
Edward Simon, piano;
Lenny White, drums;
Marion Simon, percussion</td></tr>
<tr><td>ADO Rating</td><td>2 stars</td></tr>
<tr><td><a href="https://www.allmusic.com/album/keeper-of-the-spirit-mw0000176559">AMG Rating</a></td><td>unrated</td></tr>
<tr><td>Penguin Rating</td><td>3 stars</td></tr>
</table>
<hr>
<p>Also of note:</p>
<table>
<tr><td>Artist</td><td>Holly Cole Trio</td></tr>
<tr><td>CD</td><td>Blame It On My Youth</td></tr>
<tr><td>Copyright Date</td><td>1992</td></tr>
<tr><td>Label</td><td>Manhattan</td></tr>
<tr><td>ID</td><td>CDP 7 97349 2</td></tr>
<tr><td>Total Time</td><td>37:45</td></tr>
<tr><td>Personnel</td><td>Holly Cole, voice;
Marion Simon, percussion.
ADO &#x2605;,
<a href="https://www.allmusic.com/album/keeper-of-the-spirit-mw0000176559">AMG</a>
unrated, Penguin &#x2605;&#x2605;&#x2605;.
</ul>
</li>
<li>
Holly Cole Trio, Blame It On My Youth (1992). Manhattan CDP 7 97349 2, 37:45.
Holly Cole, voice;
Aaron Davis, piano;
David Piltch, string bass</td></tr>
<tr><td>Notes</td><td>Lyrical reference to "Eastern Standard Time" in
Tom Waits' "Purple Avenue"</td></tr>
<tr><td>ADO Rating</td><td>2.5 stars</td></tr>
<tr><td><a href="https://www.allmusic.com/album/blame-it-on-my-youth-mw0000274303">AMG Rating</a></td><td>3 stars</td></tr>
<tr><td>Penguin Rating</td><td>unrated</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Milt Hinton</td></tr>
<tr><td>CD</td><td>Old Man Time</td></tr>
<tr><td>Copyright Date</td><td>1990</td></tr>
<tr><td>Label</td><td>Chiaroscuro</td></tr>
<tr><td>ID</td><td>CR(D) 310</td></tr>
<tr><td>Total Time</td><td>149:38 (two CDs)</td></tr>
<tr><td>Personnel</td><td>Milt Hinton, bass;
David Piltch, string bass.
Lyrical reference to "Eastern Standard Time" in
Tom Waits's "Purple Avenue".
ADO &#x2605;&#x2605;&#x2BEA;,
<a href="https://www.allmusic.com/album/blame-it-on-my-youth-mw0000274303">AMG</a>
&#x2605;&#x2605;&#x2605;, Penguin unrated.
</li>
<li>
Milt Hinton,
<a href="https://chiaroscurojazz.org/catalog/old-man-time-2-cd-set/"><em>Old
Man Time</em></a> (1990).
Chiaroscuro CR(D) 310, 149:38 (two CDs).
Milt Hinton, bass;
Doc Cheatham, Dizzy Gillespie, Clark Terry, trumpet;
Al Grey, trombone;
Eddie Barefield, Joe Camel (Flip Phillips), Buddy Tate,
@ -328,165 +308,129 @@ Gus Johnson, Gerryck King, Bob Rosengarden, Jackie Williams,
drums;
Lionel Hampton, vibraphone;
Cab Calloway, Joe Williams, vocal;
Buck Clayton, arrangements</td></tr>
<tr><td>Notes</td><td>tunes include Old Man Time, Time After Time,
Sometimes I'm Happy,
A Hot Time in the Old Town Tonight,
Four or Five Times, Now's the Time,
Time on My Hands, This Time It's Us,
and Good Time Charlie.
<a href="http://www.chiaroscurojazz.com/album.php?C=310">Album info</a>
is available.</td></tr>
<tr><td>ADO Rating</td><td>3 stars</td></tr>
<tr><td><a href="https://www.allmusic.com/album/old-man-time-mw0000269353">AMG Rating</a></td><td>4.5 stars</td></tr>
<tr><td>Penguin Rating</td><td>3 stars</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Alan Broadbent</td></tr>
<tr><td>CD</td><td>Pacific Standard Time</td></tr>
<tr><td>Copyright Date</td><td>1995</td></tr>
<tr><td>Label</td><td>Concord Jazz, Inc.</td></tr>
<tr><td>ID</td><td>CCD-4664</td></tr>
<tr><td>Total Time</td><td>62:42</td></tr>
<tr><td>Personnel</td><td>Alan Broadbent, piano;
Buck Clayton, arrangements.
Tunes include "Old Man Time", "Time After Time",
"Sometimes I'm Happy",
"A Hot Time in the Old Town Tonight",
"Four or Five Times", "Now's the Time",
"Time on My Hands", "This Time It's Us",
and "Good Time Charlie".
ADO &#x2605;&#x2605;&#x2605;,
<a href="https://www.allmusic.com/album/old-man-time-mw0000269353">AMG</a>
&#x2605;&#x2605;&#x2605;&#x2605;&#x2BEA;, Penguin &#x2605;&#x2605;&#x2605;.
</li>
<li>
Alan Broadbent, <em>Pacific Standard Time</em> (1995).
Concord Jazz CCD-4664, 62:42.
Alan Broadbent, piano;
Putter Smith, Bass;
Frank Gibson, Jr., drums</td></tr>
<tr><td>Notes</td><td>The CD cover features an analemma for equation-of-time fans</td></tr>
<tr><td>ADO Rating</td><td>1 star</td></tr>
<tr><td><a href="https://www.allmusic.com/album/pacific-standard-time-mw0000645433">AMG Rating</a></td><td>4 stars</td></tr>
<tr><td>Penguin Rating</td><td>3.5 stars</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Anthony Braxton/Richard Teitelbaum</td></tr>
<tr><td>CD</td><td>Silence/Time Zones</td></tr>
<tr><td>Copyright Date</td><td>1996</td></tr>
<tr><td>Label</td><td>Black Lion</td></tr>
<tr><td>ID</td><td>BLCD 760221</td></tr>
<tr><td>Total Time</td><td>72:58</td></tr>
<tr><td>Personnel</td><td>Anthony Braxton, sopranino and alto saxophones,
Frank Gibson, Jr., drums.
The CD cover features an analemma for equation-of-time fans.
ADO &#x2605;,
<a href="https://www.allmusic.com/album/pacific-standard-time-mw0000645433">AMG</a>
&#x2605;&#x2605;&#x2605;&#x2605;, Penguin &#x2605;&#x2605;&#x2605;&#x2BEA;.
</li>
<li>
Anthony Braxton/Richard Teitelbaum, <em>Silence/Time Zones</em> (1996).
Black Lion BLCD 760221, 72:58.
Anthony Braxton, sopranino and alto saxophones,
contrebasse clarinet, miscellaneous instruments;
Leo Smith, trumpet and miscellaneous instruments;
Leroy Jenkins, violin and miscellaneous instruments;
Richard Teitelbaum, modular moog and micromoog synthesizer</td></tr>
<tr><td>ADO Rating</td><td>black dot</td></tr>
<tr><td><a href="https://www.allmusic.com/album/silence-time-zones-mw0000595735">AMG Rating</a></td><td>4 stars</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Charles Gayle</td></tr>
<tr><td>CD</td><td>Time Zones</td></tr>
<tr><td>Copyright Date</td><td>2006</td></tr>
<tr><td>Label</td><td>Tompkins Square</td></tr>
<tr><td>ID</td><td>TSQ2839</td></tr>
<tr><td>Total Time</td><td>49:06</td></tr>
<tr><td>Personnel</td><td>Charles Gayle, piano</td></tr>
<tr><td>ADO Rating</td><td>1 star</td></tr>
<tr><td><a href="https://www.allmusic.com/album/time-zones-mw0000349642">AMG Rating</a></td><td>4.5 stars</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>The Get Up Kids</td></tr>
<tr><td>CD</td><td>Eudora</td></tr>
<tr><td>Copyright Date</td><td>2001</td></tr>
<tr><td>Label</td><td>Vagrant</td></tr>
<tr><td>ID</td><td>357</td></tr>
<tr><td>Total Time</td><td>65:12</td></tr>
<tr><td>Notes</td><td>Includes the song "Central Standard Time." Thanks to Colin Bowern for this information.</td></tr>
<tr><td><a href="https://www.allmusic.com/album/eudora-mw0000592063">AMG Rating</a></td><td>2.5 stars</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Coldplay</td></tr>
<tr><td>Song</td><td>Clocks</td></tr>
<tr><td>Copyright Date</td><td>2003</td></tr>
<tr><td>Label</td><td>Capitol Records</td></tr>
<tr><td>ID</td><td>52608</td></tr>
<tr><td>Total Time</td><td>4:13</td></tr>
<tr><td>Notes</td><td>Won the 2004 Record of the Year honor at the
Richard Teitelbaum, modular moog and micromoog synthesizer.
ADO &#x2022;,
<a href="https://www.allmusic.com/album/silence-time-zones-mw0000595735">AMG</a>
&#x2605;&#x2605;&#x2605;&#x2605;.
</li>
<li>
Charles Gayle, <em>Time Zones</em> (2006). Tompkins Square TSQ2839, 49:06.
Charles Gayle, piano.
ADO &#x2605;,
<a href="https://www.allmusic.com/album/time-zones-mw0000349642">AMG</a>
&#x2605;&#x2605;&#x2605;&#x2605;&#x2BEA;.
</li>
<li>
The Get Up Kids, <em>Eudora</em> (2001). Vagrant 357, 65:12.
Includes the song "Central Standard Time."
Thanks to Colin Bowern for this information.
<a href="https://www.allmusic.com/album/eudora-mw0000592063">AMG</a>
&#x2605;&#x2605;&#x2BEA;.
</li>
<li>
Coldplay, "Clocks" (2003).
Capitol 52608, 4:13.
Won the 2004 Record of the Year honor at the
Grammy Awards. Co-written and performed by Chris Martin,
great-great-grandson of <abbr>DST</abbr> inventor William Willett.
The song's first line is "Lights go out and I can't be saved".</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Jaime Guevara</td></tr>
<tr><td>Song</td><td><a
The song's first line is "Lights go out and I can't be saved".
</li>
<li>
Jaime Guevara, "<a
href="https://www.youtube.com/watch?v=ZfN4Fe_A50U">Qu&eacute;
hora es</a></td></tr>
<tr><td>Date</td><td>1993</td></tr>
<tr><td>Total Time</td><td>3:04</td></tr>
<tr><td>Notes</td><td>The song protested "Sixto Hour" in Ecuador
hora es</a>" (1993), 3:04.
The song protested "Sixto Hour" in Ecuador
(1992&ndash;3). Its lyrics include "Amanec&iacute;a en mitad de la noche, los
guaguas iban a clase sin sol" ("It was dawning in the middle of the
night, the buses went to class without sun").
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Irving Kahal and Harry Richman</td></tr>
<tr><td>Song</td><td>There Ought to be a Moonlight Saving Time</td></tr>
<tr><td>Copyright Date</td><td>1931</td>
<tr><td>Notes</td><td>This musical standard was a No. 1 hit for Guy Lombardo
</li>
<li>
Irving Kahal and Harry Richman,
"There Ought to be a Moonlight Saving Time" (1931).
This musical standard was a No. 1 hit for Guy Lombardo
in 1931, and was also performed by Maurice Chevalier, Blossom Dearie
and many others. The phrase "Moonlight saving time" also appears in
the 1995 country song "Not Enough Hours in the Night" written by Aaron
Barker, Kim Williams and Rob Harbin and performed by Doug
Supernaw.</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>The Microscopic Septet</td></tr>
<tr><td>CD</td><td>Lobster Leaps In</td></tr>
<tr><td>Copyright Date</td><td>2008</td></tr>
<tr><td>Label</td><td>Cuneiform</td></tr>
<tr><td>ID</td><td>272</td></tr>
<tr><td>Total Time</td><td>73:05</td></tr>
<tr><td>Notes</td><td>Includes the song "Twilight Time Zone."</td></tr>
<tr><td><a href="https://www.allmusic.com/album/lobster-leaps-in-mw0000794929">AMG Rating</a></td><td>3.5 stars</td></tr>
<tr><td>ADO Rating</td><td>2 stars</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Bob Dylan</td></tr>
<tr><td>CD</td><td>The Times They Are a-Changin'</td></tr>
<tr><td>Copyright Date</td><td>1964</td></tr>
<tr><td>Label</td><td>Columbia</td></tr>
<tr><td>ID</td><td>CK-8905</td></tr>
<tr><td>Total Time</td><td>45:36</td></tr>
<tr><td><a href="https://www.allmusic.com/album/the-times-they-a-changin-mw0000202344">AMG Rating</a></td><td>4.5 stars</td></tr>
<tr><td>ADO Rating</td><td>1.5 stars</td></tr>
<tr><td>Notes<td>The title song is also available on "Bob Dylan's Greatest Hits" and "The Essential Bob Dylan."</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Luciana Souza</td></tr>
<tr><td>CD</td><td>Tide</td></tr>
<tr><td>Copyright Date</td><td>2009</td></tr>
<tr><td>Label</td><td>Universal Jazz France</td></tr>
<tr><td>ID</td><td>B0012688-02</td></tr>
<tr><td>Total Time</td><td>42:31</td></tr>
<tr><td><a href="https://www.allmusic.com/album/tide-mw0000815692">AMG Rating</a></td><td>3.5 stars</td></tr>
<tr><td>ADO Rating</td><td>2.5 stars</td></tr>
<tr><td>Notes<td>Includes the song "Fire and Wood" with the lyric
Supernaw.
</li>
<li>
The Microscopic Septet, <em>Lobster Leaps In</em> (2008).
Cuneiform 272, 73:05.
Includes the song "Twilight Time Zone."
ADO &#x2605;&#x2605;,
<a href="https://www.allmusic.com/album/lobster-leaps-in-mw0000794929">AMG</a>
&#x2605;&#x2605;&#x2605;&#x2BEA;.
</li>
<li>
Bob Dylan, <em>The Times They Are a-Changin'</em> (1964).
Columbia CK-8905, 45:36.
ADO &#x2605;&#x2BEA;,
<a href="https://www.allmusic.com/album/the-times-they-a-changin-mw0000202344">AMG</a>
&#x2605;&#x2605;&#x2605;&#x2605;&#x2BEA;.
The title song is also available on "Bob Dylan's Greatest Hits" and "The Essential Bob Dylan."
</li>
<li>
Luciana Souza, <em>Tide</em> (2009). Universal Jazz France B0012688-02, 42:31.
ADO &#x2605;&#x2605;&#x2BEA;,
<a href="https://www.allmusic.com/album/tide-mw0000815692">AMG</a>
&#x2605;&#x2605;&#x2605;&#x2BEA;.
Includes the song "Fire and Wood" with the lyric
"The clocks were turned back you remember/Think it's still November."
</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Ken Nordine</td></tr>
<tr><td>CD</td><td>You're Getting Better: The Word Jazz Dot Masters</td></tr>
<tr><td>Copyright Date</td><td>2005</td></tr>
<tr><td>Label</td><td>Geffen</td></tr>
<tr><td>ID</td><td>B0005171-02</td></tr>
<tr><td>Total Time</td><td>156:22</td></tr>
<tr><td>ADO Rating</td><td>1 star</td></tr>
<tr><td><a href="https://www.allmusic.com/album/youre-getting-better-the-word-jazz-dot-masters-mw0000736197">AMG Rating</a></td><td>4.5 stars</td></tr>
<tr><td>Notes</td><td>Includes the piece "What Time Is It"
("He knew what time it was everywhere...that counted").</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Chicago</td></tr>
<tr><td>CD</td><td>Chicago Transit Authority</td></tr>
<tr><td>Copyright Date</td><td>1969</td></tr>
<tr><td>Label</td><td>Columbia</td></tr>
<tr><td>ID</td><td>64409</td></tr>
<tr><td>Total Time</td><td>1:16:20</td></tr>
<tr><td><a href="https://www.allmusic.com/album/chicago-transit-authority-mw0000189364">AMG Rating</a></td><td>4 stars</td></tr>
<tr><td>Notes</td><td>Includes the song "Does Anybody Really Know What Time It Is?"</td></tr>
<tr><td>&nbsp;</td><td></td></tr>
<tr><td>Artist</td><td>Emanuele Arciuli</td></tr>
<tr><td>Composer</td><td>William Duckworth</td></tr>
<tr><td>CD</td><td><a href="https://neumarecords.org/ols/products/william-duckworth-the-time-curve-preludes">The Time Curve Preludes</a></td></tr>
<tr><td>Copyright Date</td><td>2023</td></tr>
<tr><td>Label</td><td>Neuma</td></tr>
<tr><td>Total Time</td><td>44:46</td></tr>
<tr><td>Notes</td><td>The first work of postminimal music. Unlike minimalism, it does not assume that the listener has plenty of time.</td></tr>
</table>
</li>
<li>
Ken Nordine, <em>You're Getting Better: The Word Jazz Dot Masters</em> (2005).
Geffen B0005171-02, 156:22.
ADO &#x2605;,
<a href="https://www.allmusic.com/album/youre-getting-better-the-word-jazz-dot-masters-mw0000736197">AMG</a>
&#x2605;&#x2605;&#x2605;&#x2605;&#x2BEA;.
Includes the piece "What Time Is It"
("He knew what time it was everywhere...that counted").
</li>
<li>
Chicago, <em>Chicago Transit Authority</em> (1969). Columbia 64409, 1:16:20.
<a href="https://www.allmusic.com/album/chicago-transit-authority-mw0000189364">AMG</a> &#x2605;&#x2605;&#x2605;&#x2605;.
Includes the song "Does Anybody Really Know What Time It Is?".
</li>
<li>
Emanuele Arciuli,
<a href="https://neumarecords.org/ols/products/william-duckworth-the-time-curve-preludes"><em>The Time Curve Preludes</em></a> (2023).
Neuma 174, 44:46.
The title piece, composed by
<a href="https://en.wikipedia.org/wiki/William_Duckworth_(composer)">William
Duckworth</a>, is the first work of postminimal music.
Unlike minimalism, it does not assume that the listener has plenty of time.
</li>
</ul>
<h2>Comics</h2>
<ul>
<li>
@ -506,7 +450,10 @@ along with the panels
"<a href="https://xkcd.com/2050/">6/6 Time</a>" (2018-09-24),
"<a href="https://xkcd.com/2092/">Consensus New Year</a>" (2018-12-31),
"<a href="https://xkcd.com/2266/">Leap Smearing</a>" (2020-02-10),
and "<a href="https://xkcd.com/2594/">Consensus Time</a>" (2022-03-16).
"<a href="https://xkcd.com/2594/">Consensus Time</a>" (2022-03-16),
"<a href="https://xkcd.com/2846/">Daylight Saving Choice</a>" (2023-10-25),
"<a href="https://xkcd.com/2854/">Date Line</a>" (2023-11-13),
and "<a href="https://xkcd.com/2867/">DateTime</a>" (2023-12-13).
The related book <em>What If?</em> has an entry
"<a href="https://what-if.xkcd.com/26/">Leap Seconds</a>" (2012-12-31).
</li>
@ -519,9 +466,13 @@ Before Swine</em> (2016-11-06)</a>.
Stonehenge is abandoned in <a
href="https://www.gocomics.com/nonsequitur/2017/03/12"><em>Non Sequitur</em>
(2017-03-12)</a>.
</li>
<li>
The boss freaks out in <a
href="https://dilbert.com/strip/1998-03-14"><em>Dilbert</em> (1998-03-14)</a>.
Caulfield proposes changing clocks just once a year in
<a href="https://www.gocomics.com/frazz/2023/12/31"><em>Frazz</em>
(2023-12-31)</a>, while Peter and Jason go multi-lingual and -zonal in
<a href="https://www.gocomics.com/foxtrot/2023/12/31"><em>FoxTrot</em>
(the same day)</a>.
</li>
<li>
Peppermint Patty: "What if the world comes to an end tonight, Marcie?"
@ -605,10 +556,10 @@ entitled "The Kid," originally aired 1997-11-04)
</li>
<li>
"I put myself and my staff through this crazy, huge ordeal, all because
I refused to go on at midnight, okay? And so I work, you know, and
then I get this job at eleven, supposed to be a big deal. Then
I refused to go on at midnight, okay? And so I work, you know, and
then I get this job at eleven, supposed to be a big deal. Then
yesterday daylight [saving] time ended. Right now it's basically
midnight." (Conan O'Brien on the 2010-11-08 premiere of <em>Conan</em>.)
midnight." (Conan O'Brien on the 2010-11-08 premiere of <em>Conan</em>)
</li>
<li>
"The best method, I told folks, was to hang a large clock high on a
@ -616,7 +567,7 @@ barn wall where all the cows could see it. If you have Holsteins, you
will need to use an analog clock." (Jerry Nelson, <a
href="http://www.agriculture.com/family/farm-humor/how-to-adjust-dairy-cows-to-daylight-savings-time">How
to adjust dairy cows to daylight saving time</a>", <em>Successful Farming</em>,
2017-10-09.)
2017-10-09)
</li>
<li>
"And now, driving to California, I find that I must enter a password

View File

@ -114,7 +114,7 @@ Indiana, which switched from central to eastern time in 1991
and switched back in 2006.
To use the database on an extended <a
href="https://en.wikipedia.org/wiki/POSIX"><abbr
title="Portable Operating System Interface">POSIX</abbr></a>
title="Portable Operating System Interface">POSIX</abbr>.1-2017</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>
@ -172,7 +172,7 @@ Since version 2022a, each release has been distributed in
ustar interchange format</a>, compressed as described above;
older releases use a nearly compatible format.
Since version 2016h, each release has contained a text file named
"<samp>version</samp>" whose first (and currently only) line is the version.
"<code>version</code>" whose first (and currently only) line is the version.
Older releases are <a href="https://ftp.iana.org/tz/releases/">archived</a>,
and are also available in an
<a href="ftp://ftp.iana.org/tz/releases/"><abbr
@ -362,9 +362,6 @@ lets you see the <code><abbr>TZ</abbr></code> values directly.</li>
<li><a
href="https://www.convertit.com/Go/ConvertIt/World_Time/Current_Time.ASP">Current
Time in 1000 Places</a> uses descriptions of the values.</li>
<li><a href="https://home.kpn.nl/vanadovv/time/TZworld.html">Complete
timezone information for all countries</a>
displays tables of <abbr>DST</abbr> rules.
<li><a href="https://www.timeanddate.com/worldclock/">The World Clock &ndash;
Worldwide</a> lets you sort zone names and convert times.</li>
<li><a href="https://24timezones.com">24TimeZones</a> has a world
@ -511,12 +508,12 @@ It is freely available under the Apache License.</li>
<li>Many modern
<a href="https://en.wikipedia.org/wiki/JavaScript">JavaScript</a>
runtimes support <code><abbr>tz</abbr></code> natively via the
<samp>timeZone</samp> option of <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat"><samp>Intl.DateTimeFormat</samp></a>.
<code>timeZone</code> option of <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat"><code>Intl.DateTimeFormat</code></a>.
This can be used as-is or with most of the following libraries,
many of which also support runtimes lacking the <samp>timeZone</samp> option.
many of which also support runtimes lacking the <code>timeZone</code> option.
<ul>
<li>The <a
href="https://github.com/formatjs/date-time-format-timezone"><samp>Intl.DateTimeFormat</samp>
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>
@ -529,7 +526,7 @@ the <a href="https://momentjs.com/docs/">now-legacy Moment.js</a> date
manipulation library.
It is freely available under the <abbr>MIT</abbr> license.</li>
<li><a href="https://moment.github.io/luxon/">Luxon</a> improves
timezone support for the <samp>Intl</samp> API.
timezone support for the <code>Intl</code> API.
It is freely available under the <abbr>MIT</abbr> license.</li>
<li><a href="https://momentjs.com/timezone/">Moment Timezone</a> is a
Moment.js plugin.
@ -550,11 +547,11 @@ convert timestamps, view transition histories, and download code and data.
It is freely available under the <abbr>MIT</abbr> license.</li>
</ul>
The proposed <a
href="https://github.com/tc39/proposal-temporal"><samp>Temporal</samp>
href="https://github.com/tc39/proposal-temporal"><code>Temporal</code>
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 <samp>Date</samp> objects</a> when working with dates and times.
problematic <code>Date</code> objects</a> when working with dates and times.
<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
@ -620,6 +617,16 @@ the Apache License.</li>
library that translates between <abbr>UT</abbr> and civil time and
can read <abbr>TZif</abbr> files. It is freely available under the Apache
License.</li>
<li>The
<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.
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.
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
timestamps from one time zone or format to another.
@ -666,9 +673,7 @@ available under a <abbr>BSD</abbr>-style license.</li>
<ul>
<li><a href="https://foxclocks.org">FoxClocks</a>
is an extension for <a href="https://www.google.com/chrome/">Google
Chrome</a> and for <a
href="https://wiki.mozilla.org/Modules/Toolkit">Mozilla
Toolkit</a> applications like <a
Chrome</a>, <a
href="https://www.mozilla.org/en-US/firefox/new/">Firefox</a> and <a
href="https://www.mozilla.org/en-US/thunderbird/">Thunderbird</a>.
It displays multiple clocks in the application window, and has a mapping
@ -782,32 +787,9 @@ boundaries of <code><abbr>tzdb</abbr></code> timezones.
Its code is freely available under the <abbr>MIT</abbr> license, and
its data entries are freely available under the
<a href="https://opendatacommons.org/licenses/odbl/">Open Data Commons
Open Database License</a>. The maps' borders appear to be quite accurate.</li>
<li>Programmatic interfaces that map geographical coordinates via tz_world to
<code><abbr>tzdb</abbr></code> timezones include:
<ul>
<li><a href="https://github.com/mj1856/GeoTimeZone">GeoTimeZone</a> is
written in <a
href="https://en.wikipedia.org/wiki/C_Sharp_(programming_language)">C#</a>
and is freely available under the <abbr>MIT</abbr> license.</li>
<li>The <a href="https://github.com/bradfitz/latlong">latlong package</a>
is written in Go and is freely available under the Apache License.</li>
<li><a href="https://github.com/drtimcooper/LatLongToTimezone">LatLongToTimezone</a>,
in both Java and
<a href="https://en.wikipedia.org/wiki/Swift_(programming_language)">Swift</a>
form, is freely available under the MIT license.</li>
<li>For Node.js,
the <a href="https://www.npmjs.com/package/geo-tz">geo-tz module</a>
is freely available under the MIT license, and
the <a href="https://www.npmjs.com/package/tz-lookup">tz-lookup module</a>
is in the public domain.</li>
<li>The <a
href="https://github.com/MrMinimal64/timezonefinder">timezonefinder</a>
library for Python is freely available under the MIT license.
<li>The <a
href="https://github.com/gunyarakun/timezone_finder">timezone_finder</a>
library for Ruby is freely available under the MIT license.</li>
</ul></li>
Open Database License</a>. The borders appear to be quite accurate.
Its main web page lists more than twenty libraries
for looking up a timezone name from a GPS coordinate.</li>
<li>Free access via a network API, if you register a key, is provided by
the <a
href="https://www.geonames.org/export/web-services.html#timezone">GeoNames
@ -826,12 +808,9 @@ coordinates?</a>" discusses other geolocation possibilities.</li>
<li><a href="http://statoids.com/statoids.html">Administrative
Divisions of Countries ("Statoids")</a> lists
political subdivision data related to time zones.</li>
<li><a href="https://home.kpn.nl/vanadovv/time/Multizones.html">Time
zone boundaries for multizone countries</a> summarizes legal
boundaries between time zones within countries.</li>
<li><a href="https://manifold.net/info/freestuff.shtml">Manifold Software
&ndash; GIS and Database Tools</a> includes a Manifold-format map of
world time zone boundaries distributed under the
world time zone boundaries circa 2007, distributed under the
<abbr>GPL</abbr>.</li>
<li>A ship within the <a
href="https://en.wikipedia.org/wiki/Territorial_waters">territorial
@ -862,7 +841,7 @@ Lords</a> discusses how authoritarians manipulate civil time.</li>
<li><a href="https://www.w3.org/TR/timezone/">Working with Time Zones</a>
contains guidelines and best practices for software applications that
deal with civil time.</li>
<li><a href="https://www.staff.science.uu.nl/~gent0113/idl/idl.htm">A History of
<li><a href="https://webspace.science.uu.nl/~gent0113/idl/idl.htm">A History of
the International Date Line</a> tells the story of the most important
time zone boundary.</li>
<li><a href="http://statoids.com/tconcept.html">Basic Time
@ -875,7 +854,7 @@ Zone Concepts</a> discusses terminological issues behind time zones.</li>
<dl>
<dt>Australia</dt>
<dd>The Parliamentary Library commissioned a <a
href="https://www.aph.gov.au/binaries/library/pubs/rp/2009-10/10rp10.pdf">research
href="https://parlinfo.aph.gov.au/parlInfo/download/library/prspub/359V6/upload_binary/359v60.pdf">research
paper on daylight saving time in Australia</a>.
The Bureau of Meteorology publishes a list of <a
href="http://www.bom.gov.au/climate/averages/tables/dst_times.shtml">Implementation
@ -883,9 +862,9 @@ Dates of Daylight Savings Time within Australia</a>.</dd>
<dt>Belgium</dt>
<dd>The Royal Observatory of Belgium maintains a table of time in
Belgium (in
<a href="https://www.astro.oma.be/GENERAL/INFO/nli001a.html"
<a href="https://robinfo.oma.be/nl/astro-info/tijd/"
hreflang="nl">Dutch</a> and <a
href="https://www.astro.oma.be/GENERAL/INFO/fri001a.html"
href="https://robinfo.oma.be/fr/astro-info/heure/"
hreflang="fr">French</a>).</dd>
<dt>Brazil</dt>
<dd>The Time Service Department of the National Observatory
@ -929,7 +908,7 @@ Congress has published a <a
href="https://www.diputados.gob.mx/bibliot/publica/inveyana/polisoc/horver/index.htm"
hreflang="es">history of Mexican local time (in Spanish)</a>.</dd>
<dt>Netherlands</dt>
<dd><a href="https://www.staff.science.uu.nl/~gent0113/wettijd/wettijd.htm"
<dd><a href="https://webspace.science.uu.nl/~gent0113/wettijd/wettijd.htm"
hreflang="nl">Legal time in the Netherlands (in Dutch)</a>
covers the history of local time in the Netherlands from ancient times.</dd>
<dt>New Zealand</dt>
@ -938,7 +917,7 @@ href="https://www.dia.govt.nz/Daylight-Saving-History">History of
Daylight Saving</a>.</dd>
<dt>Palestine</dt>
<dd>The Ministry of Telecom and IT publishes a <a
href="https://mtit.pna.ps/Site/TimeZoon"
href="https://mtit.pna.ps/home/TimeZone"
hreflang="ar">history of clock changes (in Arabic)</a>.</dd>
<dt>Portugal</dt>
<dd>The Lisbon Astronomical Observatory publishes a
@ -973,6 +952,9 @@ zone shifts, and many scientific studies have been conducted. This
section summarizes reviews and position statements based on
scientific literature in the area.</p>
<ul>
<li>In 2022 the American Medical Association issued a
<a href="https://www.ama-assn.org/press-center/press-releases/ama-calls-permanent-standard-time">statement
supporting permanent standard time</a> on health grounds.</li>
<li>Carey RN, Sarma KM.
<a href="https://bmjopen.bmj.com/content/7/6/e014319.long">Impact of
daylight saving time on road traffic collision risk: a systematic
@ -983,25 +965,36 @@ neither supports nor refutes road safety benefits from
shifts in time zones.</li>
<li>Havranek T, Herman D, Irsova D.
<a href="https://www.iaee.org/en/publications/ejarticle.aspx?id=3051">Does
daylight saving save electricity? A meta-analysis.</a>
daylight saving save electricity? A meta-analysis</a>.
<em>Energy J.</em> 2018;39(2):35&ndash;61.
doi:<a href="https://doi.org/10.5547/01956574.39.2.thav">10.5547/01956574.39.2.thav</a>.
This analyzes research literature and concludes, "Electricity savings
are larger for countries farther away from the equator, while
subtropical regions consume more electricity because of <abbr>DST</abbr>."</li>
<li>Rishi MA, Ahmed O, Barrantes Perez JH <em>et al</em>.
<a href="https://jcsm.aasm.org/doi/10.5664/jcsm.8780">Daylight saving time:
<li>Malow BA. <a
href="https://academic.oup.com/sleep/article/45/12/zsac236/6717940">It is time
to abolish the clock change and adopt permanent
standard time in the United States:
a Sleep Research Society position statement</a>.
<em>Sleep.</em> 2022;45(12):zsac236.
doi:<a href="https://doi.org/10.1093/sleep/zsac236">10.1093/sleep/zsac236</a>.
After reviewing the scientific literature, the Sleep Research Society
advocates permanent standard time due to its health benefits.
<li>Rishi MA, Cheng JY, Strang AR <em>et al</em>.
<a href="https://jcsm.aasm.org/doi/10.5664/jcsm.10898">Permanent standard time
is the optimal choice for health and safety:
an American Academy of Sleep Medicine position statement</a>.
<em>J Clin Sleep Med.</em>
2020;<a href="https://doi.org/10.5664/jcsm.8780">10.5664/jcsm.8780</a>.
This argues for permanent standard time due to health risks of both
<abbr>DST</abbr> transitions and permanent <abbr>DST</abbr>.</li>
<em>J Clin Sleep Med.</em> 2024;20(1):121&ndash;125.
doi:<a href="https://doi.org/10.5664/jcsm.10898">10.5664/jcsm.10898</a>.
The AASM argues for permanent standard time due to health and safety risks
and economic costs of both <abbr>DST</abbr> transitions and
permanent <abbr>DST</abbr>.</li>
<li>Roenneberg T, Wirz-Justice A, Skene DJ <em>et al</em>.
<a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7205184/">Why
<a href="https://journals.sagepub.com/doi/10.1177/0748730419854197">Why
should we abolish Daylight Saving Time?</a>
<em>J Biol Rhythms</em>. 2019;34(3):227&ndash;230.
<em>J Biol Rhythms.</em> 2019;34(3):227&ndash;230.
doi:<a href="https://doi.org/10.1177/0748730419854197">10.1177/0748730419854197</a>.
This position paper of the Society for Research on Biological Rhythms
The Society for Research on Biological Rhythms
opposes DST changes and permanent DST, and advocates that governments adopt
"permanent Standard Time for the health and safety of their citizens".</li>
</ul>
@ -1117,9 +1110,12 @@ might be redefined
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">voted in 2022</a>
<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.
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.
</li>
</ul>
</section>

6
contrib/tzcode/tzdir.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef TZDEFAULT
# define TZDEFAULT "/etc/localtime" /* default zone */
#endif
#ifndef TZDIR
# define TZDIR "/usr/share/zoneinfo" /* TZif directory */
#endif

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-style TZ string described below.)
POSIX.1-2017-style TZ string described below.)
These values serve as indices into the next field.
.It Va tzh_typecnt
.Vt ttinfo
@ -166,7 +166,8 @@ must also be set.
.Pp
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-style TZ string that lacks rules.
for another time zone specified via
a POSIX.1-2017-style 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
@ -195,13 +196,14 @@ the above header and data are followed by a second header and data,
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,
POSIX-TZ-environment-variable-style string for use in handling instants
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,
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 POSIX-style TZ string is empty (i.e., nothing between the newlines)
if there is no POSIX-style representation for such instants.
If nonempty, the POSIX-style TZ string must agree with the local time
The TZ string is empty (i.e., nothing between the newlines)
if there is no POSIX.1-2017-style 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
.Dq "WET0WEST,M3.5.0/1,M10.5.0"
@ -213,8 +215,8 @@ 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 POSIX-TZ-style string may
use two minor extensions to the POSIX TZ format, as described in
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
@ -334,7 +336,7 @@ 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 in the TZ-like string.
they cannot parse extensions to POSIX.1-2017 in the TZ-like 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.
@ -385,7 +387,7 @@ Some readers mishandle a transition if its timestamp has
the minimum possible signed 64-bit value.
Timestamps less than \-2**59 are not recommended.
.It
Some readers mishandle POSIX-style TZ strings that
Some readers mishandle TZ strings that
contain
.Dq "<"
or
@ -413,13 +415,13 @@ Some readers mishandle TZif files that specify
daylight-saving time UT offsets that are less than the UT
offsets for the corresponding standard time.
These readers do not support locations like Ireland, which
uses the equivalent of the POSIX TZ string
.Dq "IST\*-1GMT0,M10.5.0,M3.5.0/1" ,
uses the equivalent of the TZ string
.Dq "IST\*-1GMT0,M10.5.0,M3.5.0/1",
observing standard time
(IST, +01) in summer and daylight saving time (GMT, +00) in winter.
As a partial workaround, a writer can output data for the
equivalent of the POSIX TZ string
.Dq "GMT0IST,M3.5.0/1,M10.5.0" ,
equivalent of the TZ string
.Dq "GMT0IST,M3.5.0/1,M10.5.0",
thus swapping standard and daylight saving time.
Although this workaround misidentifies which part of the year
uses daylight saving time, it records UT offsets and time zone

View File

@ -23,14 +23,6 @@
** Information about time zone files.
*/
#ifndef TZDIR
# define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
#endif /* !defined TZDIR */
#ifndef TZDEFAULT
# define TZDEFAULT "/etc/localtime"
#endif /* !defined TZDEFAULT */
#ifndef TZDEFRULES
# define TZDEFRULES "posixrules"
#endif /* !defined TZDEFRULES */
@ -88,11 +80,11 @@ struct tzhead {
** time uses 8 rather than 4 chars,
** then a POSIX-TZ-environment-variable-style string for use in handling
** instants after the last transition time stored in the file
** (with nothing between the newlines if there is no POSIX representation for
** such instants).
** (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.
** First, the POSIX TZ string's hour offset may range from -167
** First, the TZ string's hour offset may range from -167
** through 167 as compared to the POSIX-required 0 through 24.
** 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

View File

@ -95,7 +95,7 @@ Output version information and exit.
.SH "ENVIRONMENT VARIABLES"
.TP
\f3AWK\fP
Name of a Posix-compliant
Name of a POSIX-compliant
.B awk
program (default:
.BR awk ).

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
2023c
2024a

View File

@ -604,7 +604,7 @@ main(int argc, char *argv[])
if (!tz) {
char const *e = strerror(errno);
fprintf(stderr, _("%s: unknown timezone '%s': %s\n"),
progname, argv[1], e);
progname, argv[i], e);
return EXIT_FAILURE;
}
if (now) {

View File

@ -109,6 +109,12 @@ will act as if the input contained a link line of the form
Link \fItimezone\fP posixrules
.Ed
.Pp
If
.Ar timezone
is
.Dq "\*-"
(the default), any already-existing link is removed.
.Pp
Unless
.Ar timezone
is
@ -120,12 +126,6 @@ and it should not be combined with
if
.Ar timezone 's
transitions are at standard time or Universal Time (UT) instead of local time.
.Pp
If
.Ar timezone
is
.Ql - ,
any already-existing link is removed.
.It Fl r Oo @ Ns Ar lo Oc Ns Oo /@ Ns Ar hi Oc
Limit the applicability of output files
to timestamps in the range from
@ -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 TZ string.
with an extended POSIX.1-2017 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 TZ string.
more concisely represented via the extended POSIX.1-2017 TZ string.
This option does not affect the represented timestamps.
Although it accommodates nonstandard TZif readers
that ignore the extended POSIX TZ string,
that ignore the extended POSIX.1-2017 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,11 @@ 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 TZ string.
an extended POSIX.1-2017 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 TZ string cannot represent.
an extended POSIX.1-2017 TZ string cannot represent.
.It
The output contains data that may not be handled properly by client
code designed for older
@ -341,23 +341,14 @@ an unquoted name should not contain characters from the set
Gives the first year in which the rule applies.
Any signed integer year can be supplied; the proleptic Gregorian calendar
is assumed, with year 0 preceding year 1.
The word
.Cm minimum
(or an abbreviation) means the indefinite past.
The word
.Cm maximum
(or an abbreviation) means the indefinite future.
Rules can describe times that are not representable as time values,
with the unrepresentable times ignored; this allows rules to be portable
among hosts with differing time value types.
.It TO
Gives the final year in which the rule applies.
In addition to
.Cm minimum
and
The word
.Cm maximum
(as above),
the word
(or an abbreviation) means the indefinite future, and the word
.Cm only
(or an abbreviation)
may be used to repeat the value of the

View File

@ -14,6 +14,7 @@
#include "version.h"
#include "private.h"
#include "tzdir.h"
#include "tzfile.h"
#include <fcntl.h>
@ -34,6 +35,9 @@ static zic_t const
# define ZIC_MAX_ABBR_LEN_WO_WARN 6
#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */
/* Minimum and maximum years, assuming signed 32-bit time_t. */
enum { YEAR_32BIT_MIN = 1901, YEAR_32BIT_MAX = 2038 };
/* An upper bound on how much a format might grow due to concatenation. */
enum { FORMAT_LEN_GROWTH_BOUND = 5 };
@ -92,7 +96,6 @@ struct rule {
zic_t r_loyear; /* for example, 1986 */
zic_t r_hiyear; /* for example, 1986 */
bool r_lowasnum;
bool r_hiwasnum;
int r_month; /* 0..11 */
@ -164,13 +167,8 @@ symlink(char const *target, char const *linkname)
}
#endif
#ifndef AT_SYMLINK_FOLLOW
# if HAVE_LINK
# define linkat(targetdir, target, linknamedir, linkname, flag) \
(itssymlink(target) ? (errno = ENOTSUP, -1) : link(target, linkname))
# else
# define linkat(targetdir, target, linknamedir, linkname, flag) \
(errno = ENOTSUP, -1)
# endif
#endif
static void addtt(zic_t starttime, int type);
@ -190,7 +188,7 @@ static void inrule(char ** fields, int nfields);
static bool inzcont(char ** fields, int nfields);
static bool inzone(char ** fields, int nfields);
static bool inzsub(char **, int, bool);
static bool itssymlink(char const *);
static int itssymlink(char const *, int *);
static bool is_alpha(char a);
static char lowerit(char);
static void mkdirs(char const *, bool);
@ -334,7 +332,7 @@ enum {
*/
enum {
YR_MINIMUM,
YR_MINIMUM, /* "minimum" is for backward compatibility only */
YR_MAXIMUM,
YR_ONLY
};
@ -418,12 +416,10 @@ static struct lookup const lasts[] = {
static struct lookup const begin_years[] = {
{ "minimum", YR_MINIMUM },
{ "maximum", YR_MAXIMUM },
{ NULL, 0 }
};
static struct lookup const end_years[] = {
{ "minimum", YR_MINIMUM },
{ "maximum", YR_MAXIMUM },
{ "only", YR_ONLY },
{ NULL, 0 }
@ -903,7 +899,8 @@ static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
static zic_t lo_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
static zic_t hi_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
/* The time specified by the -R option, defaulting to MIN_TIME. */
/* The time specified by the -R option, defaulting to MIN_TIME;
or lo_time, whichever is greater. */
static zic_t redundant_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
/* The time specified by an Expires line, or negative if no such line. */
@ -1036,7 +1033,8 @@ main(int argc, char **argv)
directory = optarg;
else {
fprintf(stderr,
_("%s: More than one -d option specified\n"),
_("%s: More than one -d option"
" specified\n"),
progname);
return EXIT_FAILURE;
}
@ -1049,7 +1047,8 @@ _("%s: More than one -d option specified\n"),
lcltime = optarg;
else {
fprintf(stderr,
_("%s: More than one -l option specified\n"),
_("%s: More than one -l option"
" specified\n"),
progname);
return EXIT_FAILURE;
}
@ -1071,7 +1070,8 @@ _("invalid file mode"));
psxrules = optarg;
else {
fprintf(stderr,
_("%s: More than one -p option specified\n"),
_("%s: More than one -p option"
" specified\n"),
progname);
return EXIT_FAILURE;
}
@ -1097,7 +1097,8 @@ _("%s: More than one -p option specified\n"),
leapsec = optarg;
else {
fprintf(stderr,
_("%s: More than one -L option specified\n"),
_("%s: More than one -L option"
" specified\n"),
progname);
return EXIT_FAILURE;
}
@ -1108,13 +1109,14 @@ _("%s: More than one -L option specified\n"),
case 'r':
if (timerange_given) {
fprintf(stderr,
_("%s: More than one -r option specified\n"),
_("%s: More than one -r option"
" specified\n"),
progname);
return EXIT_FAILURE;
}
if (! timerange_option(optarg)) {
fprintf(stderr,
_("%s: invalid time range: %s\n"),
_("%s: invalid time range: %s\n"),
progname, optarg);
return EXIT_FAILURE;
}
@ -1137,6 +1139,8 @@ _("%s: invalid time range: %s\n"),
fprintf(stderr, _("%s: -R time exceeds -r cutoff\n"), progname);
return EXIT_FAILURE;
}
if (redundant_time < lo_time)
redundant_time = lo_time;
if (bloat == 0) {
static char const bloat_default[] = ZIC_BLOAT_DEFAULT;
if (strcmp(bloat_default, "slim") == 0)
@ -1429,9 +1433,9 @@ rename_dest(char *tempname, char const *name)
}
}
/* Create symlink contents suitable for symlinking FROM to TO, as a
freshly allocated string. FROM should be a relative file name, and
is relative to the global variable DIRECTORY. TO can be either
/* Create symlink contents suitable for symlinking TARGET to LINKNAME, as a
freshly allocated string. TARGET should be a relative file name, and
is relative to the global variable DIRECTORY. LINKNAME can be either
relative or absolute. */
static char *
relname(char const *target, char const *linkname)
@ -1468,6 +1472,18 @@ relname(char const *target, char const *linkname)
return result;
}
/* 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
same_parent_dirs(char const *a, char const *b)
{
for (; *a == *b; a++, b++)
if (!*a)
return true;
return ! (strchr(a, '/') || strchr(b, '/'));
}
static void
dolink(char const *target, char const *linkname, bool staysymlink)
{
@ -1475,6 +1491,7 @@ dolink(char const *target, char const *linkname, bool staysymlink)
int link_errno;
char *tempname = NULL;
char const *outname = linkname;
int targetissym = -2, linknameissym = -2;
check_for_signal();
@ -1496,13 +1513,32 @@ dolink(char const *target, char const *linkname, bool staysymlink)
break;
}
link_errno = errno;
/* Linux 2.6.16 and 2.6.17 mishandle AT_SYMLINK_FOLLOW. */
if (link_errno == EINVAL)
link_errno = ENOTSUP;
#if HAVE_LINK
/* If linkat is not supported, fall back on link(A, B).
However, skip this if A is a relative symlink
and A and B might not have the same parent directory.
On some platforms link(A, B) does not follow a symlink A,
and if A is relative it might misbehave elsewhere. */
if (link_errno == ENOTSUP
&& (same_parent_dirs(target, outname)
|| 0 <= itssymlink(target, &targetissym))) {
if (link(target, outname) == 0) {
link_errno = 0;
break;
}
link_errno = errno;
}
#endif
if (link_errno == EXDEV || link_errno == ENOTSUP)
break;
if (link_errno == EEXIST) {
staysymlink &= !tempname;
random_dirent(&outname, &tempname);
if (staysymlink && itssymlink(linkname))
if (staysymlink && itssymlink(linkname, &linknameissym))
break;
} else if (link_errno == ENOENT && !linkdirs_made) {
mkdirs(linkname, true);
@ -1565,12 +1601,17 @@ dolink(char const *target, char const *linkname, bool staysymlink)
rename_dest(tempname, linkname);
}
/* Return true if NAME is a symbolic link. */
static bool
itssymlink(char const *name)
/* Return 1 if NAME is an absolute symbolic link, -1 if it is relative,
0 if it is not a symbolic link. If *CACHE is not -2, it is the
cached result of a previous call to this function with the same NAME. */
static int
itssymlink(char const *name, int *cache)
{
char c;
return 0 <= readlink(name, &c, 1);
if (*cache == -2) {
char c = '\0';
*cache = readlink(name, &c, 1) < 0 ? 0 : c == '/' ? 1 : -1;
}
return *cache;
}
/*
@ -1883,16 +1924,14 @@ inzone(char **fields, int nfields)
return false;
}
if (lcltime != NULL && strcmp(fields[ZF_NAME], tzdefault) == 0) {
error(
_("\"Zone %s\" line and -l option are mutually exclusive"),
tzdefault);
return false;
error(_("\"Zone %s\" line and -l option are mutually exclusive"),
tzdefault);
return false;
}
if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) {
error(
_("\"Zone %s\" line and -p option are mutually exclusive"),
TZDEFRULES);
return false;
error(_("\"Zone %s\" line and -p option are mutually exclusive"),
TZDEFRULES);
return false;
}
for (i = 0; i < nzones; ++i)
if (zones[i].z_name != NULL &&
@ -1984,10 +2023,9 @@ inzsub(char **fields, int nfields, bool iscont)
zones[nzones - 1].z_untiltime > min_time &&
zones[nzones - 1].z_untiltime < max_time &&
zones[nzones - 1].z_untiltime >= z.z_untiltime) {
error(_(
"Zone continuation line end time is not after end time of previous line"
));
return false;
error(_("Zone continuation line end time is"
" not after end time of previous line"));
return false;
}
}
z.z_name = iscont ? NULL : estrdup(fields[ZF_NAME]);
@ -2189,13 +2227,12 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
*/
cp = loyearp;
lp = byword(cp, begin_years);
rp->r_lowasnum = lp == NULL;
if (!rp->r_lowasnum) switch (lp->l_value) {
if (lp) switch (lp->l_value) {
case YR_MINIMUM:
rp->r_loyear = ZIC_MIN;
break;
case YR_MAXIMUM:
rp->r_loyear = ZIC_MAX;
warning(_("FROM year \"%s\" is obsolete;"
" treated as %d"),
cp, YEAR_32BIT_MIN - 1);
rp->r_loyear = YEAR_32BIT_MIN - 1;
break;
default: unreachable();
} else if (sscanf(cp, "%"SCNdZIC"%c", &rp->r_loyear, &xs) != 1) {
@ -2206,9 +2243,6 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
lp = byword(cp, end_years);
rp->r_hiwasnum = lp == NULL;
if (!rp->r_hiwasnum) switch (lp->l_value) {
case YR_MINIMUM:
rp->r_hiyear = ZIC_MIN;
break;
case YR_MAXIMUM:
rp->r_hiyear = ZIC_MAX;
break;
@ -3000,6 +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
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. */
static int
stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
{
@ -3135,11 +3173,11 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
register char * envvar;
register int max_abbr_len;
register int max_envvar_len;
register bool prodstic; /* all rules are min to max */
register int compat;
register bool do_extend;
register char version;
ptrdiff_t lastatmax = -1;
zic_t nonTZlimtime = ZIC_MIN;
int nonTZlimtype = -1;
zic_t max_year0;
int defaulttype = -1;
@ -3160,7 +3198,6 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
timecnt = 0;
typecnt = 0;
charcnt = 0;
prodstic = zonecount == 1;
/*
** Thanks to Earl Chew
** for noting the need to unconditionally initialize startttisstd.
@ -3178,12 +3215,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
updateminmax(zp->z_untilrule.r_loyear);
for (j = 0; j < zp->z_nrules; ++j) {
struct rule *rp = &zp->z_rules[j];
if (rp->r_lowasnum)
updateminmax(rp->r_loyear);
updateminmax(rp->r_loyear);
if (rp->r_hiwasnum)
updateminmax(rp->r_hiyear);
if (rp->r_lowasnum || rp->r_hiwasnum)
prodstic = false;
}
}
/*
@ -3195,7 +3229,8 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
if (noise) {
if (!*envvar)
warning("%s %s",
_("no POSIX environment variable for zone"),
_("no POSIX.1-2017 environment variable"
" for zone"),
zpfirst->z_name);
else if (compat != 0) {
/* Circa-COMPAT clients, and earlier clients, might
@ -3207,37 +3242,12 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
}
}
if (do_extend) {
/*
** Search through a couple of extra years past the obvious
** 400, to avoid edge cases. For example, suppose a non-POSIX
** rule applies from 2012 onwards and has transitions in March
** and September, plus some one-off transitions in November
** 2013. 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, less than 400 years
** after the last one-off transition in 2013-11. Two years
** might be overkill, but with the kind of edge cases
** available we're not sure that one year would suffice.
*/
enum { years_of_observations = YEARSPERREPEAT + 2 };
if (min_year >= ZIC_MIN + years_of_observations)
min_year -= years_of_observations;
else min_year = ZIC_MIN;
if (max_year <= ZIC_MAX - years_of_observations)
max_year += years_of_observations;
else max_year = ZIC_MAX;
/*
** Regardless of any of the above,
** for a "proDSTic" zone which specifies that its rules
** always have and always will be in effect,
** we only need one cycle to define the zone.
*/
if (prodstic) {
min_year = 1900;
max_year = min_year + years_of_observations;
}
}
max_year = max(max_year, (redundant_time / (SECSPERDAY * DAYSPERNYEAR)
+ EPOCH_YEAR + 1));
@ -3245,17 +3255,16 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
if (want_bloat()) {
/* For the benefit of older systems,
generate data from 1900 through 2038. */
if (min_year > 1900)
min_year = 1900;
if (max_year < 2038)
max_year = 2038;
if (min_year > YEAR_32BIT_MIN - 1)
min_year = YEAR_32BIT_MIN - 1;
if (max_year < YEAR_32BIT_MAX)
max_year = YEAR_32BIT_MAX;
}
if (min_time < lo_time || hi_time < max_time)
unspecifiedtype = addtype(0, "-00", false, false, false);
for (i = 0; i < zonecount; ++i) {
struct rule *prevrp = NULL;
/*
** A guess that may well be corrected later.
*/
@ -3265,8 +3274,6 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
bool useuntil = i < (zonecount - 1);
zic_t stdoff = zp->z_stdoff;
zic_t startoff = stdoff;
zic_t prevktime;
INITIALIZE(prevktime);
if (useuntil && zp->z_untiltime <= min_time)
continue;
eat(zp->z_filenum, zp->z_linenum);
@ -3280,6 +3287,10 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
startttisut);
if (usestart) {
addtt(starttime, type);
if (useuntil && nonTZlimtime < starttime) {
nonTZlimtime = starttime;
nonTZlimtype = type;
}
usestart = false;
} else
defaulttype = type;
@ -3407,23 +3418,16 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
doabbr(ab, zp, rp->r_abbrvar,
rp->r_isdst, rp->r_save, false);
offset = oadd(zp->z_stdoff, rp->r_save);
if (!want_bloat() && !useuntil && !do_extend
&& prevrp && lo_time <= prevktime
&& redundant_time <= ktime
&& rp->r_hiyear == ZIC_MAX
&& prevrp->r_hiyear == ZIC_MAX)
break;
type = addtype(offset, ab, rp->r_isdst,
rp->r_todisstd, rp->r_todisut);
if (defaulttype < 0 && !rp->r_isdst)
defaulttype = type;
if (rp->r_hiyear == ZIC_MAX
&& ! (0 <= lastatmax
&& ktime < attypes[lastatmax].at))
lastatmax = timecnt;
addtt(ktime, type);
prevrp = rp;
prevktime = ktime;
if (nonTZlimtime < ktime
&& (useuntil || rp->r_hiyear != ZIC_MAX)) {
nonTZlimtime = ktime;
nonTZlimtype = type;
}
}
}
}
@ -3434,7 +3438,8 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
isdst, save, false);
eat(zp->z_filenum, zp->z_linenum);
if (*startbuf == '\0')
error(_("can't determine time zone abbreviation to use just after until time"));
error(_("can't determine time zone abbreviation"
" to use just after until time"));
else {
int type = addtype(startoff, startbuf, isdst,
startttisstd, startttisut);
@ -3458,12 +3463,38 @@ error(_("can't determine time zone abbreviation to use just after until time"));
}
if (defaulttype < 0)
defaulttype = 0;
if (0 <= lastatmax)
attypes[lastatmax].dontmerge = true;
if (!do_extend && !want_bloat()) {
/* Keep trailing transitions that are no greater than this. */
zic_t keep_at_max;
/* The earliest transition into a time governed by the TZ string. */
zic_t TZstarttime = ZIC_MAX;
for (i = 0; i < timecnt; i++) {
zic_t at = attypes[i].at;
if (nonTZlimtime < at && at < TZstarttime)
TZstarttime = at;
}
if (TZstarttime == ZIC_MAX)
TZstarttime = nonTZlimtime;
/* Omit trailing transitions deducible from the TZ string,
and not needed for -r or -R. */
keep_at_max = max(TZstarttime, redundant_time);
for (i = j = 0; i < timecnt; i++)
if (attypes[i].at <= keep_at_max) {
attypes[j].at = attypes[i].at;
attypes[j].dontmerge = (attypes[i].at == TZstarttime
&& (nonTZlimtype != attypes[i].type
|| strchr(envvar, ',')));
attypes[j].type = attypes[i].type;
j++;
}
timecnt = j;
}
if (do_extend) {
/*
** If we're extending the explicitly listed observations
** for 400 years because we can't fill the POSIX-TZ field,
** If we're extending the explicitly listed observations for
** 400 years because we can't fill the POSIX.1-2017 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

View File

@ -52,7 +52,7 @@ __SCCSID("@(#)sysconf.c 8.2 (Berkeley) 3/20/94");
#include "un-namespace.h"
#include "../stdlib/atexit.h"
#include "tzfile.h" /* from ../../../contrib/tzcode/stdtime */
#include "tzdir.h" /* from ../../../contrib/tzcode/stdtime */
#include "libc_private.h"
#define _PATH_ZONEINFO TZDIR /* from tzfile.h */

View File

@ -316,7 +316,7 @@ _fmt(const char *format, const struct tm * const t, char *pt,
time_t mkt;
tm = *t;
mkt = mktime(&tm);
mkt = timeoff(&tm, t->tm_gmtoff);
if (TYPE_SIGNED(time_t))
(void) sprintf_l(buf, loc, "%ld",
(long) mkt);