mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-24 07:40:52 +00:00
Update tzcode to 2023c.
MFC after: 3 weeks Sponsored by: Klara, Inc. Reviewed by: philip Differential Revision: https://reviews.freebsd.org/D39712
This commit is contained in:
commit
75411d1572
@ -18,7 +18,7 @@ To email small changes, please run a POSIX shell command like
|
|||||||
'diff -u old/europe new/europe >myfix.patch', and attach
|
'diff -u old/europe new/europe >myfix.patch', and attach
|
||||||
'myfix.patch' to the email.
|
'myfix.patch' to the email.
|
||||||
|
|
||||||
For more-elaborate or possibly-controversial changes,
|
For more-elaborate or possibly controversial changes,
|
||||||
such as renaming, adding or removing zones, please read
|
such as renaming, adding or removing zones, please read
|
||||||
"Theory and pragmatics of the tz code and data"
|
"Theory and pragmatics of the tz code and data"
|
||||||
<https://www.iana.org/time-zones/repository/theory.html>.
|
<https://www.iana.org/time-zones/repository/theory.html>.
|
||||||
|
@ -35,22 +35,14 @@ DATAFORM= main
|
|||||||
|
|
||||||
LOCALTIME= Factory
|
LOCALTIME= Factory
|
||||||
|
|
||||||
# The POSIXRULES macro controls interpretation of nonstandard and obsolete
|
# The POSIXRULES macro controls interpretation of POSIX-like TZ
|
||||||
# POSIX-like TZ settings like TZ='EET-2EEST' that lack DST transition rules.
|
# settings like TZ='EET-2EEST' that lack DST transition rules.
|
||||||
# Such a setting uses the rules in a template file to determine
|
|
||||||
# "spring forward" and "fall back" days and times; the environment
|
|
||||||
# variable itself specifies UT offsets of standard and daylight saving time.
|
|
||||||
#
|
|
||||||
# If POSIXRULES is '-', no template is installed; this is the default.
|
# 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:
|
# Any other value for POSIXRULES is obsolete and should not be relied on, as:
|
||||||
# * It does not work correctly in popular implementations such as GNU/Linux.
|
# * It does not work correctly in popular implementations such as GNU/Linux.
|
||||||
# * It does not work even in tzcode, except for historical timestamps
|
# * It does not work even in tzcode, except for historical timestamps
|
||||||
# that precede the last explicit transition in the POSIXRULES file.
|
# that precede the last explicit transition in the POSIXRULES file.
|
||||||
# Hence it typically does not work for current and future timestamps.
|
# Hence it typically does not work for current and future timestamps.
|
||||||
# In short, software should avoid ruleless settings like TZ='EET-2EEST'
|
|
||||||
# and so should not depend on the value of POSIXRULES.
|
|
||||||
#
|
|
||||||
# If, despite the above, you want a template for handling these settings,
|
# If, despite the above, you want a template for handling these settings,
|
||||||
# you can change the line below (after finding the timezone you want in the
|
# you can change the line below (after finding the timezone you want in the
|
||||||
# one of the $(TDATA) source files, or adding it to a source file).
|
# one of the $(TDATA) source files, or adding it to a source file).
|
||||||
@ -63,7 +55,7 @@ LOCALTIME= Factory
|
|||||||
POSIXRULES= -
|
POSIXRULES= -
|
||||||
|
|
||||||
# Also see TZDEFRULESTRING below, which takes effect only
|
# Also see TZDEFRULESTRING below, which takes effect only
|
||||||
# if the time zone files cannot be accessed.
|
# if POSIXRULES is '-' or if the template file cannot be accessed.
|
||||||
|
|
||||||
|
|
||||||
# Installation locations.
|
# Installation locations.
|
||||||
@ -211,7 +203,7 @@ LDLIBS=
|
|||||||
# -DHAVE_DECL_ENVIRON if <unistd.h> declares 'environ'
|
# -DHAVE_DECL_ENVIRON if <unistd.h> declares 'environ'
|
||||||
# -DHAVE_DECL_TIMEGM=0 if <time.h> does not declare timegm
|
# -DHAVE_DECL_TIMEGM=0 if <time.h> does not declare timegm
|
||||||
# -DHAVE_DIRECT_H if mkdir needs <direct.h> (MS-Windows)
|
# -DHAVE_DIRECT_H if mkdir needs <direct.h> (MS-Windows)
|
||||||
# -DHAVE_GENERIC=0 if _Generic does not work*
|
# -DHAVE__GENERIC=0 if _Generic does not work*
|
||||||
# -DHAVE_GETRANDOM if getrandom works (e.g., GNU/Linux),
|
# -DHAVE_GETRANDOM if getrandom works (e.g., GNU/Linux),
|
||||||
# -DHAVE_GETRANDOM=0 to avoid using getrandom
|
# -DHAVE_GETRANDOM=0 to avoid using getrandom
|
||||||
# -DHAVE_GETTEXT if gettext works (e.g., GNU/Linux, FreeBSD, Solaris),
|
# -DHAVE_GETTEXT if gettext works (e.g., GNU/Linux, FreeBSD, Solaris),
|
||||||
@ -220,7 +212,7 @@ LDLIBS=
|
|||||||
# -DHAVE_INCOMPATIBLE_CTIME_R if your system's time.h declares
|
# -DHAVE_INCOMPATIBLE_CTIME_R if your system's time.h declares
|
||||||
# ctime_r and asctime_r incompatibly with the POSIX standard
|
# ctime_r and asctime_r incompatibly with the POSIX standard
|
||||||
# (Solaris when _POSIX_PTHREAD_SEMANTICS is not defined).
|
# (Solaris when _POSIX_PTHREAD_SEMANTICS is not defined).
|
||||||
# -DHAVE_INTTYPES_H=0 if <inttypes.h> does not work*
|
# -DHAVE_INTTYPES_H=0 if <inttypes.h> does not work*+
|
||||||
# -DHAVE_LINK=0 if your system lacks a link function
|
# -DHAVE_LINK=0 if your system lacks a link function
|
||||||
# -DHAVE_LOCALTIME_R=0 if your system lacks a localtime_r function
|
# -DHAVE_LOCALTIME_R=0 if your system lacks a localtime_r function
|
||||||
# -DHAVE_LOCALTIME_RZ=0 if you do not want zdump to use localtime_rz
|
# -DHAVE_LOCALTIME_RZ=0 if you do not want zdump to use localtime_rz
|
||||||
@ -229,22 +221,24 @@ LDLIBS=
|
|||||||
# -DHAVE_POSIX_DECLS=0 if your system's include files do not declare
|
# -DHAVE_POSIX_DECLS=0 if your system's include files do not declare
|
||||||
# functions like 'link' or variables like 'tzname' required by POSIX
|
# functions like 'link' or variables like 'tzname' required by POSIX
|
||||||
# -DHAVE_SETENV=0 if your system lacks the setenv function
|
# -DHAVE_SETENV=0 if your system lacks the setenv function
|
||||||
# -DHAVE_SNPRINTF=0 if your system lacks the snprintf function
|
# -DHAVE_SNPRINTF=0 if your system lacks the snprintf function+
|
||||||
# -DHAVE_STDCKDINT_H=0 if neither <stdckdint.h> nor substitutes like
|
# -DHAVE_STDCKDINT_H=0 if neither <stdckdint.h> nor substitutes like
|
||||||
# __builtin_add_overflow work*
|
# __builtin_add_overflow work*
|
||||||
# -DHAVE_STDINT_H=0 if <stdint.h> does not work*
|
# -DHAVE_STDINT_H=0 if <stdint.h> does not work*+
|
||||||
# -DHAVE_STRFTIME_L if <time.h> declares locale_t and strftime_l
|
# -DHAVE_STRFTIME_L if <time.h> declares locale_t and strftime_l
|
||||||
# -DHAVE_STRDUP=0 if your system lacks the strdup function
|
# -DHAVE_STRDUP=0 if your system lacks the strdup function
|
||||||
# -DHAVE_STRTOLL=0 if your system lacks the strtoll function
|
# -DHAVE_STRTOLL=0 if your system lacks the strtoll function+
|
||||||
# -DHAVE_SYMLINK=0 if your system lacks the symlink function
|
# -DHAVE_SYMLINK=0 if your system lacks the symlink function
|
||||||
# -DHAVE_SYS_STAT_H=0 if <sys/stat.h> does not work*
|
# -DHAVE_SYS_STAT_H=0 if <sys/stat.h> does not work*
|
||||||
# -DHAVE_TZSET=0 if your system lacks a tzset function
|
# -DHAVE_TZSET=0 if your system lacks a tzset function
|
||||||
# -DHAVE_UNISTD_H=0 if <unistd.h> does not work*
|
# -DHAVE_UNISTD_H=0 if <unistd.h> does not work*
|
||||||
# -DHAVE_UTMPX_H=0 if <utmpx.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
|
# -Dlocale_t=XXX if your system uses XXX instead of locale_t
|
||||||
|
# -DPORT_TO_C89 if tzcode should also run on C89 platforms+
|
||||||
# -DRESERVE_STD_EXT_IDS if your platform reserves standard identifiers
|
# -DRESERVE_STD_EXT_IDS if your platform reserves standard identifiers
|
||||||
# with external linkage, e.g., applications cannot define 'localtime'.
|
# with external linkage, e.g., applications cannot define 'localtime'.
|
||||||
# -Dssize_t=long on hosts like MS-Windows that lack ssize_t
|
# -Dssize_t=long on hosts like MS-Windows that lack ssize_t
|
||||||
|
# -DSUPPORT_C89 if the tzcode library should support C89 callers+
|
||||||
# -DSUPPRESS_TZDIR to not prepend TZDIR to file names; this has
|
# -DSUPPRESS_TZDIR to not prepend TZDIR to file names; this has
|
||||||
# security implications and is not recommended for general use
|
# security implications and is not recommended for general use
|
||||||
# -DTHREAD_SAFE to make localtime.c thread-safe, as POSIX requires;
|
# -DTHREAD_SAFE to make localtime.c thread-safe, as POSIX requires;
|
||||||
@ -256,7 +250,13 @@ LDLIBS=
|
|||||||
# -DTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory;
|
# -DTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory;
|
||||||
# the default is system-supplied, typically "/usr/lib/locale"
|
# the default is system-supplied, typically "/usr/lib/locale"
|
||||||
# -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified
|
# -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified
|
||||||
# DST transitions if the time zone files cannot be accessed
|
# DST transitions for POSIX-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.
|
||||||
|
# It also mishandles settings like TZ='EET-2EEST' for eastern Europe,
|
||||||
|
# as Europe and US DST rules differ.
|
||||||
|
# -DTZNAME_MAXIMUM=N to limit time zone abbreviations to N bytes (default 255)
|
||||||
# -DUNINIT_TRAP if reading uninitialized storage can cause problems
|
# -DUNINIT_TRAP if reading uninitialized storage can cause problems
|
||||||
# other than simply getting garbage data
|
# other than simply getting garbage data
|
||||||
# -DUSE_LTZ=0 to build zdump with the system time zone library
|
# -DUSE_LTZ=0 to build zdump with the system time zone library
|
||||||
@ -273,6 +273,8 @@ LDLIBS=
|
|||||||
# $(GCC_DEBUG_FLAGS) if you are using recent GCC and want lots of checking
|
# $(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 "*" 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.
|
||||||
#
|
#
|
||||||
# Select instrumentation via "make GCC_INSTRUMENT='whatever'".
|
# Select instrumentation via "make GCC_INSTRUMENT='whatever'".
|
||||||
GCC_INSTRUMENT = \
|
GCC_INSTRUMENT = \
|
||||||
@ -351,6 +353,7 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
|
|||||||
# functions to be added to the time conversion library.
|
# functions to be added to the time conversion library.
|
||||||
# "offtime" is like "gmtime" except that it accepts a second (long) argument
|
# "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.
|
# 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".
|
# "timelocal" is equivalent to "mktime".
|
||||||
# "timeoff" is like "timegm" except that it accepts a second (long) argument
|
# "timeoff" is like "timegm" except that it accepts a second (long) argument
|
||||||
# that gives an offset to use when converting to a time_t.
|
# that gives an offset to use when converting to a time_t.
|
||||||
@ -363,7 +366,7 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
|
|||||||
# -DNETBSD_INSPIRED=0
|
# -DNETBSD_INSPIRED=0
|
||||||
# to the end of the "CFLAGS=" line. Otherwise, the functions
|
# to the end of the "CFLAGS=" line. Otherwise, the functions
|
||||||
# "localtime_rz", "mktime_z", "tzalloc", and "tzfree" are added to the
|
# "localtime_rz", "mktime_z", "tzalloc", and "tzfree" are added to the
|
||||||
# time library, and if STD_INSPIRED is also defined the functions
|
# time library, and if STD_INSPIRED is also defined to nonzero the functions
|
||||||
# "posix2time_z" and "time2posix_z" are added as well.
|
# "posix2time_z" and "time2posix_z" are added as well.
|
||||||
# The functions ending in "_z" (or "_rz") are like their unsuffixed
|
# The functions ending in "_z" (or "_rz") are like their unsuffixed
|
||||||
# (or suffixed-by-"_r") counterparts, except with an extra first
|
# (or suffixed-by-"_r") counterparts, except with an extra first
|
||||||
@ -455,16 +458,13 @@ SAFE_CHARSET3= 'abcdefghijklmnopqrstuvwxyz{|}~'
|
|||||||
SAFE_CHARSET= $(SAFE_CHARSET1)$(SAFE_CHARSET2)$(SAFE_CHARSET3)
|
SAFE_CHARSET= $(SAFE_CHARSET1)$(SAFE_CHARSET2)$(SAFE_CHARSET3)
|
||||||
SAFE_CHAR= '[]'$(SAFE_CHARSET)'-]'
|
SAFE_CHAR= '[]'$(SAFE_CHARSET)'-]'
|
||||||
|
|
||||||
# These characters are Latin-1, and so are likely to be displayable
|
# These non-alphabetic, non-ASCII printable characters are Latin-1,
|
||||||
# even in editors with limited character sets.
|
# and so are likely displayable even in editors like XEmacs 21
|
||||||
UNUSUAL_OK_LATIN_1 = «°±»½¾×
|
# that have limited display capabilities.
|
||||||
# This IPA symbol is represented in Unicode as the composition of
|
UNUSUAL_OK_LATIN_1 = ¡¢£¤¥¦§¨©«¬®¯°±²³´¶·¸¹»¼½¾¿×÷
|
||||||
# U+0075 and U+032F, and U+032F is not considered alphabetic by some
|
|
||||||
# grep implementations that do not grok composition.
|
|
||||||
UNUSUAL_OK_IPA = u̯
|
|
||||||
# Non-ASCII non-letters that OK_CHAR allows, as these characters are
|
# Non-ASCII non-letters that OK_CHAR allows, as these characters are
|
||||||
# useful in commentary.
|
# useful in commentary.
|
||||||
UNUSUAL_OK_CHARSET= $(UNUSUAL_OK_LATIN_1)$(UNUSUAL_OK_IPA)
|
UNUSUAL_OK_CHARSET= $(UNUSUAL_OK_LATIN_1)
|
||||||
|
|
||||||
# Put this in a bracket expression to match spaces.
|
# Put this in a bracket expression to match spaces.
|
||||||
s = [:space:]
|
s = [:space:]
|
||||||
@ -833,7 +833,7 @@ check_slashed_abbrs: $(TDATA_TO_CHECK)
|
|||||||
|
|
||||||
CHECK_CC_LIST = { n = split($$1,a,/,/); for (i=2; i<=n; i++) print a[1], a[i]; }
|
CHECK_CC_LIST = { n = split($$1,a,/,/); for (i=2; i<=n; i++) print a[1], a[i]; }
|
||||||
|
|
||||||
check_sorted: backward backzone iso3166.tab zone.tab zone1970.tab
|
check_sorted: backward backzone
|
||||||
$(AWK) '/^Link/ {printf "%.5d %s\n", g, $$3} !/./ {g++}' \
|
$(AWK) '/^Link/ {printf "%.5d %s\n", g, $$3} !/./ {g++}' \
|
||||||
backward | LC_ALL=C sort -cu
|
backward | LC_ALL=C sort -cu
|
||||||
$(AWK) '/^Zone/ {print $$2}' backzone | LC_ALL=C sort -cu
|
$(AWK) '/^Zone/ {print $$2}' backzone | LC_ALL=C sort -cu
|
||||||
|
@ -1,5 +1,116 @@
|
|||||||
News for the tz database
|
News for the tz database
|
||||||
|
|
||||||
|
Release 2023c - 2023-03-28 12:42:14 -0700
|
||||||
|
|
||||||
|
Changes to past and future timestamps
|
||||||
|
|
||||||
|
Model Lebanon's DST chaos by reverting data to tzdb 2023a.
|
||||||
|
(Thanks to Rany Hany for the heads-up.)
|
||||||
|
|
||||||
|
|
||||||
|
Release 2023b - 2023-03-23 19:50:38 -0700
|
||||||
|
|
||||||
|
Changes to future timestamps
|
||||||
|
|
||||||
|
This year Lebanon springs forward April 20/21 not March 25/26.
|
||||||
|
(Thanks to Saadallah Itani.) [This was reverted in 2023c.]
|
||||||
|
|
||||||
|
|
||||||
|
Release 2023a - 2023-03-22 12:39:33 -0700
|
||||||
|
|
||||||
|
Briefly:
|
||||||
|
Egypt now uses DST again, from April through October.
|
||||||
|
This year Morocco springs forward April 23, not April 30.
|
||||||
|
Palestine delays the start of DST this year.
|
||||||
|
Much of Greenland still uses DST from 2024 on.
|
||||||
|
America/Yellowknife now links to America/Edmonton.
|
||||||
|
tzselect can now use current time to help infer timezone.
|
||||||
|
The code now defaults to C99 or later.
|
||||||
|
Fix use of C23 attributes.
|
||||||
|
|
||||||
|
Changes to future timestamps
|
||||||
|
|
||||||
|
Starting in 2023, Egypt will observe DST from April's last Friday
|
||||||
|
through October's last Thursday. (Thanks to Ahmad ElDardiry.)
|
||||||
|
Assume the transition times are 00:00 and 24:00, respectively.
|
||||||
|
|
||||||
|
In 2023 Morocco's spring-forward transition after Ramadan
|
||||||
|
will occur April 23, not April 30. (Thanks to Milamber.)
|
||||||
|
Adjust predictions for future years accordingly. This affects
|
||||||
|
predictions for 2023, 2031, 2038, and later years.
|
||||||
|
|
||||||
|
This year Palestine will delay its spring forward from
|
||||||
|
March 25 to April 29 due to Ramadan. (Thanks to Heba Hamad.)
|
||||||
|
Make guesses for future Ramadans too.
|
||||||
|
|
||||||
|
Much of Greenland, represented by America/Nuuk, will continue to
|
||||||
|
observe DST using European Union rules. When combined with
|
||||||
|
Greenland's decision not to change the clocks in fall 2023,
|
||||||
|
America/Nuuk therefore changes from -03/-02 to -02/-01 effective
|
||||||
|
2023-10-29 at 01:00 UTC. (Thanks to Thomas M. Steenholdt.)
|
||||||
|
This change from 2022g doesn't affect timestamps until 2024-03-30,
|
||||||
|
and doesn't affect tm_isdst until 2023-03-25.
|
||||||
|
|
||||||
|
Changes to past timestamps
|
||||||
|
|
||||||
|
America/Yellowknife has changed from a Zone to a backward
|
||||||
|
compatibility Link, as it no longer differs from America/Edmonton
|
||||||
|
since 1970. (Thanks to Almaz Mingaleev.) This affects some
|
||||||
|
pre-1948 timestamps. The old data are now in 'backzone'.
|
||||||
|
|
||||||
|
Changes to past time zone abbreviations
|
||||||
|
|
||||||
|
When observing Moscow time, Europe/Kirov and Europe/Volgograd now
|
||||||
|
use the abbreviations MSK/MSD instead of numeric abbreviations,
|
||||||
|
for consistency with other timezones observing Moscow time.
|
||||||
|
|
||||||
|
Changes to code
|
||||||
|
|
||||||
|
You can now tell tzselect local time, to simplify later choices.
|
||||||
|
Select the 'time' option in its first prompt.
|
||||||
|
|
||||||
|
You can now compile with -DTZNAME_MAXIMUM=N to limit time zone
|
||||||
|
abbreviations to N bytes (default 255). The reference runtime
|
||||||
|
library now rejects POSIX-style TZ strings that contain longer
|
||||||
|
abbreviations, treating them as UTC. Previously the limit was
|
||||||
|
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 now builds again on pre-C99 platforms, if you compile
|
||||||
|
with -DPORT_TO_C89. This fixes a bug introduced in 2022f.
|
||||||
|
|
||||||
|
On C23-compatible platforms tzcode no longer uses syntax like
|
||||||
|
'static [[noreturn]] void usage(void);'. Instead, it uses
|
||||||
|
'[[noreturn]] static void usage(void);' as strict C23 requires.
|
||||||
|
(Problem reported by Houge Langley.)
|
||||||
|
|
||||||
|
The code's functions now constrain their arguments with the C
|
||||||
|
'restrict' keyword consistently with their documentation.
|
||||||
|
This may allow future optimizations.
|
||||||
|
|
||||||
|
zdump again builds standalone with ckdadd and without setenv,
|
||||||
|
fixing a bug introduced in 2022g. (Problem reported by panic.)
|
||||||
|
|
||||||
|
leapseconds.awk can now process a leap seconds file that never
|
||||||
|
expires; this might be useful if leap seconds are discontinued.
|
||||||
|
|
||||||
|
Changes to commentary
|
||||||
|
|
||||||
|
tz-link.html has a new section "Coordinating with governments and
|
||||||
|
distributors". (Thanks to Neil Fuller for some of the text.)
|
||||||
|
|
||||||
|
To improve tzselect diagnostics, zone1970.tab's comments column is
|
||||||
|
now limited to countries that have multiple timezones.
|
||||||
|
|
||||||
|
Note that leap seconds are planned to be discontinued by 2035.
|
||||||
|
|
||||||
|
|
||||||
Release 2022g - 2022-11-29 08:58:31 -0800
|
Release 2022g - 2022-11-29 08:58:31 -0800
|
||||||
|
|
||||||
Briefly:
|
Briefly:
|
||||||
@ -596,7 +707,7 @@ Release 2021b - 2021-09-24 16:23:00 -0700
|
|||||||
Starting with 2020a, zic -L truncated its output according to the
|
Starting with 2020a, zic -L truncated its output according to the
|
||||||
"Expires" directive or "#expires" comment in the leapseconds file.
|
"Expires" directive or "#expires" comment in the leapseconds file.
|
||||||
The resulting TZif files omitted daylight saving transitions after
|
The resulting TZif files omitted daylight saving transitions after
|
||||||
the leap second table expired, which led to far less-accurate
|
the leap second table expired, which led to far less accurate
|
||||||
predictions of times after the expiry. Although future timestamps
|
predictions of times after the expiry. Although future timestamps
|
||||||
cannot be converted accurately in the presence of leap seconds, it
|
cannot be converted accurately in the presence of leap seconds, it
|
||||||
is more accurate to convert near-future timestamps with a few
|
is more accurate to convert near-future timestamps with a few
|
||||||
@ -616,7 +727,7 @@ Release 2021b - 2021-09-24 16:23:00 -0700
|
|||||||
zic -L LEAPFILE -r @LO no longer generates an invalid TZif file
|
zic -L LEAPFILE -r @LO no longer generates an invalid TZif file
|
||||||
that omits leap second information for the range LO..B when LO
|
that omits leap second information for the range LO..B when LO
|
||||||
falls between two leap seconds A and B. Instead, it generates a
|
falls between two leap seconds A and B. Instead, it generates a
|
||||||
TZif version 4 file that represents the previously-missing
|
TZif version 4 file that represents the previously missing
|
||||||
information.
|
information.
|
||||||
|
|
||||||
The TZif reader now allows the leap second table to begin with a
|
The TZif reader now allows the leap second table to begin with a
|
||||||
@ -670,7 +781,7 @@ Release 2021b - 2021-09-24 16:23:00 -0700
|
|||||||
Fix a bug with 'zic -r @X' when X is a negative leap second that
|
Fix a bug with 'zic -r @X' when X is a negative leap second that
|
||||||
has a nonnegative correction. Without the fix, the output file
|
has a nonnegative correction. Without the fix, the output file
|
||||||
was truncated so that X appeared to be a positive leap second.
|
was truncated so that X appeared to be a positive leap second.
|
||||||
Fix a similar, even-less-likely bug when truncating at a positive
|
Fix a similar, even less likely bug when truncating at a positive
|
||||||
leap second that has a nonpositive correction.
|
leap second that has a nonpositive correction.
|
||||||
|
|
||||||
zic -r now reports an error if given rolling leap seconds, as this
|
zic -r now reports an error if given rolling leap seconds, as this
|
||||||
@ -691,7 +802,7 @@ Release 2021b - 2021-09-24 16:23:00 -0700
|
|||||||
fixing a bug introduced in 2014g.
|
fixing a bug introduced in 2014g.
|
||||||
|
|
||||||
zdump -v now outputs timestamps at boundaries of what localtime
|
zdump -v now outputs timestamps at boundaries of what localtime
|
||||||
and gmtime can represent, instead of the less-useful timestamps
|
and gmtime can represent, instead of the less useful timestamps
|
||||||
one day after the minimum and one day before the maximum.
|
one day after the minimum and one day before the maximum.
|
||||||
(Thanks to Arthur David Olson for prototype code, and to Manuela
|
(Thanks to Arthur David Olson for prototype code, and to Manuela
|
||||||
Friedrich for debugging help.)
|
Friedrich for debugging help.)
|
||||||
@ -2311,7 +2422,7 @@ Release 2016g - 2016-09-13 08:56:38 -0700
|
|||||||
names internally.
|
names internally.
|
||||||
|
|
||||||
zdump has a new -i option to generate transitions in a
|
zdump has a new -i option to generate transitions in a
|
||||||
more-compact but still human-readable format. This option is
|
smaller but still human-readable format. This option is
|
||||||
experimental, and the output format may change in future versions.
|
experimental, and the output format may change in future versions.
|
||||||
(Thanks to Jon Skeet for suggesting that an option was needed,
|
(Thanks to Jon Skeet for suggesting that an option was needed,
|
||||||
and thanks to Tim Parenti and Chris Rovick for further comments.)
|
and thanks to Tim Parenti and Chris Rovick for further comments.)
|
||||||
@ -2333,7 +2444,7 @@ Release 2016g - 2016-09-13 08:56:38 -0700
|
|||||||
release 2016g, the version number is now something like
|
release 2016g, the version number is now something like
|
||||||
'2016g-23-g50556e3-dirty' instead of the misleading '2016g'.
|
'2016g-23-g50556e3-dirty' instead of the misleading '2016g'.
|
||||||
Tagged releases use the same version number format as before,
|
Tagged releases use the same version number format as before,
|
||||||
e.g., '2016g'. To support the more-accurate version number, its
|
e.g., '2016g'. To support the more accurate version number, its
|
||||||
specification has moved from a line in the Makefile to a new
|
specification has moved from a line in the Makefile to a new
|
||||||
source file 'version'.
|
source file 'version'.
|
||||||
|
|
||||||
@ -2964,7 +3075,7 @@ Release 2014i - 2014-10-21 22:04:57 -0700
|
|||||||
|
|
||||||
Since Belarus is not changing its clocks even though Moscow is,
|
Since Belarus is not changing its clocks even though Moscow is,
|
||||||
the time zone abbreviation in Europe/Minsk is changing from FET
|
the time zone abbreviation in Europe/Minsk is changing from FET
|
||||||
to its more-traditional value MSK on 2014-10-26 at 01:00.
|
to its more traditional value MSK on 2014-10-26 at 01:00.
|
||||||
(Thanks to Alexander Bokovoy for the heads-up about Belarus.)
|
(Thanks to Alexander Bokovoy for the heads-up about Belarus.)
|
||||||
|
|
||||||
The new abbreviation IDT stands for the pre-1976 use of UT +08 in
|
The new abbreviation IDT stands for the pre-1976 use of UT +08 in
|
||||||
@ -3056,7 +3167,7 @@ Release 2014h - 2014-09-25 18:59:03 -0700
|
|||||||
|
|
||||||
Changes affecting build procedure
|
Changes affecting build procedure
|
||||||
|
|
||||||
'make check' now checks better for properly-sorted data.
|
'make check' now checks better for properly sorted data.
|
||||||
|
|
||||||
Changes affecting documentation and commentary
|
Changes affecting documentation and commentary
|
||||||
|
|
||||||
@ -3557,7 +3668,7 @@ Release 2014a - 2014-03-07 23:30:29 -0800
|
|||||||
|
|
||||||
Changes affecting past timestamps
|
Changes affecting past timestamps
|
||||||
|
|
||||||
Fiji ended DST on 2014-01-19 at 02:00, not the previously-scheduled 03:00.
|
Fiji ended DST on 2014-01-19 at 02:00, not the previously scheduled 03:00.
|
||||||
(Thanks to Steffen Thorsen.)
|
(Thanks to Steffen Thorsen.)
|
||||||
|
|
||||||
Ukraine switched from Moscow to Eastern European time on 1990-07-01
|
Ukraine switched from Moscow to Eastern European time on 1990-07-01
|
||||||
@ -3811,7 +3922,7 @@ Release 2013e - 2013-09-19 23:50:04 -0700
|
|||||||
Allow POSIX-like TZ strings where the transition time's hour can
|
Allow POSIX-like TZ strings where the transition time's hour can
|
||||||
range from -167 through 167, instead of the POSIX-required 0
|
range from -167 through 167, instead of the POSIX-required 0
|
||||||
through 24. E.g., TZ='FJT-12FJST,M10.3.1/146,M1.3.4/75' for the
|
through 24. E.g., TZ='FJT-12FJST,M10.3.1/146,M1.3.4/75' for the
|
||||||
new Fiji rules. This is a more-compact way to represent
|
new Fiji rules. This is a more compact way to represent
|
||||||
far-future timestamps for America/Godthab, America/Santiago,
|
far-future timestamps for America/Godthab, America/Santiago,
|
||||||
Antarctica/Palmer, Asia/Gaza, Asia/Hebron, Asia/Jerusalem,
|
Antarctica/Palmer, Asia/Gaza, Asia/Hebron, Asia/Jerusalem,
|
||||||
Pacific/Easter, and Pacific/Fiji. Other zones are unaffected by
|
Pacific/Easter, and Pacific/Fiji. Other zones are unaffected by
|
||||||
@ -3819,7 +3930,7 @@ Release 2013e - 2013-09-19 23:50:04 -0700
|
|||||||
|
|
||||||
Allow POSIX-like TZ strings where daylight saving time is in
|
Allow POSIX-like TZ strings where daylight saving time is in
|
||||||
effect all year. E.g., TZ='WART4WARST,J1/0,J365/25' for Western
|
effect all year. E.g., TZ='WART4WARST,J1/0,J365/25' for Western
|
||||||
Argentina Summer Time all year. This supports a more-compact way
|
Argentina Summer Time all year. This supports a more compact way
|
||||||
to represent the 2013d data for America/Argentina/San_Luis.
|
to represent the 2013d data for America/Argentina/San_Luis.
|
||||||
Because of the change for San Luis noted above this change does not
|
Because of the change for San Luis noted above this change does not
|
||||||
affect the current data. (Thanks to Andrew Main (Zefram) for
|
affect the current data. (Thanks to Andrew Main (Zefram) for
|
||||||
@ -3908,13 +4019,13 @@ Release 2013e - 2013-09-19 23:50:04 -0700
|
|||||||
|
|
||||||
zdump now outputs "UT" when referring to Universal Time, not "UTC".
|
zdump now outputs "UT" when referring to Universal Time, not "UTC".
|
||||||
"UTC" does not make sense for timestamps that predate the introduction
|
"UTC" does not make sense for timestamps that predate the introduction
|
||||||
of UTC, whereas "UT", a more-generic term, does. (Thanks to Steve Allen
|
of UTC, whereas "UT", a more generic term, does. (Thanks to Steve Allen
|
||||||
for clarifying UT vs UTC.)
|
for clarifying UT vs UTC.)
|
||||||
|
|
||||||
Data changes affecting behavior of tzselect and similar programs
|
Data changes affecting behavior of tzselect and similar programs
|
||||||
|
|
||||||
Country code BQ is now called the more-common name "Caribbean Netherlands"
|
Country code BQ is now called the more common name "Caribbean Netherlands"
|
||||||
rather than the more-official "Bonaire, St Eustatius & Saba".
|
rather than the more official "Bonaire, St Eustatius & Saba".
|
||||||
|
|
||||||
Remove from zone.tab the names America/Montreal, America/Shiprock,
|
Remove from zone.tab the names America/Montreal, America/Shiprock,
|
||||||
and Antarctica/South_Pole, as they are equivalent to existing
|
and Antarctica/South_Pole, as they are equivalent to existing
|
||||||
@ -4098,7 +4209,7 @@ Release 2013c - 2013-04-19 16:17:40 -0700
|
|||||||
Macquarie Island is politically part of Australia, not Antarctica.
|
Macquarie Island is politically part of Australia, not Antarctica.
|
||||||
(Thanks to Tobias Conradi.)
|
(Thanks to Tobias Conradi.)
|
||||||
|
|
||||||
Sort Macquarie more-consistently with other parts of Australia.
|
Sort Macquarie more consistently with other parts of Australia.
|
||||||
(Thanks to Tim Parenti.)
|
(Thanks to Tim Parenti.)
|
||||||
|
|
||||||
|
|
||||||
@ -5322,7 +5433,7 @@ Release data1998g - 1998-08-11 03:28:35 -0000
|
|||||||
Release data1998f - 1998-07-20 13:50:00 -0000
|
Release data1998f - 1998-07-20 13:50:00 -0000
|
||||||
[tzdata1998f.tar.gz is missing!]
|
[tzdata1998f.tar.gz is missing!]
|
||||||
|
|
||||||
Update the "leapseconds" file to include the newly-announced
|
Update the "leapseconds" file to include the newly announced
|
||||||
insertion at the end of 1998.
|
insertion at the end of 1998.
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,8 +52,18 @@ enum { STD_ASCTIME_BUF_SIZE = 26 };
|
|||||||
*/
|
*/
|
||||||
static char buf_asctime[2*3 + 5*INT_STRLEN_MAXIMUM(int) + 7 + 2 + 1 + 1];
|
static char buf_asctime[2*3 + 5*INT_STRLEN_MAXIMUM(int) + 7 + 2 + 1 + 1];
|
||||||
|
|
||||||
|
/* A similar buffer for ctime.
|
||||||
|
C89 requires that they be the same buffer.
|
||||||
|
This requirement was removed in C99, so support it only if requested,
|
||||||
|
as support is more likely to lead to bugs in badly written programs. */
|
||||||
|
#if SUPPORT_C89
|
||||||
|
# define buf_ctime buf_asctime
|
||||||
|
#else
|
||||||
|
static char buf_ctime[sizeof buf_asctime];
|
||||||
|
#endif
|
||||||
|
|
||||||
char *
|
char *
|
||||||
asctime_r(register const struct tm *timeptr, char *buf)
|
asctime_r(struct tm const *restrict timeptr, char *restrict buf)
|
||||||
{
|
{
|
||||||
static const char wday_name[][4] = {
|
static const char wday_name[][4] = {
|
||||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
||||||
@ -93,7 +103,8 @@ asctime_r(register const struct tm *timeptr, char *buf)
|
|||||||
timeptr->tm_mday, timeptr->tm_hour,
|
timeptr->tm_mday, timeptr->tm_hour,
|
||||||
timeptr->tm_min, timeptr->tm_sec,
|
timeptr->tm_min, timeptr->tm_sec,
|
||||||
year);
|
year);
|
||||||
if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime)
|
if (strlen(result) < STD_ASCTIME_BUF_SIZE
|
||||||
|
|| buf == buf_ctime || buf == buf_asctime)
|
||||||
return strcpy(buf, result);
|
return strcpy(buf, result);
|
||||||
else {
|
else {
|
||||||
errno = EOVERFLOW;
|
errno = EOVERFLOW;
|
||||||
@ -106,3 +117,17 @@ asctime(register const struct tm *timeptr)
|
|||||||
{
|
{
|
||||||
return asctime_r(timeptr, buf_asctime);
|
return asctime_r(timeptr, buf_asctime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ctime_r(const time_t *timep, char *buf)
|
||||||
|
{
|
||||||
|
struct tm mytm;
|
||||||
|
struct tm *tmp = localtime_r(timep, &mytm);
|
||||||
|
return tmp ? asctime_r(tmp, buf) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ctime(const time_t *timep)
|
||||||
|
{
|
||||||
|
return ctime_r(timep, buf_ctime);
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.\" This file is in the public domain, so clarified as of
|
.\" This file is in the public domain, so clarified as of
|
||||||
.\" 2009-05-17 by Arthur David Olson.
|
.\" 2009-05-17 by Arthur David Olson.
|
||||||
.TH date 1
|
.TH date 1 "" "Time Zone Database"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
date \- show and set date and time
|
date \- show and set date and time
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -156,7 +156,8 @@ hexadecimal (leading 0x), preceded by an optional sign.
|
|||||||
.br
|
.br
|
||||||
/usr/share/zoneinfo timezone information directory
|
/usr/share/zoneinfo timezone information directory
|
||||||
.br
|
.br
|
||||||
/usr/share/zoneinfo/posixrules used with POSIX-style TZ's
|
/usr/share/zoneinfo/posixrules default DST rules (obsolete,
|
||||||
|
and can cause bugs if present)
|
||||||
.br
|
.br
|
||||||
/usr/share/zoneinfo/GMT for UTC leap seconds
|
/usr/share/zoneinfo/GMT for UTC leap seconds
|
||||||
.sp
|
.sp
|
||||||
|
@ -42,7 +42,7 @@ static void display(const char *, time_t);
|
|||||||
static void dogmt(void);
|
static void dogmt(void);
|
||||||
static void errensure(void);
|
static void errensure(void);
|
||||||
static void timeout(FILE *, const char *, const struct tm *);
|
static void timeout(FILE *, const char *, const struct tm *);
|
||||||
static ATTRIBUTE_NORETURN void usage(void);
|
ATTRIBUTE_NORETURN static void usage(void);
|
||||||
|
|
||||||
int
|
int
|
||||||
main(const int argc, char *argv[])
|
main(const int argc, char *argv[])
|
||||||
@ -86,7 +86,9 @@ main(const int argc, char *argv[])
|
|||||||
else if (! (TIME_T_MIN <= secs && secs <= TIME_T_MAX))
|
else if (! (TIME_T_MIN <= secs && secs <= TIME_T_MAX))
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
if (errno) {
|
if (errno) {
|
||||||
perror(optarg);
|
char const *e = strerror(errno);
|
||||||
|
fprintf(stderr, _("date: %s: %s\n"),
|
||||||
|
optarg, e);
|
||||||
errensure();
|
errensure();
|
||||||
exit(retval);
|
exit(retval);
|
||||||
}
|
}
|
||||||
@ -124,10 +126,10 @@ dogmt(void)
|
|||||||
continue;
|
continue;
|
||||||
#if defined ckd_add && defined ckd_mul
|
#if defined ckd_add && defined ckd_mul
|
||||||
if (!ckd_add(&n, n, 2) && !ckd_mul(&n, n, sizeof *fakeenv)
|
if (!ckd_add(&n, n, 2) && !ckd_mul(&n, n, sizeof *fakeenv)
|
||||||
&& n <= SIZE_MAX)
|
&& n <= INDEX_MAX)
|
||||||
fakeenv = malloc(n);
|
fakeenv = malloc(n);
|
||||||
#else
|
#else
|
||||||
if (n <= min(PTRDIFF_MAX, SIZE_MAX) / sizeof *fakeenv - 2)
|
if (n <= INDEX_MAX / sizeof *fakeenv - 2)
|
||||||
fakeenv = malloc((n + 2) * sizeof *fakeenv);
|
fakeenv = malloc((n + 2) * sizeof *fakeenv);
|
||||||
#endif
|
#endif
|
||||||
if (fakeenv == NULL) {
|
if (fakeenv == NULL) {
|
||||||
@ -194,10 +196,9 @@ timeout(FILE *fp, char const *format, struct tm const *tmp)
|
|||||||
|
|
||||||
for ( ; ; ) {
|
for ( ; ; ) {
|
||||||
#ifdef ckd_mul
|
#ifdef ckd_mul
|
||||||
bool bigger = !ckd_mul(&size, size, 2) && size <= SIZE_MAX;
|
bool bigger = !ckd_mul(&size, size, 2) && size <= INDEX_MAX;
|
||||||
#else
|
#else
|
||||||
bool bigger = (size <= min(PTRDIFF_MAX, SIZE_MAX) / 2
|
bool bigger = size <= INDEX_MAX / 2 && (size *= 2, true);
|
||||||
&& (size *= 2, true));
|
|
||||||
#endif
|
#endif
|
||||||
char *newcp = bigger ? realloc(cp, size) : NULL;
|
char *newcp = bigger ? realloc(cp, size) : NULL;
|
||||||
if (!newcp) {
|
if (!newcp) {
|
||||||
|
@ -47,10 +47,6 @@ static int lock(void) { return 0; }
|
|||||||
static void unlock(void) { }
|
static void unlock(void) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TZ_ABBR_MAX_LEN
|
|
||||||
# define TZ_ABBR_MAX_LEN 16
|
|
||||||
#endif /* !defined TZ_ABBR_MAX_LEN */
|
|
||||||
|
|
||||||
#ifndef TZ_ABBR_CHAR_SET
|
#ifndef TZ_ABBR_CHAR_SET
|
||||||
# define TZ_ABBR_CHAR_SET \
|
# define TZ_ABBR_CHAR_SET \
|
||||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
|
||||||
@ -128,12 +124,11 @@ static char const UNSPEC[] = "-00";
|
|||||||
for ttunspecified to work without crashing. */
|
for ttunspecified to work without crashing. */
|
||||||
enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 };
|
enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 };
|
||||||
|
|
||||||
#ifdef TZNAME_MAX
|
/* Limit to time zone abbreviation length in POSIX-style TZ strings.
|
||||||
# define MY_TZNAME_MAX TZNAME_MAX
|
This is distinct from TZ_MAX_CHARS, which limits TZif file contents. */
|
||||||
#endif /* defined TZNAME_MAX */
|
#ifndef TZNAME_MAXIMUM
|
||||||
#ifndef TZNAME_MAX
|
# define TZNAME_MAXIMUM 255
|
||||||
# define MY_TZNAME_MAX 255
|
#endif
|
||||||
#endif /* !defined TZNAME_MAX */
|
|
||||||
|
|
||||||
struct state {
|
struct state {
|
||||||
int leapcnt;
|
int leapcnt;
|
||||||
@ -146,7 +141,7 @@ struct state {
|
|||||||
unsigned char types[TZ_MAX_TIMES];
|
unsigned char types[TZ_MAX_TIMES];
|
||||||
struct ttinfo ttis[TZ_MAX_TYPES];
|
struct ttinfo ttis[TZ_MAX_TYPES];
|
||||||
char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"),
|
char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"),
|
||||||
2 * (MY_TZNAME_MAX + 1))];
|
2 * (TZNAME_MAXIMUM + 1))];
|
||||||
struct lsinfo lsis[TZ_MAX_LEAPS];
|
struct lsinfo lsis[TZ_MAX_LEAPS];
|
||||||
|
|
||||||
/* The time type to use for early times or if no transitions.
|
/* The time type to use for early times or if no transitions.
|
||||||
@ -203,6 +198,9 @@ static pthread_once_t gmt_once = PTHREAD_ONCE_INIT;
|
|||||||
static pthread_once_t gmtime_once = PTHREAD_ONCE_INIT;
|
static pthread_once_t gmtime_once = PTHREAD_ONCE_INIT;
|
||||||
static pthread_key_t gmtime_key;
|
static pthread_key_t gmtime_key;
|
||||||
static int gmtime_key_error;
|
static int gmtime_key_error;
|
||||||
|
static pthread_once_t offtime_once = PTHREAD_ONCE_INIT;
|
||||||
|
static pthread_key_t offtime_key;
|
||||||
|
static int offtime_key_error;
|
||||||
static pthread_once_t localtime_once = PTHREAD_ONCE_INIT;
|
static pthread_once_t localtime_once = PTHREAD_ONCE_INIT;
|
||||||
static pthread_key_t localtime_key;
|
static pthread_key_t localtime_key;
|
||||||
static int localtime_key_error;
|
static int localtime_key_error;
|
||||||
@ -213,9 +211,14 @@ static int localtime_key_error;
|
|||||||
** ctime, gmtime, localtime] return values in one of two static
|
** ctime, gmtime, localtime] return values in one of two static
|
||||||
** objects: a broken-down time structure and an array of char.
|
** objects: a broken-down time structure and an array of char.
|
||||||
** Thanks to Paul Eggert for noting this.
|
** Thanks to Paul Eggert for noting this.
|
||||||
|
**
|
||||||
|
** This requirement was removed in C99, so support it only if requested,
|
||||||
|
** as support is more likely to lead to bugs in badly written programs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if SUPPORT_C89
|
||||||
static struct tm tm;
|
static struct tm tm;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 2 <= HAVE_TZNAME + TZ_TIME_T
|
#if 2 <= HAVE_TZNAME + TZ_TIME_T
|
||||||
char * tzname[2] = {
|
char * tzname[2] = {
|
||||||
@ -367,27 +370,28 @@ settzname(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* Replace bogus characters in time zone abbreviations.
|
||||||
|
Return 0 on success, an errno value if a time zone abbreviation is
|
||||||
|
too long. */
|
||||||
|
static int
|
||||||
scrub_abbrs(struct state *sp)
|
scrub_abbrs(struct state *sp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
/*
|
|
||||||
** First, replace bogus characters.
|
/* Reject overlong abbreviations. */
|
||||||
*/
|
for (i = 0; i < sp->charcnt - (TZNAME_MAXIMUM + 1); ) {
|
||||||
|
int len = strlen(&sp->chars[i]);
|
||||||
|
if (TZNAME_MAXIMUM < len)
|
||||||
|
return EOVERFLOW;
|
||||||
|
i += len + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Replace bogus characters. */
|
||||||
for (i = 0; i < sp->charcnt; ++i)
|
for (i = 0; i < sp->charcnt; ++i)
|
||||||
if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
|
if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
|
||||||
sp->chars[i] = TZ_ABBR_ERR_CHAR;
|
sp->chars[i] = TZ_ABBR_ERR_CHAR;
|
||||||
/*
|
|
||||||
** Second, truncate long abbreviations.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < sp->typecnt; ++i) {
|
|
||||||
register const struct ttinfo * const ttisp = &sp->ttis[i];
|
|
||||||
char *cp = &sp->chars[ttisp->tt_desigidx];
|
|
||||||
|
|
||||||
if (strlen(cp) > TZ_ABBR_MAX_LEN &&
|
return 0;
|
||||||
strcmp(cp, GRANDPARENTED) != 0)
|
|
||||||
*(cp + TZ_ABBR_MAX_LEN) = '\0';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DETECT_TZ_CHANGES
|
#ifdef DETECT_TZ_CHANGES
|
||||||
@ -898,7 +902,7 @@ is_digit(char c)
|
|||||||
** Return a pointer to that character.
|
** Return a pointer to that character.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static ATTRIBUTE_REPRODUCIBLE const char *
|
ATTRIBUTE_REPRODUCIBLE static const char *
|
||||||
getzname(register const char *strp)
|
getzname(register const char *strp)
|
||||||
{
|
{
|
||||||
register char c;
|
register char c;
|
||||||
@ -919,7 +923,7 @@ getzname(register const char *strp)
|
|||||||
** We don't do any checking here; checking is done later in common-case code.
|
** We don't do any checking here; checking is done later in common-case code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static ATTRIBUTE_REPRODUCIBLE const char *
|
ATTRIBUTE_REPRODUCIBLE static const char *
|
||||||
getqzname(register const char *strp, const int delim)
|
getqzname(register const char *strp, const int delim)
|
||||||
{
|
{
|
||||||
register int c;
|
register int c;
|
||||||
@ -1199,14 +1203,12 @@ tzparse(const char *name, struct state *sp, struct state *basep)
|
|||||||
name = getzname(name);
|
name = getzname(name);
|
||||||
stdlen = name - stdname;
|
stdlen = name - stdname;
|
||||||
}
|
}
|
||||||
if (!stdlen)
|
if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM))
|
||||||
return false;
|
return false;
|
||||||
name = getoffset(name, &stdoffset);
|
name = getoffset(name, &stdoffset);
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
return false;
|
return false;
|
||||||
charcnt = stdlen + 1;
|
charcnt = stdlen + 1;
|
||||||
if (sizeof sp->chars < charcnt)
|
|
||||||
return false;
|
|
||||||
if (basep) {
|
if (basep) {
|
||||||
if (0 < basep->timecnt)
|
if (0 < basep->timecnt)
|
||||||
atlo = basep->ats[basep->timecnt - 1];
|
atlo = basep->ats[basep->timecnt - 1];
|
||||||
@ -1233,11 +1235,9 @@ tzparse(const char *name, struct state *sp, struct state *basep)
|
|||||||
name = getzname(name);
|
name = getzname(name);
|
||||||
dstlen = name - dstname; /* length of DST abbr. */
|
dstlen = name - dstname; /* length of DST abbr. */
|
||||||
}
|
}
|
||||||
if (!dstlen)
|
if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM))
|
||||||
return false;
|
return false;
|
||||||
charcnt += dstlen + 1;
|
charcnt += dstlen + 1;
|
||||||
if (sizeof sp->chars < charcnt)
|
|
||||||
return false;
|
|
||||||
if (*name != '\0' && *name != ',' && *name != ';') {
|
if (*name != '\0' && *name != ',' && *name != ';') {
|
||||||
name = getoffset(name, &dstoffset);
|
name = getoffset(name, &dstoffset);
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
@ -1511,7 +1511,7 @@ zoneinit(struct state *sp, char const *name)
|
|||||||
if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL))
|
if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL))
|
||||||
err = 0;
|
err = 0;
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
scrub_abbrs(sp);
|
err = scrub_abbrs(sp);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1732,7 +1732,8 @@ localsub(struct state const *sp, time_t const *timep, int_fast32_t setname,
|
|||||||
#if NETBSD_INSPIRED
|
#if NETBSD_INSPIRED
|
||||||
|
|
||||||
struct tm *
|
struct tm *
|
||||||
localtime_rz(struct state *sp, time_t const *timep, struct tm *tmp)
|
localtime_rz(struct state *restrict sp, time_t const *restrict timep,
|
||||||
|
struct tm *restrict tmp)
|
||||||
{
|
{
|
||||||
return localsub(sp, timep, 0, tmp);
|
return localsub(sp, timep, 0, tmp);
|
||||||
}
|
}
|
||||||
@ -1766,6 +1767,9 @@ localtime_key_init(void)
|
|||||||
struct tm *
|
struct tm *
|
||||||
localtime(const time_t *timep)
|
localtime(const time_t *timep)
|
||||||
{
|
{
|
||||||
|
#if !SUPPORT_C89
|
||||||
|
static struct tm tm;
|
||||||
|
#endif
|
||||||
struct tm *p_tm = &tm;
|
struct tm *p_tm = &tm;
|
||||||
|
|
||||||
if (__isthreaded != 0) {
|
if (__isthreaded != 0) {
|
||||||
@ -1788,7 +1792,7 @@ localtime(const time_t *timep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct tm *
|
struct tm *
|
||||||
localtime_r(const time_t *timep, struct tm *tmp)
|
localtime_r(const time_t *restrict timep, struct tm *restrict tmp)
|
||||||
{
|
{
|
||||||
return localtime_tzset(timep, tmp, false);
|
return localtime_tzset(timep, tmp, false);
|
||||||
}
|
}
|
||||||
@ -1821,7 +1825,7 @@ gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct tm *
|
struct tm *
|
||||||
gmtime_r(const time_t *timep, struct tm *tmp)
|
gmtime_r(time_t const *restrict timep, struct tm *restrict tmp)
|
||||||
{
|
{
|
||||||
_once(&gmt_once, gmtcheck);
|
_once(&gmt_once, gmtcheck);
|
||||||
return gmtsub(gmtptr, timep, 0, tmp);
|
return gmtsub(gmtptr, timep, 0, tmp);
|
||||||
@ -1837,6 +1841,9 @@ gmtime_key_init(void)
|
|||||||
struct tm *
|
struct tm *
|
||||||
gmtime(const time_t *timep)
|
gmtime(const time_t *timep)
|
||||||
{
|
{
|
||||||
|
#if !SUPPORT_C89
|
||||||
|
static struct tm tm;
|
||||||
|
#endif
|
||||||
struct tm *p_tm = &tm;
|
struct tm *p_tm = &tm;
|
||||||
|
|
||||||
if (__isthreaded != 0) {
|
if (__isthreaded != 0) {
|
||||||
@ -1858,16 +1865,50 @@ gmtime(const time_t *timep)
|
|||||||
return gmtime_r(timep, p_tm);
|
return gmtime_r(timep, p_tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STD_INSPIRED
|
#if STD_INSPIRED
|
||||||
|
|
||||||
|
struct tm *
|
||||||
|
offtime_r(time_t const *restrict timep, long offset, struct tm *restrict tmp)
|
||||||
|
{
|
||||||
|
_once(&gmt_once, gmtcheck);
|
||||||
|
return gmtsub(gmtptr, timep, offset, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
offtime_key_init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
offtime_key_error = _pthread_key_create(&offtime_key, free);
|
||||||
|
}
|
||||||
|
|
||||||
struct tm *
|
struct tm *
|
||||||
offtime(const time_t *timep, long offset)
|
offtime(const time_t *timep, long offset)
|
||||||
{
|
{
|
||||||
_once(&gmt_once, gmtcheck);
|
#if !SUPPORT_C89
|
||||||
return gmtsub(gmtptr, timep, offset, &tm);
|
static struct tm tm;
|
||||||
|
#endif
|
||||||
|
struct tm *p_tm = &tm;
|
||||||
|
|
||||||
|
if (__isthreaded != 0) {
|
||||||
|
_pthread_once(&offtime_once, offtime_key_init);
|
||||||
|
if (offtime_key_error != 0) {
|
||||||
|
errno = offtime_key_error;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if ((p_tm = _pthread_getspecific(offtime_key)) == NULL) {
|
||||||
|
if ((p_tm = malloc(sizeof(*p_tm))) == NULL) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if (_pthread_setspecific(offtime_key, p_tm) != 0) {
|
||||||
|
free(p_tm);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return offtime_r(timep, offset, p_tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* defined STD_INSPIRED */
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the number of leap years through the end of the given year
|
** Return the number of leap years through the end of the given year
|
||||||
@ -2003,27 +2044,6 @@ timesub(const time_t *timep, int_fast32_t offset,
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
|
||||||
ctime(const time_t *timep)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
** Section 4.12.3.2 of X3.159-1989 requires that
|
|
||||||
** The ctime function converts the calendar time pointed to by timer
|
|
||||||
** to local time in the form of a string. It is equivalent to
|
|
||||||
** asctime(localtime(timer))
|
|
||||||
*/
|
|
||||||
struct tm *tmp = localtime(timep);
|
|
||||||
return tmp ? asctime(tmp) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
ctime_r(const time_t *timep, char *buf)
|
|
||||||
{
|
|
||||||
struct tm mytm;
|
|
||||||
struct tm *tmp = localtime_r(timep, &mytm);
|
|
||||||
return tmp ? asctime_r(tmp, buf) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Adapted from code provided by Robert Elz, who writes:
|
** Adapted from code provided by Robert Elz, who writes:
|
||||||
** The "best" way to do mktime I think is based on an idea of Bob
|
** The "best" way to do mktime I think is based on an idea of Bob
|
||||||
@ -2465,7 +2485,7 @@ mktime_tzname(struct state *sp, struct tm *tmp, bool setname)
|
|||||||
#if NETBSD_INSPIRED
|
#if NETBSD_INSPIRED
|
||||||
|
|
||||||
time_t
|
time_t
|
||||||
mktime_z(struct state *sp, struct tm *tmp)
|
mktime_z(struct state *restrict sp, struct tm *restrict tmp)
|
||||||
{
|
{
|
||||||
return mktime_tzname(sp, tmp, false);
|
return mktime_tzname(sp, tmp, false);
|
||||||
}
|
}
|
||||||
@ -2487,7 +2507,7 @@ mktime(struct tm *tmp)
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STD_INSPIRED
|
#if STD_INSPIRED
|
||||||
time_t
|
time_t
|
||||||
timelocal(struct tm *tmp)
|
timelocal(struct tm *tmp)
|
||||||
{
|
{
|
||||||
@ -2539,7 +2559,7 @@ leapcorr(struct state const *sp, time_t t)
|
|||||||
** XXX--is the below the right way to conditionalize??
|
** XXX--is the below the right way to conditionalize??
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef STD_INSPIRED
|
#if STD_INSPIRED
|
||||||
|
|
||||||
/* NETBSD_INSPIRED_EXTERN functions are exported to callers if
|
/* NETBSD_INSPIRED_EXTERN functions are exported to callers if
|
||||||
NETBSD_INSPIRED is defined, and are private otherwise. */
|
NETBSD_INSPIRED is defined, and are private otherwise. */
|
||||||
@ -2628,7 +2648,7 @@ posix2time(time_t t)
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* defined STD_INSPIRED */
|
#endif /* STD_INSPIRED */
|
||||||
|
|
||||||
#if TZ_TIME_T
|
#if TZ_TIME_T
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.\" This file is in the public domain, so clarified as of
|
.\" This file is in the public domain, so clarified as of
|
||||||
.\" 2009-05-17 by Arthur David Olson.
|
.\" 2009-05-17 by Arthur David Olson.
|
||||||
.TH NEWCTIME 3
|
.TH newctime 3 "" "Time Zone Database"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
|
asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -11,13 +11,13 @@ asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
|
|||||||
.PP
|
.PP
|
||||||
.BR "extern char *tzname[];" " /\(** (optional) \(**/"
|
.BR "extern char *tzname[];" " /\(** (optional) \(**/"
|
||||||
.PP
|
.PP
|
||||||
.B char *ctime(time_t const *clock);
|
.B [[deprecated]] char *ctime(time_t const *clock);
|
||||||
.PP
|
.PP
|
||||||
.B char *ctime_r(time_t const *clock, char *buf);
|
.B char *ctime_r(time_t const *clock, char *buf);
|
||||||
.PP
|
.PP
|
||||||
.B double difftime(time_t time1, time_t time0);
|
.B double difftime(time_t time1, time_t time0);
|
||||||
.PP
|
.PP
|
||||||
.B char *asctime(struct tm const *tm);
|
.B [[deprecated]] char *asctime(struct tm const *tm);
|
||||||
.PP
|
.PP
|
||||||
.B "char *asctime_r(struct tm const *restrict tm,"
|
.B "char *asctime_r(struct tm const *restrict tm,"
|
||||||
.B " char *restrict result);"
|
.B " char *restrict result);"
|
||||||
@ -91,6 +91,15 @@ introduction of UTC and are some other flavor of Universal Time (UT).
|
|||||||
Some implementations support leap seconds, in contradiction to POSIX.
|
Some implementations support leap seconds, in contradiction to POSIX.
|
||||||
.PP
|
.PP
|
||||||
The
|
The
|
||||||
|
.B ctime
|
||||||
|
function is deprecated starting in C23.
|
||||||
|
Callers can use
|
||||||
|
.B localtime_r
|
||||||
|
and
|
||||||
|
.B strftime
|
||||||
|
instead.
|
||||||
|
.PP
|
||||||
|
The
|
||||||
.B localtime
|
.B localtime
|
||||||
and
|
and
|
||||||
.B gmtime
|
.B gmtime
|
||||||
@ -128,6 +137,10 @@ converts a time value contained in a
|
|||||||
structure to a string,
|
structure to a string,
|
||||||
as shown in the above example,
|
as shown in the above example,
|
||||||
and returns a pointer to the string.
|
and returns a pointer to the string.
|
||||||
|
This function is deprecated starting in C23.
|
||||||
|
Callers can use
|
||||||
|
.B strftime
|
||||||
|
instead.
|
||||||
.PP
|
.PP
|
||||||
The
|
The
|
||||||
.B mktime
|
.B mktime
|
||||||
@ -283,7 +296,8 @@ continue to exist in this form in future releases of this code.
|
|||||||
.br
|
.br
|
||||||
/usr/share/zoneinfo/localtime local timezone file
|
/usr/share/zoneinfo/localtime local timezone file
|
||||||
.br
|
.br
|
||||||
/usr/share/zoneinfo/posixrules used with POSIX-style TZ's
|
/usr/share/zoneinfo/posixrules default DST rules (obsolete,
|
||||||
|
and can cause bugs if present)
|
||||||
.br
|
.br
|
||||||
/usr/share/zoneinfo/GMT for UTC leap seconds
|
/usr/share/zoneinfo/GMT for UTC leap seconds
|
||||||
.sp
|
.sp
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
.\" from: @(#)strftime.3 5.12 (Berkeley) 6/29/91
|
.\" from: @(#)strftime.3 5.12 (Berkeley) 6/29/91
|
||||||
.\" $Id: strftime.3,v 1.4 1993/12/15 20:33:00 jtc Exp $
|
.\" $Id: strftime.3,v 1.4 1993/12/15 20:33:00 jtc Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH NEWSTRFTIME 3
|
.TH newstrftime 3 "" "Time Zone Database"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
strftime \- format date and time
|
strftime \- format date and time
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.\" This file is in the public domain, so clarified as of
|
.\" This file is in the public domain, so clarified as of
|
||||||
.\" 2009-05-17 by Arthur David Olson.
|
.\" 2009-05-17 by Arthur David Olson.
|
||||||
.TH NEWTZSET 3
|
.TH newtzset 3 "" "Time Zone Database"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
tzset \- initialize time conversion information
|
tzset \- initialize time conversion information
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -333,7 +333,8 @@ from the rest of the specification.
|
|||||||
.br
|
.br
|
||||||
/usr/share/zoneinfo/localtime local timezone file
|
/usr/share/zoneinfo/localtime local timezone file
|
||||||
.br
|
.br
|
||||||
/usr/share/zoneinfo/posixrules used with POSIX-style TZ
|
/usr/share/zoneinfo/posixrules default DST rules (obsolete,
|
||||||
|
and can cause bugs if present)
|
||||||
.br
|
.br
|
||||||
/usr/share/zoneinfo/GMT for UTC leap seconds
|
/usr/share/zoneinfo/GMT for UTC leap seconds
|
||||||
.sp
|
.sp
|
||||||
|
@ -17,12 +17,25 @@
|
|||||||
** Thank you!
|
** Thank you!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* PORT_TO_C89 means the code should work even if the underlying
|
||||||
|
compiler and library support only 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,
|
||||||
|
and the plan is to remove them along with any code needed only when
|
||||||
|
they are nonzero. */
|
||||||
|
#ifndef PORT_TO_C89
|
||||||
|
# define PORT_TO_C89 0
|
||||||
|
#endif
|
||||||
|
#ifndef SUPPORT_C89
|
||||||
|
# define SUPPORT_C89 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef __STDC_VERSION__
|
#ifndef __STDC_VERSION__
|
||||||
# define __STDC_VERSION__ 0
|
# define __STDC_VERSION__ 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Define true, false and bool if they don't work out of the box. */
|
/* Define true, false and bool if they don't work out of the box. */
|
||||||
#if __STDC_VERSION__ < 199901
|
#if PORT_TO_C89 && __STDC_VERSION__ < 199901
|
||||||
# define true 1
|
# define true 1
|
||||||
# define false 0
|
# define false 0
|
||||||
# define bool int
|
# define bool int
|
||||||
@ -30,6 +43,10 @@
|
|||||||
# include <stdbool.h>
|
# include <stdbool.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __STDC_VERSION__ < 202311
|
||||||
|
# define static_assert(cond) extern int static_assert_check[(cond) ? 1 : -1]
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** zdump has been made independent of the rest of the time
|
** zdump has been made independent of the rest of the time
|
||||||
** conversion package to increase confidence in the verification it provides.
|
** conversion package to increase confidence in the verification it provides.
|
||||||
@ -52,19 +69,19 @@
|
|||||||
# define HAVE_DECL_ASCTIME_R 1
|
# define HAVE_DECL_ASCTIME_R 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined HAVE_GENERIC && defined __has_extension
|
#if !defined HAVE__GENERIC && defined __has_extension
|
||||||
# if __has_extension(c_generic_selections)
|
# if __has_extension(c_generic_selections)
|
||||||
# define HAVE_GENERIC 1
|
# define HAVE__GENERIC 1
|
||||||
# else
|
# else
|
||||||
# define HAVE_GENERIC 0
|
# define HAVE__GENERIC 0
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
/* _Generic is buggy in pre-4.9 GCC. */
|
/* _Generic is buggy in pre-4.9 GCC. */
|
||||||
#if !defined HAVE_GENERIC && defined __GNUC__ && !defined __STRICT_ANSI__
|
#if !defined HAVE__GENERIC && defined __GNUC__ && !defined __STRICT_ANSI__
|
||||||
# define HAVE_GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
|
# define HAVE__GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_GENERIC
|
#ifndef HAVE__GENERIC
|
||||||
# define HAVE_GENERIC (201112 <= __STDC_VERSION__)
|
# define HAVE__GENERIC (201112 <= __STDC_VERSION__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined HAVE_GETTEXT && defined __has_include
|
#if !defined HAVE_GETTEXT && defined __has_include
|
||||||
@ -100,10 +117,6 @@
|
|||||||
# define HAVE_STRDUP 1
|
# define HAVE_STRDUP 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_STRTOLL
|
|
||||||
# define HAVE_STRTOLL 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_SYMLINK
|
#ifndef HAVE_SYMLINK
|
||||||
# define HAVE_SYMLINK 1
|
# define HAVE_SYMLINK 1
|
||||||
#endif /* !defined HAVE_SYMLINK */
|
#endif /* !defined HAVE_SYMLINK */
|
||||||
@ -185,6 +198,9 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#if !PORT_TO_C89
|
||||||
|
# include <inttypes.h>
|
||||||
|
#endif
|
||||||
#include <limits.h> /* for CHAR_BIT et al. */
|
#include <limits.h> /* for CHAR_BIT et al. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -254,10 +270,12 @@
|
|||||||
# define R_OK 4
|
# define R_OK 4
|
||||||
#endif /* !defined R_OK */
|
#endif /* !defined R_OK */
|
||||||
|
|
||||||
|
#if PORT_TO_C89
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Define HAVE_STDINT_H's default value here, rather than at the
|
** Define HAVE_STDINT_H's default value here, rather than at the
|
||||||
** start, since __GLIBC__ and INTMAX_MAX's values depend on
|
** start, since __GLIBC__ and INTMAX_MAX's values depend on
|
||||||
** previously-included files. glibc 2.1 and Solaris 10 and later have
|
** previously included files. glibc 2.1 and Solaris 10 and later have
|
||||||
** stdint.h, even with pre-C99 compilers.
|
** stdint.h, even with pre-C99 compilers.
|
||||||
*/
|
*/
|
||||||
#if !defined HAVE_STDINT_H && defined __has_include
|
#if !defined HAVE_STDINT_H && defined __has_include
|
||||||
@ -334,6 +352,9 @@ typedef int int_fast32_t;
|
|||||||
#ifndef INTMAX_MAX
|
#ifndef INTMAX_MAX
|
||||||
# ifdef LLONG_MAX
|
# ifdef LLONG_MAX
|
||||||
typedef long long intmax_t;
|
typedef long long intmax_t;
|
||||||
|
# ifndef HAVE_STRTOLL
|
||||||
|
# define HAVE_STRTOLL true
|
||||||
|
# endif
|
||||||
# if HAVE_STRTOLL
|
# if HAVE_STRTOLL
|
||||||
# define strtoimax strtoll
|
# define strtoimax strtoll
|
||||||
# endif
|
# endif
|
||||||
@ -379,8 +400,10 @@ typedef unsigned long long uint_fast64_t;
|
|||||||
#ifndef UINTMAX_MAX
|
#ifndef UINTMAX_MAX
|
||||||
# ifdef ULLONG_MAX
|
# ifdef ULLONG_MAX
|
||||||
typedef unsigned long long uintmax_t;
|
typedef unsigned long long uintmax_t;
|
||||||
|
# define UINTMAX_MAX ULLONG_MAX
|
||||||
# else
|
# else
|
||||||
typedef unsigned long uintmax_t;
|
typedef unsigned long uintmax_t;
|
||||||
|
# define UINTMAX_MAX ULONG_MAX
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -396,6 +419,16 @@ typedef unsigned long uintmax_t;
|
|||||||
# define SIZE_MAX ((size_t) -1)
|
# define SIZE_MAX ((size_t) -1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORT_TO_C89 */
|
||||||
|
|
||||||
|
/* The maximum size of any created object, as a signed integer.
|
||||||
|
Although the C standard does not outright prohibit larger objects,
|
||||||
|
behavior is undefined if the result of pointer subtraction does not
|
||||||
|
fit into ptrdiff_t, and the code assumes in several places that
|
||||||
|
pointer subtraction works. As a practical matter it's OK to not
|
||||||
|
support objects larger than this. */
|
||||||
|
#define INDEX_MAX ((ptrdiff_t) min(PTRDIFF_MAX, SIZE_MAX))
|
||||||
|
|
||||||
/* Support ckd_add, ckd_sub, ckd_mul on C23 or recent-enough GCC-like
|
/* Support ckd_add, ckd_sub, ckd_mul on C23 or recent-enough GCC-like
|
||||||
hosts, unless compiled with -DHAVE_STDCKDINT_H=0 or with pre-C23 EDG. */
|
hosts, unless compiled with -DHAVE_STDCKDINT_H=0 or with pre-C23 EDG. */
|
||||||
#if !defined HAVE_STDCKDINT_H && defined __has_include
|
#if !defined HAVE_STDCKDINT_H && defined __has_include
|
||||||
@ -435,12 +468,25 @@ typedef unsigned long uintmax_t;
|
|||||||
|
|
||||||
#if (defined __has_c_attribute \
|
#if (defined __has_c_attribute \
|
||||||
&& (202311 <= __STDC_VERSION__ || !defined __STRICT_ANSI__))
|
&& (202311 <= __STDC_VERSION__ || !defined __STRICT_ANSI__))
|
||||||
# define HAVE_HAS_C_ATTRIBUTE true
|
# define HAVE___HAS_C_ATTRIBUTE true
|
||||||
#else
|
#else
|
||||||
# define HAVE_HAS_C_ATTRIBUTE false
|
# define HAVE___HAS_C_ATTRIBUTE false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_HAS_C_ATTRIBUTE
|
#if HAVE___HAS_C_ATTRIBUTE
|
||||||
|
# if __has_c_attribute(deprecated)
|
||||||
|
# define ATTRIBUTE_DEPRECATED [[deprecated]]
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#ifndef ATTRIBUTE_DEPRECATED
|
||||||
|
# if 3 < __GNUC__ + (2 <= __GNUC_MINOR__)
|
||||||
|
# define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_DEPRECATED /* empty */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE___HAS_C_ATTRIBUTE
|
||||||
# if __has_c_attribute(fallthrough)
|
# if __has_c_attribute(fallthrough)
|
||||||
# define ATTRIBUTE_FALLTHROUGH [[fallthrough]]
|
# define ATTRIBUTE_FALLTHROUGH [[fallthrough]]
|
||||||
# endif
|
# endif
|
||||||
@ -453,7 +499,7 @@ typedef unsigned long uintmax_t;
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_HAS_C_ATTRIBUTE
|
#if HAVE___HAS_C_ATTRIBUTE
|
||||||
# if __has_c_attribute(maybe_unused)
|
# if __has_c_attribute(maybe_unused)
|
||||||
# define ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]]
|
# define ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]]
|
||||||
# endif
|
# endif
|
||||||
@ -466,7 +512,7 @@ typedef unsigned long uintmax_t;
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_HAS_C_ATTRIBUTE
|
#if HAVE___HAS_C_ATTRIBUTE
|
||||||
# if __has_c_attribute(noreturn)
|
# if __has_c_attribute(noreturn)
|
||||||
# define ATTRIBUTE_NORETURN [[noreturn]]
|
# define ATTRIBUTE_NORETURN [[noreturn]]
|
||||||
# endif
|
# endif
|
||||||
@ -481,7 +527,7 @@ typedef unsigned long uintmax_t;
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_HAS_C_ATTRIBUTE
|
#if HAVE___HAS_C_ATTRIBUTE
|
||||||
# if __has_c_attribute(reproducible)
|
# if __has_c_attribute(reproducible)
|
||||||
# define ATTRIBUTE_REPRODUCIBLE [[reproducible]]
|
# define ATTRIBUTE_REPRODUCIBLE [[reproducible]]
|
||||||
# endif
|
# endif
|
||||||
@ -494,7 +540,7 @@ typedef unsigned long uintmax_t;
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_HAS_C_ATTRIBUTE
|
#if HAVE___HAS_C_ATTRIBUTE
|
||||||
# if __has_c_attribute(unsequenced)
|
# if __has_c_attribute(unsequenced)
|
||||||
# define ATTRIBUTE_UNSEQUENCED [[unsequenced]]
|
# define ATTRIBUTE_UNSEQUENCED [[unsequenced]]
|
||||||
# endif
|
# endif
|
||||||
@ -507,7 +553,8 @@ typedef unsigned long uintmax_t;
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __STDC_VERSION__ < 199901 && !defined restrict
|
#if (__STDC_VERSION__ < 199901 && !defined restrict \
|
||||||
|
&& (PORT_TO_C89 || defined _MSC_VER))
|
||||||
# define restrict /* empty */
|
# define restrict /* empty */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -579,6 +626,8 @@ typedef time_tz tz_time_t;
|
|||||||
# define mktime_z tz_mktime_z
|
# define mktime_z tz_mktime_z
|
||||||
# undef offtime
|
# undef offtime
|
||||||
# define offtime tz_offtime
|
# define offtime tz_offtime
|
||||||
|
# undef offtime_r
|
||||||
|
# define offtime_r tz_offtime_r
|
||||||
# undef posix2time
|
# undef posix2time
|
||||||
# define posix2time tz_posix2time
|
# define posix2time tz_posix2time
|
||||||
# undef posix2time_z
|
# undef posix2time_z
|
||||||
@ -624,11 +673,16 @@ typedef time_tz tz_time_t;
|
|||||||
# define altzone tz_altzone
|
# define altzone tz_altzone
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
char *asctime(struct tm const *);
|
# if __STDC_VERSION__ < 202311
|
||||||
|
# define DEPRECATED_IN_C23 /* empty */
|
||||||
|
# else
|
||||||
|
# define DEPRECATED_IN_C23 ATTRIBUTE_DEPRECATED
|
||||||
|
# endif
|
||||||
|
DEPRECATED_IN_C23 char *asctime(struct tm const *);
|
||||||
char *asctime_r(struct tm const *restrict, char *restrict);
|
char *asctime_r(struct tm const *restrict, char *restrict);
|
||||||
char *ctime(time_t const *);
|
DEPRECATED_IN_C23 char *ctime(time_t const *);
|
||||||
char *ctime_r(time_t const *, char *);
|
char *ctime_r(time_t const *, char *);
|
||||||
double difftime(time_t, time_t) ATTRIBUTE_UNSEQUENCED;
|
ATTRIBUTE_UNSEQUENCED double difftime(time_t, time_t);
|
||||||
size_t strftime(char *restrict, size_t, char const *restrict,
|
size_t strftime(char *restrict, size_t, char const *restrict,
|
||||||
struct tm const *restrict);
|
struct tm const *restrict);
|
||||||
# if HAVE_STRFTIME_L
|
# if HAVE_STRFTIME_L
|
||||||
@ -691,10 +745,16 @@ extern long altzone;
|
|||||||
** declarations if time_tz is defined.
|
** declarations if time_tz is defined.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef STD_INSPIRED
|
#ifndef STD_INSPIRED
|
||||||
|
# define STD_INSPIRED 0
|
||||||
|
#endif
|
||||||
|
#if STD_INSPIRED
|
||||||
# if TZ_TIME_T || !defined offtime
|
# if TZ_TIME_T || !defined offtime
|
||||||
struct tm *offtime(time_t const *, long);
|
struct tm *offtime(time_t const *, long);
|
||||||
# endif
|
# endif
|
||||||
|
# if TZ_TIME_T || !defined offtime_r
|
||||||
|
struct tm *offtime_r(time_t const *, long, struct tm *);
|
||||||
|
# endif
|
||||||
# if TZ_TIME_T || !defined timelocal
|
# if TZ_TIME_T || !defined timelocal
|
||||||
time_t timelocal(struct tm *);
|
time_t timelocal(struct tm *);
|
||||||
# endif
|
# endif
|
||||||
@ -738,12 +798,12 @@ struct tm *localtime_rz(timezone_t restrict, time_t const *restrict,
|
|||||||
time_t mktime_z(timezone_t restrict, struct tm *restrict);
|
time_t mktime_z(timezone_t restrict, struct tm *restrict);
|
||||||
timezone_t tzalloc(char const *);
|
timezone_t tzalloc(char const *);
|
||||||
void tzfree(timezone_t);
|
void tzfree(timezone_t);
|
||||||
# ifdef STD_INSPIRED
|
# if STD_INSPIRED
|
||||||
# if TZ_TIME_T || !defined posix2time_z
|
# if TZ_TIME_T || !defined posix2time_z
|
||||||
time_t posix2time_z(timezone_t, time_t) ATTRIBUTE_REPRODUCIBLE;
|
ATTRIBUTE_REPRODUCIBLE time_t posix2time_z(timezone_t, time_t);
|
||||||
# endif
|
# endif
|
||||||
# if TZ_TIME_T || !defined time2posix_z
|
# if TZ_TIME_T || !defined time2posix_z
|
||||||
time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_REPRODUCIBLE;
|
ATTRIBUTE_REPRODUCIBLE time_t time2posix_z(timezone_t, time_t);
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
@ -752,7 +812,7 @@ time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_REPRODUCIBLE;
|
|||||||
** Finally, some convenience items.
|
** Finally, some convenience items.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define TYPE_BIT(type) (sizeof(type) * CHAR_BIT)
|
#define TYPE_BIT(type) (CHAR_BIT * (ptrdiff_t) sizeof(type))
|
||||||
#define TYPE_SIGNED(type) (((type) -1) < 0)
|
#define TYPE_SIGNED(type) (((type) -1) < 0)
|
||||||
#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
|
#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
|
||||||
|
|
||||||
@ -780,7 +840,7 @@ time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_REPRODUCIBLE;
|
|||||||
This implementation assumes no padding if time_t is signed and
|
This implementation assumes no padding if time_t is signed and
|
||||||
either the compiler lacks support for _Generic or time_t is not one
|
either the compiler lacks support for _Generic or time_t is not one
|
||||||
of the standard signed integer types. */
|
of the standard signed integer types. */
|
||||||
#if HAVE_GENERIC
|
#if HAVE__GENERIC
|
||||||
# define TIME_T_MIN \
|
# define TIME_T_MIN \
|
||||||
_Generic((time_t) 0, \
|
_Generic((time_t) 0, \
|
||||||
signed char: SCHAR_MIN, short: SHRT_MIN, \
|
signed char: SCHAR_MIN, short: SHRT_MIN, \
|
||||||
@ -793,10 +853,23 @@ time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_REPRODUCIBLE;
|
|||||||
int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \
|
int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \
|
||||||
default: TIME_T_MAX_NO_PADDING) \
|
default: TIME_T_MAX_NO_PADDING) \
|
||||||
: (time_t) -1)
|
: (time_t) -1)
|
||||||
|
enum { SIGNED_PADDING_CHECK_NEEDED
|
||||||
|
= _Generic((time_t) 0,
|
||||||
|
signed char: false, short: false,
|
||||||
|
int: false, long: false, long long: false,
|
||||||
|
default: true) };
|
||||||
#else
|
#else
|
||||||
# define TIME_T_MIN TIME_T_MIN_NO_PADDING
|
# define TIME_T_MIN TIME_T_MIN_NO_PADDING
|
||||||
# define TIME_T_MAX TIME_T_MAX_NO_PADDING
|
# define TIME_T_MAX TIME_T_MAX_NO_PADDING
|
||||||
|
enum { SIGNED_PADDING_CHECK_NEEDED = true };
|
||||||
#endif
|
#endif
|
||||||
|
/* Try to check the padding assumptions. Although TIME_T_MAX and the
|
||||||
|
following check can both have undefined behavior on oddball
|
||||||
|
platforms due to shifts exceeding widths of signed integers, these
|
||||||
|
platforms' compilers are likely to diagnose these issues in integer
|
||||||
|
constant expressions, so it shouldn't hurt to check statically. */
|
||||||
|
static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED
|
||||||
|
|| TIME_T_MAX >> (TYPE_BIT(time_t) - 2) == 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** 302 / 1000 is log10(2.0) rounded up.
|
** 302 / 1000 is log10(2.0) rounded up.
|
||||||
@ -863,7 +936,7 @@ time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_REPRODUCIBLE;
|
|||||||
#if HAVE_INCOMPATIBLE_CTIME_R
|
#if HAVE_INCOMPATIBLE_CTIME_R
|
||||||
#undef asctime_r
|
#undef asctime_r
|
||||||
#undef ctime_r
|
#undef ctime_r
|
||||||
char *asctime_r(struct tm const *, char *);
|
char *asctime_r(struct tm const *restrict, char *restrict);
|
||||||
char *ctime_r(time_t const *, char *);
|
char *ctime_r(time_t const *, char *);
|
||||||
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
||||||
|
|
||||||
|
@ -116,7 +116,8 @@ static char * _yconv(int, int, bool, bool, char *, char const *);
|
|||||||
|
|
||||||
#if HAVE_STRFTIME_L
|
#if HAVE_STRFTIME_L
|
||||||
size_t
|
size_t
|
||||||
strftime_l(char *s, size_t maxsize, char const *format, struct tm const *t,
|
strftime_l(char *restrict s, size_t maxsize, char const *restrict format,
|
||||||
|
struct tm const *restrict t,
|
||||||
ATTRIBUTE_MAYBE_UNUSED locale_t locale)
|
ATTRIBUTE_MAYBE_UNUSED locale_t locale)
|
||||||
{
|
{
|
||||||
/* Just call strftime, as only the C locale is supported. */
|
/* Just call strftime, as only the C locale is supported. */
|
||||||
@ -125,7 +126,8 @@ strftime_l(char *s, size_t maxsize, char const *format, struct tm const *t,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
strftime(char *s, size_t maxsize, const char *format, const struct tm *t)
|
strftime(char *restrict s, size_t maxsize, char const *restrict format,
|
||||||
|
struct tm const *restrict t)
|
||||||
{
|
{
|
||||||
char * p;
|
char * p;
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<li><a href="#stability">Interface stability</a></li>
|
<li><a href="#stability">Interface stability</a></li>
|
||||||
<li><a href="#leapsec">Leap seconds</a></li>
|
<li><a href="#leapsec">Leap seconds</a></li>
|
||||||
<li><a href="#calendar">Calendrical issues</a></li>
|
<li><a href="#calendar">Calendrical issues</a></li>
|
||||||
<li><a href="#planets">Time and time zones on other planets</a></li>
|
<li><a href="#planets">Time and time zones off earth</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
@ -443,11 +443,11 @@ in decreasing order of importance:
|
|||||||
CAT/CAST Central Africa,
|
CAT/CAST Central Africa,
|
||||||
CET/CEST/CEMT Central European,
|
CET/CEST/CEMT Central European,
|
||||||
ChST Chamorro,
|
ChST Chamorro,
|
||||||
CST/CDT/CWT/CPT/CDDT Central [North America],
|
CST/CDT/CWT/CPT Central [North America],
|
||||||
CST/CDT China,
|
CST/CDT China,
|
||||||
GMT/BST/IST/BDST Greenwich,
|
GMT/BST/IST/BDST Greenwich,
|
||||||
EAT East Africa,
|
EAT East Africa,
|
||||||
EST/EDT/EWT/EPT/EDDT Eastern [North America],
|
EST/EDT/EWT/EPT Eastern [North America],
|
||||||
EET/EEST Eastern European,
|
EET/EEST Eastern European,
|
||||||
GST/GDT Guam,
|
GST/GDT Guam,
|
||||||
HST/HDT/HWT/HPT Hawaii,
|
HST/HDT/HWT/HPT Hawaii,
|
||||||
@ -460,13 +460,13 @@ in decreasing order of importance:
|
|||||||
MET/MEST Middle European (a backward-compatibility alias for
|
MET/MEST Middle European (a backward-compatibility alias for
|
||||||
Central European),
|
Central European),
|
||||||
MSK/MSD Moscow,
|
MSK/MSD Moscow,
|
||||||
MST/MDT/MWT/MPT/MDDT Mountain,
|
MST/MDT/MWT/MPT Mountain,
|
||||||
NST/NDT/NWT/NPT/NDDT Newfoundland,
|
NST/NDT/NWT/NPT/NDDT Newfoundland,
|
||||||
NST/NDT/NWT/NPT Nome,
|
NST/NDT/NWT/NPT Nome,
|
||||||
NZMT/NZST New Zealand through 1945,
|
NZMT/NZST New Zealand through 1945,
|
||||||
NZST/NZDT New Zealand 1946–present,
|
NZST/NZDT New Zealand 1946–present,
|
||||||
PKT/PKST Pakistan,
|
PKT/PKST Pakistan,
|
||||||
PST/PDT/PWT/PPT/PDDT Pacific,
|
PST/PDT/PWT/PPT Pacific,
|
||||||
PST/PDT Philippine,
|
PST/PDT Philippine,
|
||||||
SAST South Africa,
|
SAST South Africa,
|
||||||
SST Samoa,
|
SST Samoa,
|
||||||
@ -494,7 +494,7 @@ in decreasing order of importance:
|
|||||||
<p>
|
<p>
|
||||||
<small>These abbreviations are:
|
<small>These abbreviations are:
|
||||||
AMT Asunción, Athens;
|
AMT Asunción, Athens;
|
||||||
BMT Baghdad, Bangkok, Batavia, Bermuda, Bern, Bogotá, Bridgetown,
|
BMT Baghdad, Bangkok, Batavia, Bermuda, Bern, Bogotá,
|
||||||
Brussels, Bucharest;
|
Brussels, Bucharest;
|
||||||
CMT Calamarca, Caracas, Chisinau, Colón, Córdoba;
|
CMT Calamarca, Caracas, Chisinau, Colón, Córdoba;
|
||||||
DMT Dublin/Dunsink;
|
DMT Dublin/Dunsink;
|
||||||
@ -506,12 +506,13 @@ in decreasing order of importance:
|
|||||||
IMT Irkutsk, Istanbul;
|
IMT Irkutsk, Istanbul;
|
||||||
JMT Jerusalem;
|
JMT Jerusalem;
|
||||||
KMT Kaunas, Kyiv, Kingston;
|
KMT Kaunas, Kyiv, Kingston;
|
||||||
LMT Lima, Lisbon, local, Luanda;
|
LMT Lima, Lisbon, local;
|
||||||
MMT Macassar, Madras, Malé, Managua, Minsk, Monrovia, Montevideo,
|
MMT Macassar, Madras, Malé, Managua, Minsk, Monrovia, Montevideo,
|
||||||
Moratuwa, Moscow;
|
Moratuwa, Moscow;
|
||||||
PLMT Phù Liễn;
|
PLMT Phù Liễn;
|
||||||
PMT Paramaribo, Paris, Perm, Pontianak, Prague;
|
PMT Paramaribo, Paris, Perm, Pontianak, Prague;
|
||||||
PMMT Port Moresby;
|
PMMT Port Moresby;
|
||||||
|
PPMT Port-au-Prince;
|
||||||
QMT Quito;
|
QMT Quito;
|
||||||
RMT Rangoon, Riga, Rome;
|
RMT Rangoon, Riga, Rome;
|
||||||
SDMT Santo Domingo;
|
SDMT Santo Domingo;
|
||||||
@ -519,8 +520,7 @@ in decreasing order of importance:
|
|||||||
SMT Santiago, Simferopol, Singapore, Stanley;
|
SMT Santiago, Simferopol, Singapore, Stanley;
|
||||||
TBMT Tbilisi;
|
TBMT Tbilisi;
|
||||||
TMT Tallinn, Tehran;
|
TMT Tallinn, Tehran;
|
||||||
WMT Warsaw;
|
WMT Warsaw.</small>
|
||||||
ZMT Zomba.</small>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -791,7 +791,7 @@ href="https://www.dissentmagazine.org/blog/booked-a-global-history-of-time-vanes
|
|||||||
with days starting at midnight.
|
with days starting at midnight.
|
||||||
Although <abbr>UT</abbr> equals <abbr>UTC</abbr> for modern
|
Although <abbr>UT</abbr> equals <abbr>UTC</abbr> for modern
|
||||||
timestamps, <abbr>UTC</abbr> was not defined until 1960, so
|
timestamps, <abbr>UTC</abbr> was not defined until 1960, so
|
||||||
commentary uses the more-general abbreviation <abbr>UT</abbr> for
|
commentary uses the more general abbreviation <abbr>UT</abbr> for
|
||||||
timestamps that might predate 1960.
|
timestamps that might predate 1960.
|
||||||
Since <abbr>UT</abbr>, <abbr>UT1</abbr>, etc. disagree slightly,
|
Since <abbr>UT</abbr>, <abbr>UT1</abbr>, etc. disagree slightly,
|
||||||
and since pre-1972 <abbr>UTC</abbr> seconds varied in length,
|
and since pre-1972 <abbr>UTC</abbr> seconds varied in length,
|
||||||
@ -818,7 +818,8 @@ href="https://www.dissentmagazine.org/blog/booked-a-global-history-of-time-vanes
|
|||||||
<li>
|
<li>
|
||||||
The relationship between POSIX time (that is, <abbr>UTC</abbr> but
|
The relationship between POSIX time (that is, <abbr>UTC</abbr> but
|
||||||
ignoring <a href="https://en.wikipedia.org/wiki/Leap_second">leap
|
ignoring <a href="https://en.wikipedia.org/wiki/Leap_second">leap
|
||||||
seconds</a>) and <abbr>UTC</abbr> is not agreed upon after 1972.
|
seconds</a>) and <abbr>UTC</abbr> is not agreed upon.
|
||||||
|
This affects time stamps during the leap second era (1972–2035).
|
||||||
Although the POSIX
|
Although the POSIX
|
||||||
clock officially stops during an inserted leap second, at least one
|
clock officially stops during an inserted leap second, at least one
|
||||||
proposed standard has it jumping back a second instead; and in
|
proposed standard has it jumping back a second instead; and in
|
||||||
@ -877,7 +878,7 @@ an older <code>zic</code>.
|
|||||||
is error-prone in practice.
|
is error-prone in practice.
|
||||||
Also, POSIX <code>TZ</code> strings cannot deal with daylight
|
Also, POSIX <code>TZ</code> strings cannot deal with daylight
|
||||||
saving time rules not based on the Gregorian calendar (as in
|
saving time rules not based on the Gregorian calendar (as in
|
||||||
Iran), or with situations where more than two time zone
|
Morocco), or with situations where more than two time zone
|
||||||
abbreviations or <abbr>UT</abbr> offsets are used in an area.
|
abbreviations or <abbr>UT</abbr> offsets are used in an area.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -913,8 +914,8 @@ an older <code>zic</code>.
|
|||||||
<dt><var>date</var>[<code>/</code><var>time</var>]<code>,</code><var>date</var>[<code>/</code><var>time</var>]</dt><dd>
|
<dt><var>date</var>[<code>/</code><var>time</var>]<code>,</code><var>date</var>[<code>/</code><var>time</var>]</dt><dd>
|
||||||
specifies the beginning and end of <abbr>DST</abbr>.
|
specifies the beginning and end of <abbr>DST</abbr>.
|
||||||
If this is absent, the system supplies its own ruleset
|
If this is absent, the system supplies its own ruleset
|
||||||
for <abbr>DST</abbr>, and its rules can differ from year to year;
|
for <abbr>DST</abbr>, typically current <abbr>US</abbr>
|
||||||
typically <abbr>US</abbr> <abbr>DST</abbr> rules are used.
|
<abbr>DST</abbr> rules.
|
||||||
</dd>
|
</dd>
|
||||||
<dt><var>time</var></dt><dd>
|
<dt><var>time</var></dt><dd>
|
||||||
takes the form
|
takes the form
|
||||||
@ -974,10 +975,11 @@ an older <code>zic</code>.
|
|||||||
Traditionally the current <abbr>US</abbr> <abbr>DST</abbr> rules
|
Traditionally the current <abbr>US</abbr> <abbr>DST</abbr> rules
|
||||||
were used to interpret such values, but this meant that the
|
were used to interpret such values, but this meant that the
|
||||||
<abbr>US</abbr> <abbr>DST</abbr> rules were compiled into each
|
<abbr>US</abbr> <abbr>DST</abbr> rules were compiled into each
|
||||||
program that did time conversion. This meant that when
|
time conversion package, and when
|
||||||
<abbr>US</abbr> time conversion rules changed (as in the United
|
<abbr>US</abbr> time conversion rules changed (as in the United
|
||||||
States in 1987), all programs that did time conversion had to be
|
States in 1987 and again in 2007), all packages that
|
||||||
recompiled to ensure proper results.
|
interpreted <code>TZ</code> values had to be updated
|
||||||
|
to ensure proper results.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
The <code>TZ</code> environment variable is process-global, which
|
The <code>TZ</code> environment variable is process-global, which
|
||||||
@ -1173,7 +1175,7 @@ The vestigial <abbr>API</abbr>s are:
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
The functions that are conditionally compiled
|
The functions that are conditionally compiled
|
||||||
if <code>STD_INSPIRED</code> is defined should, at this point, be
|
if <code>STD_INSPIRED</code> is nonzero should, at this point, be
|
||||||
looked on primarily as food for thought.
|
looked on primarily as food for thought.
|
||||||
They are not in any sense "standard compatible" – some are
|
They are not in any sense "standard compatible" – some are
|
||||||
not, in fact, specified in <em>any</em> standard.
|
not, in fact, specified in <em>any</em> standard.
|
||||||
@ -1240,7 +1242,7 @@ The <code><abbr>tz</abbr></code> code and data supply the following interfaces:
|
|||||||
Interface changes in a release attempt to preserve compatibility with
|
Interface changes in a release attempt to preserve compatibility with
|
||||||
recent releases.
|
recent releases.
|
||||||
For example, <code><abbr>tz</abbr></code> data files typically do not
|
For example, <code><abbr>tz</abbr></code> data files typically do not
|
||||||
rely on recently-added <code>zic</code> features, so that users can
|
rely on recently added <code>zic</code> features, so that users can
|
||||||
run older <code>zic</code> versions to process newer data files.
|
run older <code>zic</code> versions to process newer data files.
|
||||||
<a href="tz-link.html#download">Downloading
|
<a href="tz-link.html#download">Downloading
|
||||||
the <code><abbr>tz</abbr></code> database</a> describes how releases
|
the <code><abbr>tz</abbr></code> database</a> describes how releases
|
||||||
@ -1268,6 +1270,18 @@ between now and the future time.
|
|||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h2 id="leapsec">Leap seconds</h2>
|
<h2 id="leapsec">Leap seconds</h2>
|
||||||
|
<p>
|
||||||
|
Leap seconds were introduced in 1972 to accommodate the
|
||||||
|
difference between atomic time and the less regular rotation of the earth.
|
||||||
|
Unfortunately they caused so many problems with civil
|
||||||
|
timekeeping that they
|
||||||
|
are <a href="https://www.bipm.org/en/cgpm-2022/resolution-4">planned
|
||||||
|
to be discontinued by 2035</a>, with some as-yet-undetermined
|
||||||
|
mechanism replacing them, perhaps after the year 2135.
|
||||||
|
Despite their impending obsolescence, a record of leap seconds is still
|
||||||
|
needed to resolve timestamps from 1972 through 2035.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The <code><abbr>tz</abbr></code> code and data can account for leap seconds,
|
The <code><abbr>tz</abbr></code> code and data can account for leap seconds,
|
||||||
thanks to code contributed by Bradley White.
|
thanks to code contributed by Bradley White.
|
||||||
@ -1282,12 +1296,12 @@ commonly used by
|
|||||||
<a href="https://www.ntp.org"><abbr title="Network Time Protocol">NTP</abbr></a>
|
<a href="https://www.ntp.org"><abbr title="Network Time Protocol">NTP</abbr></a>
|
||||||
software that adjusts the kernel clock.
|
software that adjusts the kernel clock.
|
||||||
However, kernel-clock twiddling approximates UTC only roughly,
|
However, kernel-clock twiddling approximates UTC only roughly,
|
||||||
and systems needing more-precise UTC can use this package's leap
|
and systems needing more precise UTC can use this package's leap
|
||||||
second support directly.
|
second support directly.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The directly-supported mechanism assumes that <code>time_t</code>
|
The directly supported mechanism assumes that <code>time_t</code>
|
||||||
counts of seconds since the POSIX epoch normally include leap seconds,
|
counts of seconds since the POSIX epoch normally include leap seconds,
|
||||||
as opposed to POSIX <code>time_t</code> counts which exclude leap seconds.
|
as opposed to POSIX <code>time_t</code> counts which exclude leap seconds.
|
||||||
This modified timescale is converted to <abbr>UTC</abbr>
|
This modified timescale is converted to <abbr>UTC</abbr>
|
||||||
@ -1348,7 +1362,15 @@ They sometimes disagree.
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h2 id="planets">Time and time zones on other planets</h2>
|
<h2 id="planets">Time and time zones off Earth</h2>
|
||||||
|
<p>
|
||||||
|
The European Space Agency is <a
|
||||||
|
href='https://www.esa.int/Applications/Navigation/Telling_time_on_the_Moon'>considering</a>
|
||||||
|
the establishment of a reference timescale for the Moon, which has
|
||||||
|
days roughly equivalent to 29.5 Earth days, and where relativistic
|
||||||
|
effects cause clocks to tick slightly faster than on Earth.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Some people's work schedules have used
|
Some people's work schedules have used
|
||||||
<a href="https://en.wikipedia.org/wiki/Timekeeping_on_Mars">Mars time</a>.
|
<a href="https://en.wikipedia.org/wiki/Timekeeping_on_Mars">Mars time</a>.
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
.\" This file is in the public domain, so clarified as of
|
.\" This file is in the public domain, so clarified as of
|
||||||
.\" 1996-06-05 by Arthur David Olson.
|
.\" 1996-06-05 by Arthur David Olson.
|
||||||
.\"
|
|
||||||
.\" $FreeBSD$
|
|
||||||
.\"
|
|
||||||
.Dd December 15, 2022
|
.Dd December 15, 2022
|
||||||
.Dt TIME2POSIX 3
|
.Dt TIME2POSIX 3
|
||||||
.Os
|
.Os
|
||||||
|
@ -478,22 +478,35 @@ Supernaw.</td></tr>
|
|||||||
<tr><td>Total Time</td><td>1:16:20</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><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>Notes</td><td>Includes the song "Does Anybody Really Know What Time It Is?"</td></tr>
|
||||||
|
<tr><td> </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>
|
</table>
|
||||||
<h2>Comics</h2>
|
<h2>Comics</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
The webcomic <em>xkcd</em> has the strip
|
The webcomic <em>xkcd</em> has the strips
|
||||||
"<a href="https://xkcd.com/673/">The Sun</a>" (2009-12-09) and the panels
|
"<a href="https://xkcd.com/673/">The Sun</a>" (2009-12-09),
|
||||||
|
"<a href="https://xkcd.com/1655/">Doomsday Clock</a>" (2016-03-14) and
|
||||||
|
"<a href="https://xkcd.com/2549/">Edge Cake</a>" (2021-12-01),
|
||||||
|
along with the panels
|
||||||
|
"<a href="https://xkcd.com/448/">Good Morning</a>" (2008-07-11),
|
||||||
"<a href="https://xkcd.com/1017/">Backward in Time</a>" (2012-02-14),
|
"<a href="https://xkcd.com/1017/">Backward in Time</a>" (2012-02-14),
|
||||||
"<a href="https://xkcd.com/1061/">EST</a>" (2012-05-28),
|
"<a href="https://xkcd.com/1061/">EST</a>" (2012-05-28),
|
||||||
"<a href="https://xkcd.com/1179/">ISO 8601</a>" (2013-02-27),
|
"<a href="https://xkcd.com/1179/">ISO 8601</a>" (2013-02-27),
|
||||||
"<a href="https://xkcd.com/1335/">Now</a>" (2014-02-26),
|
"<a href="https://xkcd.com/1335/">Now</a>" (2014-02-26),
|
||||||
"<a href="https://xkcd.com/1655/">Doomsday Clock</a>" (2016-03-14),
|
|
||||||
"<a href="https://xkcd.com/1799/">Bad Map Projection: Time Zones</a>"
|
"<a href="https://xkcd.com/1799/">Bad Map Projection: Time Zones</a>"
|
||||||
(2017-02-15),
|
(2017-02-15),
|
||||||
"<a href="https://xkcd.com/1883/">Supervillain Plan</a>" (2017-08-30),
|
"<a href="https://xkcd.com/1883/">Supervillain Plan</a>" (2017-08-30),
|
||||||
"<a href="https://xkcd.com/2050/">6/6 Time</a>" (2018-09-24),
|
"<a href="https://xkcd.com/2050/">6/6 Time</a>" (2018-09-24),
|
||||||
and "<a href="https://xkcd.com/2266/">Leap Smearing</a>" (2020-02-10).
|
"<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).
|
||||||
The related book <em>What If?</em> has an entry
|
The related book <em>What If?</em> has an entry
|
||||||
"<a href="https://what-if.xkcd.com/26/">Leap Seconds</a>" (2012-12-31).
|
"<a href="https://what-if.xkcd.com/26/">Leap Seconds</a>" (2012-12-31).
|
||||||
</li>
|
</li>
|
||||||
|
@ -548,8 +548,8 @@ a <code>SAVE</code> of zero.
|
|||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
<li>The <a href="https://en.wikipedia.org/wiki/Tz_database">tz
|
<li>The <a href="https://en.wikipedia.org/wiki/Tz_database">tz
|
||||||
database</a> gives abbreviations for time zones in <i>popular
|
database</a> gives abbreviations for time zones
|
||||||
usage</i>, which is not necessarily “correct” by law. For
|
in popular English-language usage. For
|
||||||
example, the last line in
|
example, the last line in
|
||||||
<code>Zone</code> <code>Pacific/Honolulu</code> (shown below) gives
|
<code>Zone</code> <code>Pacific/Honolulu</code> (shown below) gives
|
||||||
“HST” for “Hawaii standard time” even though the
|
“HST” for “Hawaii standard time” even though the
|
||||||
@ -567,7 +567,7 @@ the abbreviations. They are intended to be the values returned through the
|
|||||||
function in the
|
function in the
|
||||||
<a href="https://kirste.userpage.fu-berlin.de/chemnet/use/info/libc/libc_19.html#SEC324">“C” locale</a>.
|
<a href="https://kirste.userpage.fu-berlin.de/chemnet/use/info/libc/libc_19.html#SEC324">“C” locale</a>.
|
||||||
|
|
||||||
<li>If there is no generally-accepted abbreviation for a time zone,
|
<li>If there is no generally accepted abbreviation for a time zone,
|
||||||
a numeric offset is used instead, e.g., <code>+07</code> for 7 hours
|
a numeric offset is used instead, e.g., <code>+07</code> for 7 hours
|
||||||
ahead of Greenwich. By convention, <code>-00</code> is used in a
|
ahead of Greenwich. By convention, <code>-00</code> is used in a
|
||||||
zone while uninhabited, where the offset is zero but in some sense
|
zone while uninhabited, where the offset is zero but in some sense
|
||||||
|
@ -26,6 +26,7 @@ area.
|
|||||||
<li><a href="#tzdb">The <code><abbr>tz</abbr></code> database</a></li>
|
<li><a href="#tzdb">The <code><abbr>tz</abbr></code> database</a></li>
|
||||||
<li><a href="#download">Downloading the <code><abbr>tz</abbr></code> database</a></li>
|
<li><a href="#download">Downloading the <code><abbr>tz</abbr></code> database</a></li>
|
||||||
<li><a href="#changes">Changes to the <code><abbr>tz</abbr></code> database</a></li>
|
<li><a href="#changes">Changes to the <code><abbr>tz</abbr></code> database</a></li>
|
||||||
|
<li><a href="#coordinating">Coordinating with governments and distributors</a></li>
|
||||||
<li><a href="#commentary">Commentary on the <code><abbr>tz</abbr></code> database</a></li>
|
<li><a href="#commentary">Commentary on the <code><abbr>tz</abbr></code> database</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
@ -169,14 +170,14 @@ through <samp>zzz</samp>, and so on).
|
|||||||
Since version 2022a, each release has been distributed in
|
Since version 2022a, each release has been distributed in
|
||||||
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_06">POSIX
|
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_06">POSIX
|
||||||
ustar interchange format</a>, compressed as described above;
|
ustar interchange format</a>, compressed as described above;
|
||||||
older releases use a nearly-compatible format.
|
older releases use a nearly compatible format.
|
||||||
Since version 2016h, each release has contained a text file named
|
Since version 2016h, each release has contained a text file named
|
||||||
"<samp>version</samp>" whose first (and currently only) line is the version.
|
"<samp>version</samp>" whose first (and currently only) line is the version.
|
||||||
Older releases are <a href="https://ftp.iana.org/tz/releases/">archived</a>,
|
Older releases are <a href="https://ftp.iana.org/tz/releases/">archived</a>,
|
||||||
and are also available in an
|
and are also available in an
|
||||||
<a href="ftp://ftp.iana.org/tz/releases/"><abbr
|
<a href="ftp://ftp.iana.org/tz/releases/"><abbr
|
||||||
title="File Transfer Protocol">FTP</abbr> directory</a> via a
|
title="File Transfer Protocol">FTP</abbr> directory</a> via a
|
||||||
less-secure protocol.</p>
|
less secure protocol.</p>
|
||||||
<p>Alternatively, a development repository of code and data can be
|
<p>Alternatively, a development repository of code and data can be
|
||||||
retrieved from <a href="https://github.com">GitHub</a> via the shell
|
retrieved from <a href="https://github.com">GitHub</a> via the shell
|
||||||
command:</p>
|
command:</p>
|
||||||
@ -215,23 +216,6 @@ discussions</a> and corresponding data changes can be
|
|||||||
generated <a href="https://github.com/timparenti/tzdata-meta">automatically</a>.
|
generated <a href="https://github.com/timparenti/tzdata-meta">automatically</a>.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
If your government plans to change its time zone boundaries or
|
|
||||||
daylight saving rules, inform <code>tz@iana.org</code> well in
|
|
||||||
advance, as this will coordinate updates to many cell phones,
|
|
||||||
computers, and other devices around the world.
|
|
||||||
The change should be officially announced at least a year before it affects
|
|
||||||
how clocks operate; otherwise, there is a good chance that some
|
|
||||||
clocks will operate incorrectly after the change, due
|
|
||||||
to delays in propagating updates to software and data. The shorter
|
|
||||||
the notice, the more likely clock problems will arise; see "<a
|
|
||||||
href="https://codeofmatt.com/2016/04/23/on-the-timing-of-time-zone-changes/">On
|
|
||||||
the Timing of Time Zone Changes</a>" for examples.
|
|
||||||
The <code><abbr>tz</abbr></code> data can represent planned changes
|
|
||||||
far into the future, and a long-planned change can easily be reverted
|
|
||||||
or otherwise altered with a year's notice before the change would have
|
|
||||||
affected clocks.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Changes to the <code><abbr>tz</abbr></code> code and data are often
|
Changes to the <code><abbr>tz</abbr></code> code and data are often
|
||||||
propagated to clients via operating system updates, so
|
propagated to clients via operating system updates, so
|
||||||
client <code><abbr>tz</abbr></code> data can often be corrected by
|
client <code><abbr>tz</abbr></code> data can often be corrected by
|
||||||
@ -286,6 +270,55 @@ displays changes between recent <code><abbr>tzdb</abbr></code> versions.
|
|||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2 id="coordinating">Coordinating with governments and distributors</h2>
|
||||||
|
<p>
|
||||||
|
As discussed in
|
||||||
|
"<a href="https://www.icann.org/en/blogs/details/how-time-zones-are-coordinated-13-03-2023-en">How
|
||||||
|
Time Zones Are Coordinated</a>", the time zone database relies on
|
||||||
|
collaboration among governments, the time zone database volunteer
|
||||||
|
community, and data distributors downstream.
|
||||||
|
<p>
|
||||||
|
If your government plans to change its time zone boundaries or
|
||||||
|
daylight saving rules, please send email to <a
|
||||||
|
href="mailto:tz@iana.org"><code>tz@iana.org</code></a> well in advance,
|
||||||
|
as this will lessen confusion and will coordinate updates to many cell phones,
|
||||||
|
computers, and other devices around the world.
|
||||||
|
In your email, please cite the legislation or regulation that specifies
|
||||||
|
the change, so that it can be checked for details such as the exact times
|
||||||
|
when clock transitions occur.
|
||||||
|
It is OK if a rule change is planned to affect clocks
|
||||||
|
far into the future, as a long-planned change can easily be reverted
|
||||||
|
or otherwise altered with a year's notice before the change would have
|
||||||
|
affected clocks.</p>
|
||||||
|
<p>
|
||||||
|
There is no fixed schedule for <code><abbr>tzdb</abbr></code> releases.
|
||||||
|
However, typically a release occurs every few months.
|
||||||
|
Many downstream timezone data distributors wait for
|
||||||
|
a <code><abbr>tzdb</abbr></code> release before they produce an update
|
||||||
|
to time zone behavior in consumer devices and software products.
|
||||||
|
After a release, various parties must integrate, test,
|
||||||
|
and roll out an update before <a
|
||||||
|
href="https://en.wikipedia.org/wiki/End_user">end users</a> see changes.
|
||||||
|
These updates can be expensive, for both the <a
|
||||||
|
href="https://en.wikipedia.org/wiki/Quality_assurance">quality
|
||||||
|
assurance</a> process and the overall cost of shipping and installing
|
||||||
|
updates to each device's copy of <code><abbr>tzdb</abbr></code>.
|
||||||
|
Updates may be batched with other updates and may take substantial
|
||||||
|
time to reach end users after a release.
|
||||||
|
Older devices may no longer be supported and thus may never be updated,
|
||||||
|
which means they will continue to use out-of-date rules.</p>
|
||||||
|
<p>
|
||||||
|
For these reasons any rule change should be promulgated at least a
|
||||||
|
year before it affects how clocks operate; otherwise, there is a good
|
||||||
|
chance that many clocks will be wrong due to delays in propagating updates,
|
||||||
|
and that residents will be confused or even actively resist the change.
|
||||||
|
The shorter the notice, the more likely clock problems will arise; see "<a
|
||||||
|
href="https://codeofmatt.com/2016/04/23/on-the-timing-of-time-zone-changes/">On
|
||||||
|
the Timing of Time Zone Changes</a>" for examples.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h2 id="commentary">Commentary on the <code><abbr>tz</abbr></code> database</h2>
|
<h2 id="commentary">Commentary on the <code><abbr>tz</abbr></code> database</h2>
|
||||||
<ul>
|
<ul>
|
||||||
@ -384,7 +417,7 @@ running the command <code>make rearguard_tarballs</code> and compiling
|
|||||||
from the resulting tarballs instead.</p>
|
from the resulting tarballs instead.</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://sourceforge.net/projects/vzic/">Vzic</a> is a <a
|
<li><a href="https://sourceforge.net/projects/vzic/">Vzic</a> is a <a
|
||||||
href="https://en.wikipedia.org/wiki/C_%28programming_language%29">C</a>
|
href="https://en.wikipedia.org/wiki/C_(programming_language)">C</a>
|
||||||
program that compiles
|
program that compiles
|
||||||
<code><abbr>tz</abbr></code> source into iCalendar-compatible VTIMEZONE files.
|
<code><abbr>tz</abbr></code> source into iCalendar-compatible VTIMEZONE files.
|
||||||
Vzic is freely
|
Vzic is freely
|
||||||
@ -409,7 +442,7 @@ License. DateTime::TimeZone also contains a script
|
|||||||
transition in the <code><abbr>tz</abbr></code> database.</li>
|
transition in the <code><abbr>tz</abbr></code> database.</li>
|
||||||
<li>The <a href="https://howardhinnant.github.io/date/tz.html">Time Zone
|
<li>The <a href="https://howardhinnant.github.io/date/tz.html">Time Zone
|
||||||
Database Parser</a> is a
|
Database Parser</a> is a
|
||||||
<a href="https://en.wikipedia.org/wiki/C%2B%2B">C++</a> parser and
|
<a href="https://en.wikipedia.org/wiki/C++">C++</a> parser and
|
||||||
runtime library with <a
|
runtime library with <a
|
||||||
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0355r7.html">API</a>
|
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0355r7.html">API</a>
|
||||||
adopted by
|
adopted by
|
||||||
@ -419,7 +452,7 @@ It is freely available under the
|
|||||||
<abbr title="Massachusetts Institute of Technology">MIT</abbr> license.</li>
|
<abbr title="Massachusetts Institute of Technology">MIT</abbr> license.</li>
|
||||||
<li><a id="ICU" href="https://icu.unicode.org">International Components for
|
<li><a id="ICU" href="https://icu.unicode.org">International Components for
|
||||||
Unicode (<abbr>ICU</abbr>)</a> contains C/C++ and <a
|
Unicode (<abbr>ICU</abbr>)</a> contains C/C++ and <a
|
||||||
href="https://en.wikipedia.org/wiki/Java_%28programming_language%29">Java</a>
|
href="https://en.wikipedia.org/wiki/Java_(programming_language)">Java</a>
|
||||||
libraries for internationalization that
|
libraries for internationalization that
|
||||||
has a compiler from <code><abbr>tz</abbr></code> source
|
has a compiler from <code><abbr>tz</abbr></code> source
|
||||||
and from <abbr title="Common Locale Data Repository">CLDR</abbr> data
|
and from <abbr title="Common Locale Data Repository">CLDR</abbr> data
|
||||||
@ -903,6 +936,10 @@ covers the history of local time in the Netherlands from ancient times.</dd>
|
|||||||
<dd>The Department of Internal Affairs maintains a brief <a
|
<dd>The Department of Internal Affairs maintains a brief <a
|
||||||
href="https://www.dia.govt.nz/Daylight-Saving-History">History of
|
href="https://www.dia.govt.nz/Daylight-Saving-History">History of
|
||||||
Daylight Saving</a>.</dd>
|
Daylight Saving</a>.</dd>
|
||||||
|
<dt>Palestine</dt>
|
||||||
|
<dd>The Ministry of Telecom and IT publishes a <a
|
||||||
|
href="https://mtit.pna.ps/Site/TimeZoon"
|
||||||
|
hreflang="ar">history of clock changes (in Arabic)</a>.</dd>
|
||||||
<dt>Portugal</dt>
|
<dt>Portugal</dt>
|
||||||
<dd>The Lisbon Astronomical Observatory publishes a
|
<dd>The Lisbon Astronomical Observatory publishes a
|
||||||
<a href="https://oal.ul.pt/hora-legal/" hreflang="pt">history of
|
<a href="https://oal.ul.pt/hora-legal/" hreflang="pt">history of
|
||||||
@ -978,7 +1015,7 @@ href="http://leapsecond.com/hpan/an1289.pdf">The
|
|||||||
Science of Timekeeping</a> is a thorough introduction
|
Science of Timekeeping</a> is a thorough introduction
|
||||||
to the theory and practice of precision timekeeping.</li>
|
to the theory and practice of precision timekeeping.</li>
|
||||||
<li><a href="https://doi.org/10.1007/978-3-319-59909-0">The Science of
|
<li><a href="https://doi.org/10.1007/978-3-319-59909-0">The Science of
|
||||||
Time 2016</a> contains several freely-readable papers.</li>
|
Time 2016</a> contains several freely readable papers.</li>
|
||||||
<li><a href="https://www.ntp.org"><abbr
|
<li><a href="https://www.ntp.org"><abbr
|
||||||
title="Network Time Protocol">NTP</abbr>: The Network
|
title="Network Time Protocol">NTP</abbr>: The Network
|
||||||
Time Protocol</a> (Internet <abbr>RFC</abbr> 5905)
|
Time Protocol</a> (Internet <abbr>RFC</abbr> 5905)
|
||||||
@ -1050,7 +1087,7 @@ and to
|
|||||||
In practice the two configurations also agree for timestamps before
|
In practice the two configurations also agree for timestamps before
|
||||||
1972 even though the historical situation is messy, partly because
|
1972 even though the historical situation is messy, partly because
|
||||||
neither <abbr>UTC</abbr> nor <abbr>TAI</abbr>
|
neither <abbr>UTC</abbr> nor <abbr>TAI</abbr>
|
||||||
is well-defined for sufficiently-old timestamps.</li>
|
is well-defined for sufficiently old timestamps.</li>
|
||||||
<li><a href="https://developers.google.com/time/smear">Leap Smear</a>
|
<li><a href="https://developers.google.com/time/smear">Leap Smear</a>
|
||||||
discusses how to gradually adjust <abbr>POSIX</abbr> clocks near a
|
discusses how to gradually adjust <abbr>POSIX</abbr> clocks near a
|
||||||
leap second so that they disagree with <abbr>UTC</abbr> by at most a
|
leap second so that they disagree with <abbr>UTC</abbr> by at most a
|
||||||
@ -1078,8 +1115,12 @@ leap second: its history and possible future</a>.
|
|||||||
<a href="https://www.ucolick.org/~sla/leapsecs/"><abbr>UTC</abbr>
|
<a href="https://www.ucolick.org/~sla/leapsecs/"><abbr>UTC</abbr>
|
||||||
might be redefined
|
might be redefined
|
||||||
without Leap Seconds</a> gives pointers on this
|
without Leap Seconds</a> gives pointers on this
|
||||||
contentious issue, which was active until 2015 and could become active
|
contentious issue.
|
||||||
again.</li>
|
The General Conference on Weights and Measures
|
||||||
|
<a href="https://www.bipm.org/en/cgpm-2022/resolution-4">voted 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.
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
.\" This file is in the public domain, so clarified as of
|
.\" This file is in the public domain, so clarified as of
|
||||||
.\" 1996-06-05 by Arthur David Olson.
|
.\" 1996-06-05 by Arthur David Olson.
|
||||||
.\"
|
|
||||||
.\" $FreeBSD$
|
|
||||||
.\"
|
|
||||||
.Dd December 15, 2022
|
.Dd December 15, 2022
|
||||||
.Dt TZFILE 5
|
.Dt TZFILE 5
|
||||||
.Os
|
.Os
|
||||||
@ -207,7 +204,7 @@ if there is no POSIX-style representation for such instants.
|
|||||||
If nonempty, the POSIX-style TZ string must agree with the local time
|
If nonempty, the POSIX-style TZ string must agree with the local time
|
||||||
type after the last transition time if present in the eight-byte data;
|
type after the last transition time if present in the eight-byte data;
|
||||||
for example, given the string
|
for example, given the string
|
||||||
.Dq "WET0WEST,M3.5.0,M10.5.0/3"
|
.Dq "WET0WEST,M3.5.0/1,M10.5.0"
|
||||||
then if a last transition time is in July, the transition's local time
|
then if a last transition time is in July, the transition's local time
|
||||||
type must specify a daylight-saving time abbreviated
|
type must specify a daylight-saving time abbreviated
|
||||||
.Dq "WEST"
|
.Dq "WEST"
|
||||||
|
@ -105,20 +105,24 @@ struct tzhead {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TZ_MAX_TIMES
|
#ifndef TZ_MAX_TIMES
|
||||||
|
/* This must be at least 242 for Europe/London with 'zic -b fat'. */
|
||||||
# define TZ_MAX_TIMES 2000
|
# define TZ_MAX_TIMES 2000
|
||||||
#endif /* !defined TZ_MAX_TIMES */
|
#endif /* !defined TZ_MAX_TIMES */
|
||||||
|
|
||||||
#ifndef TZ_MAX_TYPES
|
#ifndef TZ_MAX_TYPES
|
||||||
/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */
|
/* This must be at least 18 for Europe/Vilnius with 'zic -b fat'. */
|
||||||
# define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
|
# define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
|
||||||
#endif /* !defined TZ_MAX_TYPES */
|
#endif /* !defined TZ_MAX_TYPES */
|
||||||
|
|
||||||
#ifndef TZ_MAX_CHARS
|
#ifndef TZ_MAX_CHARS
|
||||||
|
/* This must be at least 40 for America/Anchorage. */
|
||||||
# define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
|
# define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
|
||||||
/* (limited by what unsigned chars can hold) */
|
/* (limited by what unsigned chars can hold) */
|
||||||
#endif /* !defined TZ_MAX_CHARS */
|
#endif /* !defined TZ_MAX_CHARS */
|
||||||
|
|
||||||
#ifndef TZ_MAX_LEAPS
|
#ifndef TZ_MAX_LEAPS
|
||||||
|
/* This must be at least 27 for leap seconds from 1972 through mid-2023.
|
||||||
|
There's a plan to discontinue leap seconds by 2035. */
|
||||||
# define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
|
# define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
|
||||||
#endif /* !defined TZ_MAX_LEAPS */
|
#endif /* !defined TZ_MAX_LEAPS */
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.\" This file is in the public domain, so clarified as of
|
.\" This file is in the public domain, so clarified as of
|
||||||
.\" 2009-05-17 by Arthur David Olson.
|
.\" 2009-05-17 by Arthur David Olson.
|
||||||
.TH TZSELECT 8
|
.TH tzselect 8 "" "Time Zone Database"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
tzselect \- select a timezone
|
tzselect \- select a timezone
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -39,7 +39,7 @@ REPORT_BUGS_TO=tz@iana.org
|
|||||||
: ${AWK=awk}
|
: ${AWK=awk}
|
||||||
: ${TZDIR=`pwd`}
|
: ${TZDIR=`pwd`}
|
||||||
|
|
||||||
# Output one argument as-is to standard output.
|
# Output one argument as-is to standard output, with trailing newline.
|
||||||
# Safer than 'echo', which can mishandle '\' or leading '-'.
|
# Safer than 'echo', which can mishandle '\' or leading '-'.
|
||||||
say() {
|
say() {
|
||||||
printf '%s\n' "$1"
|
printf '%s\n' "$1"
|
||||||
@ -82,8 +82,8 @@ Report bugs to $REPORT_BUGS_TO."
|
|||||||
|
|
||||||
# Ask the user to select from the function's arguments,
|
# Ask the user to select from the function's arguments,
|
||||||
# and assign the selected argument to the variable 'select_result'.
|
# and assign the selected argument to the variable 'select_result'.
|
||||||
# Exit on EOF or I/O error. Use the shell's 'select' builtin if available,
|
# Exit on EOF or I/O error. Use the shell's nicer 'select' builtin if
|
||||||
# falling back on a less-nice but portable substitute otherwise.
|
# available, falling back on a portable substitute otherwise.
|
||||||
if
|
if
|
||||||
case $BASH_VERSION in
|
case $BASH_VERSION in
|
||||||
?*) : ;;
|
?*) : ;;
|
||||||
@ -197,16 +197,65 @@ newline='
|
|||||||
'
|
'
|
||||||
IFS=$newline
|
IFS=$newline
|
||||||
|
|
||||||
|
# Awk script to output a country list.
|
||||||
|
output_country_list='
|
||||||
|
BEGIN { FS = "\t" }
|
||||||
|
/^#$/ { next }
|
||||||
|
/^#[^@]/ { next }
|
||||||
|
{
|
||||||
|
commentary = $0 ~ /^#@/
|
||||||
|
if (commentary) {
|
||||||
|
col1ccs = substr($1, 3)
|
||||||
|
conts = $2
|
||||||
|
} else {
|
||||||
|
col1ccs = $1
|
||||||
|
conts = $3
|
||||||
|
}
|
||||||
|
ncc = split(col1ccs, cc, /,/)
|
||||||
|
ncont = split(conts, cont, /,/)
|
||||||
|
for (i = 1; i <= ncc; i++) {
|
||||||
|
elsewhere = commentary
|
||||||
|
for (ci = 1; ci <= ncont; ci++) {
|
||||||
|
if (cont[ci] ~ continent_re) {
|
||||||
|
if (!cc_seen[cc[i]]++) cc_list[++ccs] = cc[i]
|
||||||
|
elsewhere = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (elsewhere) {
|
||||||
|
for (i = 1; i <= ncc; i++) {
|
||||||
|
cc_elsewhere[cc[i]] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
while (getline <TZ_COUNTRY_TABLE) {
|
||||||
|
if ($0 !~ /^#/) cc_name[$1] = $2
|
||||||
|
}
|
||||||
|
for (i = 1; i <= ccs; i++) {
|
||||||
|
country = cc_list[i]
|
||||||
|
if (cc_elsewhere[country]) continue
|
||||||
|
if (cc_name[country]) {
|
||||||
|
country = cc_name[country]
|
||||||
|
}
|
||||||
|
print country
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'
|
||||||
|
|
||||||
# Awk script to read a time zone table and output the same table,
|
# Awk script to read a time zone table and output the same table,
|
||||||
# with each column preceded by its distance from 'here'.
|
# with each row preceded by its distance from 'here'.
|
||||||
output_distances='
|
# If output_times is set, each row is instead preceded by its local time
|
||||||
|
# and any apostrophes are escaped for the shell.
|
||||||
|
output_distances_or_times='
|
||||||
BEGIN {
|
BEGIN {
|
||||||
FS = "\t"
|
FS = "\t"
|
||||||
while (getline <TZ_COUNTRY_TABLE)
|
if (!output_times) {
|
||||||
if ($0 ~ /^[^#]/)
|
while (getline <TZ_COUNTRY_TABLE)
|
||||||
country[$1] = $2
|
if ($0 ~ /^[^#]/)
|
||||||
country["US"] = "US" # Otherwise the strings get too long.
|
country[$1] = $2
|
||||||
|
country["US"] = "US" # Otherwise the strings get too long.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function abs(x) {
|
function abs(x) {
|
||||||
return x < 0 ? -x : x;
|
return x < 0 ? -x : x;
|
||||||
@ -268,18 +317,35 @@ output_distances='
|
|||||||
coord_long = convert_longitude(coord)
|
coord_long = convert_longitude(coord)
|
||||||
}
|
}
|
||||||
/^[^#]/ {
|
/^[^#]/ {
|
||||||
here_lat = convert_latitude($2)
|
inline[inlines++] = $0
|
||||||
here_long = convert_longitude($2)
|
ncc = split($1, cc, /,/)
|
||||||
|
for (i = 1; i <= ncc; i++)
|
||||||
|
cc_used[cc[i]]++
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
for (h = 0; h < inlines; h++) {
|
||||||
|
$0 = inline[h]
|
||||||
line = $1 "\t" $2 "\t" $3
|
line = $1 "\t" $2 "\t" $3
|
||||||
sep = "\t"
|
sep = "\t"
|
||||||
ncc = split($1, cc, /,/)
|
ncc = split($1, cc, /,/)
|
||||||
|
split("", item_seen)
|
||||||
|
item_seen[""] = 1
|
||||||
for (i = 1; i <= ncc; i++) {
|
for (i = 1; i <= ncc; i++) {
|
||||||
line = line sep country[cc[i]]
|
item = cc_used[cc[i]] <= 1 ? country[cc[i]] : $4
|
||||||
sep = ", "
|
if (item_seen[item]++) continue
|
||||||
|
line = line sep item
|
||||||
|
sep = "; "
|
||||||
}
|
}
|
||||||
if (NF == 4)
|
if (output_times) {
|
||||||
line = line " - " $4
|
fmt = "TZ='\''%s'\'' date +'\''%d %%Y %%m %%d %%H:%%M %%a %%b\t%s'\''\n"
|
||||||
printf "%g\t%s\n", dist(coord_lat, coord_long, here_lat, here_long), line
|
gsub(/'\''/, "&\\\\&&", line)
|
||||||
|
printf fmt, $3, h, line
|
||||||
|
} else {
|
||||||
|
here_lat = convert_latitude($2)
|
||||||
|
here_long = convert_longitude($2)
|
||||||
|
printf "%g\t%s\n", dist(coord_lat, coord_long, here_lat, here_long), line
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
'
|
'
|
||||||
|
|
||||||
@ -300,7 +366,7 @@ while
|
|||||||
|
|
||||||
# Ask the user for continent or ocean.
|
# Ask the user for continent or ocean.
|
||||||
|
|
||||||
echo >&2 'Please select a continent, ocean, "coord", or "TZ".'
|
echo >&2 'Please select a continent, ocean, "coord", "TZ", or "time".'
|
||||||
|
|
||||||
quoted_continents=`
|
quoted_continents=`
|
||||||
$AWK '
|
$AWK '
|
||||||
@ -331,7 +397,8 @@ while
|
|||||||
eval '
|
eval '
|
||||||
doselect '"$quoted_continents"' \
|
doselect '"$quoted_continents"' \
|
||||||
"coord - I want to use geographical coordinates." \
|
"coord - I want to use geographical coordinates." \
|
||||||
"TZ - I want to specify the timezone using the Posix TZ format."
|
"TZ - I want to specify the timezone using the Posix TZ format." \
|
||||||
|
"time - I know local time already."
|
||||||
continent=$select_result
|
continent=$select_result
|
||||||
case $continent in
|
case $continent in
|
||||||
Americas) continent=America;;
|
Americas) continent=America;;
|
||||||
@ -384,74 +451,99 @@ while
|
|||||||
distance_table=`$AWK \
|
distance_table=`$AWK \
|
||||||
-v coord="$coord" \
|
-v coord="$coord" \
|
||||||
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||||
"$output_distances" <"$TZ_ZONE_TABLE" |
|
"$output_distances_or_times" <"$TZ_ZONE_TABLE" |
|
||||||
sort -n |
|
sort -n |
|
||||||
sed "${location_limit}q"
|
sed "${location_limit}q"
|
||||||
`
|
`
|
||||||
regions=`say "$distance_table" | $AWK '
|
regions=`$AWK \
|
||||||
BEGIN { FS = "\t" }
|
-v distance_table="$distance_table" '
|
||||||
{ print $NF }
|
BEGIN {
|
||||||
|
nlines = split(distance_table, line, /\n/)
|
||||||
|
for (nr = 1; nr <= nlines; nr++) {
|
||||||
|
nf = split(line[nr], f, /\t/)
|
||||||
|
print f[nf]
|
||||||
|
}
|
||||||
|
}
|
||||||
'`
|
'`
|
||||||
echo >&2 'Please select one of the following timezones,' \
|
echo >&2 'Please select one of the following timezones,'
|
||||||
echo >&2 'listed roughly in increasing order' \
|
echo >&2 'listed roughly in increasing order' \
|
||||||
"of distance from $coord".
|
"of distance from $coord".
|
||||||
doselect $regions
|
doselect $regions
|
||||||
region=$select_result
|
region=$select_result
|
||||||
TZ=`say "$distance_table" | $AWK -v region="$region" '
|
TZ=`$AWK \
|
||||||
BEGIN { FS="\t" }
|
-v distance_table="$distance_table" \
|
||||||
$NF == region { print $4 }
|
-v region="$region" '
|
||||||
|
BEGIN {
|
||||||
|
nlines = split(distance_table, line, /\n/)
|
||||||
|
for (nr = 1; nr <= nlines; nr++) {
|
||||||
|
nf = split(line[nr], f, /\t/)
|
||||||
|
if (f[nf] == region) {
|
||||||
|
print f[4]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
'`
|
'`
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# Get list of names of countries in the continent or ocean.
|
case $continent in
|
||||||
countries=`$AWK \
|
time)
|
||||||
|
minute_format='%a %b %d %H:%M'
|
||||||
|
old_minute=`TZ=UTC0 date +"$minute_format"`
|
||||||
|
for i in 1 2 3
|
||||||
|
do
|
||||||
|
time_table_command=`
|
||||||
|
$AWK -v output_times=1 \
|
||||||
|
"$output_distances_or_times" <"$TZ_ZONE_TABLE"
|
||||||
|
`
|
||||||
|
time_table=`eval "$time_table_command"`
|
||||||
|
new_minute=`TZ=UTC0 date +"$minute_format"`
|
||||||
|
case $old_minute in
|
||||||
|
"$new_minute") break;;
|
||||||
|
esac
|
||||||
|
old_minute=$new_minute
|
||||||
|
done
|
||||||
|
echo >&2 "The system says Universal Time is $new_minute."
|
||||||
|
echo >&2 "Assuming that's correct, what is the local time?"
|
||||||
|
eval doselect `
|
||||||
|
say "$time_table" |
|
||||||
|
sort -k2n -k2,5 -k1n |
|
||||||
|
$AWK '{
|
||||||
|
line = $6 " " $7 " " $4 " " $5
|
||||||
|
if (line == oldline) next
|
||||||
|
oldline = line
|
||||||
|
gsub(/'\''/, "&\\\\&&", line)
|
||||||
|
printf "'\''%s'\''\n", line
|
||||||
|
}'
|
||||||
|
`
|
||||||
|
time=$select_result
|
||||||
|
zone_table=`
|
||||||
|
say "$time_table" |
|
||||||
|
$AWK -v time="$time" '{
|
||||||
|
if ($6 " " $7 " " $4 " " $5 == time) {
|
||||||
|
sub(/[^\t]*\t/, "")
|
||||||
|
print
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
`
|
||||||
|
countries=`
|
||||||
|
say "$zone_table" |
|
||||||
|
$AWK \
|
||||||
|
-v continent_re='' \
|
||||||
|
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||||
|
"$output_country_list" |
|
||||||
|
sort -f
|
||||||
|
`
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
zone_table=file
|
||||||
|
# Get list of names of countries in the continent or ocean.
|
||||||
|
countries=`$AWK \
|
||||||
-v continent_re="^$continent/" \
|
-v continent_re="^$continent/" \
|
||||||
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||||
'
|
"$output_country_list" \
|
||||||
BEGIN { FS = "\t" }
|
<"$TZ_ZONE_TABLE" | sort -f
|
||||||
/^#$/ { next }
|
`;;
|
||||||
/^#[^@]/ { next }
|
esac
|
||||||
{
|
|
||||||
commentary = $0 ~ /^#@/
|
|
||||||
if (commentary) {
|
|
||||||
col1ccs = substr($1, 3)
|
|
||||||
conts = $2
|
|
||||||
} else {
|
|
||||||
col1ccs = $1
|
|
||||||
conts = $3
|
|
||||||
}
|
|
||||||
ncc = split(col1ccs, cc, /,/)
|
|
||||||
ncont = split(conts, cont, /,/)
|
|
||||||
for (i = 1; i <= ncc; i++) {
|
|
||||||
elsewhere = commentary
|
|
||||||
for (ci = 1; ci <= ncont; ci++) {
|
|
||||||
if (cont[ci] ~ continent_re) {
|
|
||||||
if (!cc_seen[cc[i]]++) cc_list[++ccs] = cc[i]
|
|
||||||
elsewhere = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (elsewhere) {
|
|
||||||
for (i = 1; i <= ncc; i++) {
|
|
||||||
cc_elsewhere[cc[i]] = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END {
|
|
||||||
while (getline <TZ_COUNTRY_TABLE) {
|
|
||||||
if ($0 !~ /^#/) cc_name[$1] = $2
|
|
||||||
}
|
|
||||||
for (i = 1; i <= ccs; i++) {
|
|
||||||
country = cc_list[i]
|
|
||||||
if (cc_elsewhere[country]) continue
|
|
||||||
if (cc_name[country]) {
|
|
||||||
country = cc_name[country]
|
|
||||||
}
|
|
||||||
print country
|
|
||||||
}
|
|
||||||
}
|
|
||||||
' <"$TZ_ZONE_TABLE" | sort -f`
|
|
||||||
|
|
||||||
|
|
||||||
# If there's more than one country, ask the user which one.
|
# If there's more than one country, ask the user which one.
|
||||||
case $countries in
|
case $countries in
|
||||||
@ -459,6 +551,7 @@ while
|
|||||||
echo >&2 'Please select a country' \
|
echo >&2 'Please select a country' \
|
||||||
'whose clocks agree with yours.'
|
'whose clocks agree with yours.'
|
||||||
doselect $countries
|
doselect $countries
|
||||||
|
country_result=$select_result
|
||||||
country=$select_result;;
|
country=$select_result;;
|
||||||
*)
|
*)
|
||||||
country=$countries
|
country=$countries
|
||||||
@ -466,10 +559,15 @@ while
|
|||||||
|
|
||||||
|
|
||||||
# Get list of timezones in the country.
|
# Get list of timezones in the country.
|
||||||
regions=`$AWK \
|
regions=`
|
||||||
|
case $zone_table in
|
||||||
|
file) cat -- "$TZ_ZONE_TABLE";;
|
||||||
|
*) say "$zone_table";;
|
||||||
|
esac |
|
||||||
|
$AWK \
|
||||||
-v country="$country" \
|
-v country="$country" \
|
||||||
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||||
'
|
'
|
||||||
BEGIN {
|
BEGIN {
|
||||||
FS = "\t"
|
FS = "\t"
|
||||||
cc = country
|
cc = country
|
||||||
@ -482,7 +580,8 @@ while
|
|||||||
}
|
}
|
||||||
/^#/ { next }
|
/^#/ { next }
|
||||||
$1 ~ cc { print $4 }
|
$1 ~ cc { print $4 }
|
||||||
' <"$TZ_ZONE_TABLE"`
|
'
|
||||||
|
`
|
||||||
|
|
||||||
|
|
||||||
# If there's more than one region, ask the user which one.
|
# If there's more than one region, ask the user which one.
|
||||||
@ -490,17 +589,20 @@ while
|
|||||||
*"$newline"*)
|
*"$newline"*)
|
||||||
echo >&2 'Please select one of the following timezones.'
|
echo >&2 'Please select one of the following timezones.'
|
||||||
doselect $regions
|
doselect $regions
|
||||||
region=$select_result;;
|
region=$select_result
|
||||||
*)
|
|
||||||
region=$regions
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Determine TZ from country and region.
|
# Determine TZ from country and region.
|
||||||
TZ=`$AWK \
|
TZ=`
|
||||||
|
case $zone_table in
|
||||||
|
file) cat -- "$TZ_ZONE_TABLE";;
|
||||||
|
*) say "$zone_table";;
|
||||||
|
esac |
|
||||||
|
$AWK \
|
||||||
-v country="$country" \
|
-v country="$country" \
|
||||||
-v region="$region" \
|
-v region="$region" \
|
||||||
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||||
'
|
'
|
||||||
BEGIN {
|
BEGIN {
|
||||||
FS = "\t"
|
FS = "\t"
|
||||||
cc = country
|
cc = country
|
||||||
@ -512,8 +614,9 @@ while
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/^#/ { next }
|
/^#/ { next }
|
||||||
$1 ~ cc && $4 == region { print $3 }
|
$1 ~ cc && ($4 == region || !region) { print $3 }
|
||||||
' <"$TZ_ZONE_TABLE"`
|
'
|
||||||
|
`;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Make sure the corresponding zoneinfo file exists.
|
# Make sure the corresponding zoneinfo file exists.
|
||||||
@ -549,17 +652,21 @@ Universal Time is now: $UTdate."
|
|||||||
# Output TZ info and ask the user to confirm.
|
# Output TZ info and ask the user to confirm.
|
||||||
|
|
||||||
echo >&2 ""
|
echo >&2 ""
|
||||||
echo >&2 "The following information has been given:"
|
echo >&2 "Based on the following information:"
|
||||||
echo >&2 ""
|
echo >&2 ""
|
||||||
case $country%$region%$coord in
|
case $time%$country_result%$region%$coord in
|
||||||
?*%?*%) say >&2 " $country$newline $region";;
|
?*%?*%?*%)
|
||||||
?*%%) say >&2 " $country";;
|
say >&2 " $time$newline $country_result$newline $region";;
|
||||||
%?*%?*) say >&2 " coord $coord$newline $region";;
|
?*%?*%%|?*%%?*%) say >&2 " $time$newline $country_result$region";;
|
||||||
%%?*) say >&2 " coord $coord";;
|
?*%%%) say >&2 " $time";;
|
||||||
|
%?*%?*%) say >&2 " $country_result$newline $region";;
|
||||||
|
%?*%%) say >&2 " $country_result";;
|
||||||
|
%%?*%?*) say >&2 " coord $coord$newline $region";;
|
||||||
|
%%%?*) say >&2 " coord $coord";;
|
||||||
*) say >&2 " TZ='$TZ'"
|
*) say >&2 " TZ='$TZ'"
|
||||||
esac
|
esac
|
||||||
say >&2 ""
|
say >&2 ""
|
||||||
say >&2 "Therefore TZ='$TZ' will be used.$extra_info"
|
say >&2 "TZ='$TZ' will be used.$extra_info"
|
||||||
say >&2 "Is the above information OK?"
|
say >&2 "Is the above information OK?"
|
||||||
|
|
||||||
doselect Yes No
|
doselect Yes No
|
||||||
|
@ -1 +1 @@
|
|||||||
2022g
|
2023c
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
.\" This file is in the public domain, so clarified as of
|
.\" This file is in the public domain, so clarified as of
|
||||||
.\" 2009-05-17 by Arthur David Olson.
|
.\" 2009-05-17 by Arthur David Olson.
|
||||||
.\"
|
|
||||||
.\" $FreeBSD$
|
|
||||||
.\"
|
|
||||||
.Dd December 15, 2022
|
.Dd December 15, 2022
|
||||||
.Dt ZDUMP 8
|
.Dt ZDUMP 8
|
||||||
.Os
|
.Os
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifndef HAVE_SNPRINTF
|
#ifndef HAVE_SNPRINTF
|
||||||
# define HAVE_SNPRINTF (199901 <= __STDC_VERSION__)
|
# define HAVE_SNPRINTF (!PORT_TO_C89 || 199901 <= __STDC_VERSION__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_LOCALTIME_R
|
#ifndef HAVE_LOCALTIME_R
|
||||||
@ -89,7 +89,7 @@ static bool warned;
|
|||||||
static bool errout;
|
static bool errout;
|
||||||
|
|
||||||
static char const *abbr(struct tm const *);
|
static char const *abbr(struct tm const *);
|
||||||
static intmax_t delta(struct tm *, struct tm *) ATTRIBUTE_REPRODUCIBLE;
|
ATTRIBUTE_REPRODUCIBLE static intmax_t delta(struct tm *, struct tm *);
|
||||||
static void dumptime(struct tm const *);
|
static void dumptime(struct tm const *);
|
||||||
static time_t hunt(timezone_t, time_t, time_t, bool);
|
static time_t hunt(timezone_t, time_t, time_t, bool);
|
||||||
static void show(timezone_t, char *, time_t, bool);
|
static void show(timezone_t, char *, time_t, bool);
|
||||||
@ -97,7 +97,7 @@ static void showextrema(timezone_t, char *, time_t, struct tm *, time_t);
|
|||||||
static void showtrans(char const *, struct tm const *, time_t, char const *,
|
static void showtrans(char const *, struct tm const *, time_t, char const *,
|
||||||
char const *);
|
char const *);
|
||||||
static const char *tformat(void);
|
static const char *tformat(void);
|
||||||
static time_t yeartot(intmax_t) ATTRIBUTE_REPRODUCIBLE;
|
ATTRIBUTE_REPRODUCIBLE static time_t yeartot(intmax_t);
|
||||||
|
|
||||||
/* Is C an ASCII digit? */
|
/* Is C an ASCII digit? */
|
||||||
static bool
|
static bool
|
||||||
@ -125,7 +125,7 @@ is_alpha(char a)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ATTRIBUTE_NORETURN void
|
ATTRIBUTE_NORETURN static void
|
||||||
size_overflow(void)
|
size_overflow(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, _("%s: size overflow\n"), progname);
|
fprintf(stderr, _("%s: size overflow\n"), progname);
|
||||||
@ -133,25 +133,37 @@ size_overflow(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Return A + B, exiting if the result would overflow either ptrdiff_t
|
/* Return A + B, exiting if the result would overflow either ptrdiff_t
|
||||||
or size_t. */
|
or size_t. A and B are both nonnegative. */
|
||||||
static ATTRIBUTE_REPRODUCIBLE size_t
|
ATTRIBUTE_REPRODUCIBLE static ptrdiff_t
|
||||||
sumsize(size_t a, size_t b)
|
sumsize(ptrdiff_t a, ptrdiff_t b)
|
||||||
{
|
{
|
||||||
#ifdef ckd_add
|
#ifdef ckd_add
|
||||||
size_t sum;
|
ptrdiff_t sum;
|
||||||
if (!ckd_add(&sum, a, b))
|
if (!ckd_add(&sum, a, b) && sum <= INDEX_MAX)
|
||||||
return sum;
|
return sum;
|
||||||
#else
|
#else
|
||||||
if (a <= SIZE_MAX && b <= SIZE_MAX - a)
|
if (a <= INDEX_MAX && b <= INDEX_MAX - a)
|
||||||
return a + b;
|
return a + b;
|
||||||
#endif
|
#endif
|
||||||
size_overflow();
|
size_overflow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the size of of the string STR, including its trailing NUL.
|
||||||
|
Report an error and exit if this would exceed INDEX_MAX which means
|
||||||
|
pointer subtraction wouldn't work. */
|
||||||
|
static ptrdiff_t
|
||||||
|
xstrsize(char const *str)
|
||||||
|
{
|
||||||
|
size_t len = strlen(str);
|
||||||
|
if (len < INDEX_MAX)
|
||||||
|
return len + 1;
|
||||||
|
size_overflow();
|
||||||
|
}
|
||||||
|
|
||||||
/* Return a pointer to a newly allocated buffer of size SIZE, exiting
|
/* Return a pointer to a newly allocated buffer of size SIZE, exiting
|
||||||
on failure. SIZE should be nonzero. */
|
on failure. SIZE should be positive. */
|
||||||
static void * ATTRIBUTE_MALLOC
|
ATTRIBUTE_MALLOC static void *
|
||||||
xmalloc(size_t size)
|
xmalloc(ptrdiff_t size)
|
||||||
{
|
{
|
||||||
void *p = malloc(size);
|
void *p = malloc(size);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
@ -216,7 +228,7 @@ localtime_r(time_t *tp, struct tm *tmp)
|
|||||||
# undef localtime_rz
|
# undef localtime_rz
|
||||||
# define localtime_rz zdump_localtime_rz
|
# define localtime_rz zdump_localtime_rz
|
||||||
static struct tm *
|
static struct tm *
|
||||||
localtime_rz(timezone_t rz __unused, time_t *tp, struct tm *tmp)
|
localtime_rz(ATTRIBUTE_MAYBE_UNUSED timezone_t rz, time_t *tp, struct tm *tmp)
|
||||||
{
|
{
|
||||||
return localtime_r(tp, tmp);
|
return localtime_r(tp, tmp);
|
||||||
}
|
}
|
||||||
@ -241,7 +253,8 @@ tzalloc(char const *val)
|
|||||||
{
|
{
|
||||||
# if HAVE_SETENV
|
# if HAVE_SETENV
|
||||||
if (setenv("TZ", val, 1) != 0) {
|
if (setenv("TZ", val, 1) != 0) {
|
||||||
perror("setenv");
|
char const *e = strerror(errno);
|
||||||
|
fprintf(stderr, _("%s: setenv: %s\n"), progname, e);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
tzset();
|
tzset();
|
||||||
@ -253,18 +266,18 @@ tzalloc(char const *val)
|
|||||||
static ptrdiff_t fakeenv0size;
|
static ptrdiff_t fakeenv0size;
|
||||||
void *freeable = NULL;
|
void *freeable = NULL;
|
||||||
char **env = fakeenv, **initial_environ;
|
char **env = fakeenv, **initial_environ;
|
||||||
size_t valsize = strlen(val) + 1;
|
ptrdiff_t valsize = xstrsize(val);
|
||||||
if (fakeenv0size < valsize) {
|
if (fakeenv0size < valsize) {
|
||||||
char **e = environ, **to;
|
char **e = environ, **to;
|
||||||
ptrdiff_t initial_nenvptrs = 1; /* Counting the trailing NULL pointer. */
|
ptrdiff_t initial_nenvptrs = 1; /* Counting the trailing NULL pointer. */
|
||||||
|
|
||||||
while (*e++) {
|
while (*e++) {
|
||||||
# ifdef ckd_add
|
# ifdef ckd_add
|
||||||
if (ckd_add(&initial_nenvptrs, initial_envptrs, 1)
|
if (ckd_add(&initial_nenvptrs, initial_nenvptrs, 1)
|
||||||
|| SIZE_MAX < initial_envptrs)
|
|| INDEX_MAX < initial_nenvptrs)
|
||||||
size_overflow();
|
size_overflow();
|
||||||
# else
|
# else
|
||||||
if (initial_nenvptrs == min(PTRDIFF_MAX, SIZE_MAX) / sizeof *environ)
|
if (initial_nenvptrs == INDEX_MAX / sizeof *environ)
|
||||||
size_overflow();
|
size_overflow();
|
||||||
initial_nenvptrs++;
|
initial_nenvptrs++;
|
||||||
# endif
|
# endif
|
||||||
@ -291,7 +304,7 @@ tzalloc(char const *val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tzfree(timezone_t initial_environ)
|
tzfree(ATTRIBUTE_MAYBE_UNUSED timezone_t initial_environ)
|
||||||
{
|
{
|
||||||
# if !HAVE_SETENV
|
# if !HAVE_SETENV
|
||||||
environ = initial_environ;
|
environ = initial_environ;
|
||||||
@ -315,14 +328,16 @@ gmtzinit(void)
|
|||||||
"Link GMT GMT0" line in the "backward" file, and which
|
"Link GMT GMT0" line in the "backward" file, and which
|
||||||
should work on all POSIX platforms. The rest of zdump does not
|
should work on all POSIX platforms. The rest of zdump does not
|
||||||
use the "GMT" abbreviation that comes from this setting, so it
|
use the "GMT" abbreviation that comes from this setting, so it
|
||||||
is OK to use "GMT" here rather than the more-modern "UTC" which
|
is OK to use "GMT" here rather than the modern "UTC" which
|
||||||
would not work on platforms that omit the "backward" file. */
|
would not work on platforms that omit the "backward" file. */
|
||||||
gmtz = tzalloc("GMT");
|
gmtz = tzalloc("GMT");
|
||||||
if (!gmtz) {
|
if (!gmtz) {
|
||||||
static char const gmt0[] = "GMT0";
|
static char const gmt0[] = "GMT0";
|
||||||
gmtz = tzalloc(gmt0);
|
gmtz = tzalloc(gmt0);
|
||||||
if (!gmtz) {
|
if (!gmtz) {
|
||||||
perror(gmt0);
|
char const *e = strerror(errno);
|
||||||
|
fprintf(stderr, _("%s: unknown timezone '%s': %s\n"),
|
||||||
|
progname, gmt0, e);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -402,7 +417,7 @@ abbrok(const char *const abbrp, const char *const zone)
|
|||||||
|
|
||||||
/* Return a time zone abbreviation. If the abbreviation needs to be
|
/* Return a time zone abbreviation. If the abbreviation needs to be
|
||||||
saved, use *BUF (of size *BUFALLOC) to save it, and return the
|
saved, use *BUF (of size *BUFALLOC) to save it, and return the
|
||||||
abbreviation in the possibly-reallocated *BUF. Otherwise, just
|
abbreviation in the possibly reallocated *BUF. Otherwise, just
|
||||||
return the abbreviation. Get the abbreviation from TMP.
|
return the abbreviation. Get the abbreviation from TMP.
|
||||||
Exit on memory allocation failure. */
|
Exit on memory allocation failure. */
|
||||||
static char const *
|
static char const *
|
||||||
@ -412,13 +427,13 @@ saveabbr(char **buf, ptrdiff_t *bufalloc, struct tm const *tmp)
|
|||||||
if (HAVE_LOCALTIME_RZ)
|
if (HAVE_LOCALTIME_RZ)
|
||||||
return ab;
|
return ab;
|
||||||
else {
|
else {
|
||||||
size_t ablen = strlen(ab);
|
ptrdiff_t absize = xstrsize(ab);
|
||||||
if ((size_t)*bufalloc <= ablen) {
|
if (*bufalloc < absize) {
|
||||||
free(*buf);
|
free(*buf);
|
||||||
|
|
||||||
/* Make the new buffer at least twice as long as the old,
|
/* Make the new buffer at least twice as long as the old,
|
||||||
to avoid O(N**2) behavior on repeated calls. */
|
to avoid O(N**2) behavior on repeated calls. */
|
||||||
*bufalloc = sumsize(*bufalloc, ablen + 1);
|
*bufalloc = sumsize(*bufalloc, absize);
|
||||||
|
|
||||||
*buf = xmalloc(*bufalloc);
|
*buf = xmalloc(*bufalloc);
|
||||||
}
|
}
|
||||||
@ -587,7 +602,9 @@ main(int argc, char *argv[])
|
|||||||
struct tm tm, newtm;
|
struct tm tm, newtm;
|
||||||
bool tm_ok;
|
bool tm_ok;
|
||||||
if (!tz) {
|
if (!tz) {
|
||||||
perror(argv[i]);
|
char const *e = strerror(errno);
|
||||||
|
fprintf(stderr, _("%s: unknown timezone '%s': %s\n"),
|
||||||
|
progname, argv[1], e);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if (now) {
|
if (now) {
|
||||||
@ -733,13 +750,9 @@ hunt(timezone_t tz, time_t lot, time_t hit, bool only_ok)
|
|||||||
|
|
||||||
for ( ; ; ) {
|
for ( ; ; ) {
|
||||||
/* T = average of LOT and HIT, rounding down.
|
/* T = average of LOT and HIT, rounding down.
|
||||||
Avoid overflow, even on oddball C89 platforms
|
Avoid overflow. */
|
||||||
where / rounds down and TIME_T_MIN == -TIME_T_MAX
|
int rem_sum = lot % 2 + hit % 2;
|
||||||
so lot / 2 + hit / 2 might overflow. */
|
time_t t = (rem_sum == 2) - (rem_sum < 0) + lot / 2 + hit / 2;
|
||||||
time_t t = (lot / 2
|
|
||||||
- ((lot % 2 + hit % 2) < 0)
|
|
||||||
+ ((lot % 2 + hit % 2) == 2)
|
|
||||||
+ hit / 2);
|
|
||||||
if (t == lot)
|
if (t == lot)
|
||||||
break;
|
break;
|
||||||
tm_ok = my_localtime_rz(tz, &t, &tm) != NULL;
|
tm_ok = my_localtime_rz(tz, &t, &tm) != NULL;
|
||||||
@ -921,7 +934,7 @@ showextrema(timezone_t tz, char *zone, time_t lo, struct tm *lotmp, time_t hi)
|
|||||||
# include <stdarg.h>
|
# include <stdarg.h>
|
||||||
|
|
||||||
/* A substitute for snprintf that is good enough for zdump. */
|
/* A substitute for snprintf that is good enough for zdump. */
|
||||||
static int ATTRIBUTE_FORMAT((printf, 3, 4))
|
ATTRIBUTE_FORMAT((printf, 3, 4)) static int
|
||||||
my_snprintf(char *s, size_t size, char const *format, ...)
|
my_snprintf(char *s, size_t size, char const *format, ...)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
@ -1174,7 +1187,7 @@ abbr(struct tm const *tmp)
|
|||||||
static const char *
|
static const char *
|
||||||
tformat(void)
|
tformat(void)
|
||||||
{
|
{
|
||||||
#if HAVE_GENERIC
|
#if HAVE__GENERIC
|
||||||
/* C11-style _Generic is more likely to return the correct
|
/* C11-style _Generic is more likely to return the correct
|
||||||
format when distinct types have the same size. */
|
format when distinct types have the same size. */
|
||||||
char const *fmt =
|
char const *fmt =
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
.\" This file is in the public domain, so clarified as of
|
.\" This file is in the public domain, so clarified as of
|
||||||
.\" 2009-05-17 by Arthur David Olson.
|
.\" 2009-05-17 by Arthur David Olson.
|
||||||
.\"
|
|
||||||
.\" $FreeBSD$
|
|
||||||
.\"
|
|
||||||
.Dd January 21, 2023
|
.Dd January 21, 2023
|
||||||
.Dt ZIC 8
|
.Dt ZIC 8
|
||||||
.Os
|
.Os
|
||||||
@ -112,7 +109,11 @@ will act as if the input contained a link line of the form
|
|||||||
Link \fItimezone\fP posixrules
|
Link \fItimezone\fP posixrules
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
This feature is obsolete and poorly supported.
|
Unless
|
||||||
|
.Ar timezone
|
||||||
|
is
|
||||||
|
.Dq "\*-" ,
|
||||||
|
this option is obsolete and poorly supported.
|
||||||
Among other things it should not be used for timestamps after the year 2037,
|
Among other things it should not be used for timestamps after the year 2037,
|
||||||
and it should not be combined with
|
and it should not be combined with
|
||||||
.Fl b Cm slim
|
.Fl b Cm slim
|
||||||
@ -135,7 +136,7 @@ to timestamps in the range from
|
|||||||
.Ar lo
|
.Ar lo
|
||||||
and
|
and
|
||||||
.Ar hi
|
.Ar hi
|
||||||
are possibly-signed decimal counts of seconds since the Epoch
|
are possibly signed decimal counts of seconds since the Epoch
|
||||||
(1970-01-01 00:00:00 UTC).
|
(1970-01-01 00:00:00 UTC).
|
||||||
Omitted counts default to extreme values.
|
Omitted counts default to extreme values.
|
||||||
The output files use UT offset 0 and abbreviation
|
The output files use UT offset 0 and abbreviation
|
||||||
@ -227,10 +228,10 @@ for
|
|||||||
The output file does not contain all the information about the
|
The output file does not contain all the information about the
|
||||||
long-term future of a timezone, because the future cannot be summarized as
|
long-term future of a timezone, because the future cannot be summarized as
|
||||||
an extended POSIX TZ string.
|
an extended POSIX TZ string.
|
||||||
For example, as of 2019 this problem
|
For example, as of 2023 this problem
|
||||||
occurs for Iran's daylight-saving rules for the predicted future, as
|
occurs for Morocco's daylight-saving rules, as these rules are based
|
||||||
these rules are based on the Iranian calendar, which cannot be
|
on predictions for when Ramadan will be observed, something that
|
||||||
represented.
|
an extended POSIX TZ string cannot represent.
|
||||||
.It
|
.It
|
||||||
The output contains data that may not be handled properly by client
|
The output contains data that may not be handled properly by client
|
||||||
code designed for older
|
code designed for older
|
||||||
|
@ -66,8 +66,10 @@ enum { FORMAT_LEN_GROWTH_BOUND = 5 };
|
|||||||
# define MKDIR_UMASK 0755
|
# define MKDIR_UMASK 0755
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The minimum alignment of a type, for pre-C23 platforms. */
|
/* The minimum alignment of a type, for pre-C23 platforms.
|
||||||
#if __STDC_VERSION__ < 201112
|
The __SUNPRO_C test is because Oracle Developer Studio 12.6 lacks
|
||||||
|
<stdalign.h> even though __STDC_VERSION__ == 201112. */
|
||||||
|
#if __STDC_VERSION__ < 201112 || defined __SUNPRO_C
|
||||||
# define alignof(type) offsetof(struct { char a; type b; }, b)
|
# define alignof(type) offsetof(struct { char a; type b; }, b)
|
||||||
#elif __STDC_VERSION__ < 202311
|
#elif __STDC_VERSION__ < 202311
|
||||||
# include <stdalign.h>
|
# include <stdalign.h>
|
||||||
@ -461,49 +463,50 @@ static char roll[TZ_MAX_LEAPS];
|
|||||||
** Memory allocation.
|
** Memory allocation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static ATTRIBUTE_NORETURN void
|
ATTRIBUTE_NORETURN static void
|
||||||
memory_exhausted(const char *msg)
|
memory_exhausted(const char *msg)
|
||||||
{
|
{
|
||||||
fprintf(stderr, _("%s: Memory exhausted: %s\n"), progname, msg);
|
fprintf(stderr, _("%s: Memory exhausted: %s\n"), progname, msg);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ATTRIBUTE_NORETURN void
|
ATTRIBUTE_NORETURN static void
|
||||||
size_overflow(void)
|
size_overflow(void)
|
||||||
{
|
{
|
||||||
memory_exhausted(_("size overflow"));
|
memory_exhausted(_("size overflow"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ATTRIBUTE_REPRODUCIBLE size_t
|
ATTRIBUTE_REPRODUCIBLE static ptrdiff_t
|
||||||
size_sum(size_t a, size_t b)
|
size_sum(size_t a, size_t b)
|
||||||
{
|
{
|
||||||
#ifdef ckd_add
|
#ifdef ckd_add
|
||||||
size_t sum;
|
ptrdiff_t sum;
|
||||||
if (!ckd_add(&sum, a, b))
|
if (!ckd_add(&sum, a, b) && sum <= INDEX_MAX)
|
||||||
return sum;
|
return sum;
|
||||||
#else
|
#else
|
||||||
if (b <= SIZE_MAX - a)
|
if (a <= INDEX_MAX && b <= INDEX_MAX - a)
|
||||||
return a + b;
|
return a + b;
|
||||||
#endif
|
#endif
|
||||||
size_overflow();
|
size_overflow();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ATTRIBUTE_REPRODUCIBLE size_t
|
ATTRIBUTE_REPRODUCIBLE static ptrdiff_t
|
||||||
size_product(size_t nitems, size_t itemsize)
|
size_product(ptrdiff_t nitems, ptrdiff_t itemsize)
|
||||||
{
|
{
|
||||||
#ifdef ckd_mul
|
#ifdef ckd_mul
|
||||||
size_t product;
|
ptrdiff_t product;
|
||||||
if (!ckd_mul(&product, nitems, itemsize))
|
if (!ckd_mul(&product, nitems, itemsize) && product <= INDEX_MAX)
|
||||||
return product;
|
return product;
|
||||||
#else
|
#else
|
||||||
if (nitems <= SIZE_MAX / itemsize)
|
ptrdiff_t nitems_max = INDEX_MAX / itemsize;
|
||||||
|
if (nitems <= nitems_max)
|
||||||
return nitems * itemsize;
|
return nitems * itemsize;
|
||||||
#endif
|
#endif
|
||||||
size_overflow();
|
size_overflow();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ATTRIBUTE_REPRODUCIBLE size_t
|
ATTRIBUTE_REPRODUCIBLE static ptrdiff_t
|
||||||
align_to(size_t size, size_t alignment)
|
align_to(ptrdiff_t size, ptrdiff_t alignment)
|
||||||
{
|
{
|
||||||
size_t lo_bits = alignment - 1, sum = size_sum(size, lo_bits);
|
size_t lo_bits = alignment - 1, sum = size_sum(size, lo_bits);
|
||||||
return sum & ~lo_bits;
|
return sum & ~lo_bits;
|
||||||
@ -526,7 +529,7 @@ memcheck(void *ptr)
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * ATTRIBUTE_MALLOC
|
ATTRIBUTE_MALLOC static void *
|
||||||
emalloc(size_t size)
|
emalloc(size_t size)
|
||||||
{
|
{
|
||||||
return memcheck(malloc(size));
|
return memcheck(malloc(size));
|
||||||
@ -538,7 +541,7 @@ erealloc(void *ptr, size_t size)
|
|||||||
return memcheck(realloc(ptr, size));
|
return memcheck(realloc(ptr, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
static char * ATTRIBUTE_MALLOC
|
ATTRIBUTE_MALLOC static char *
|
||||||
estrdup(char const *str)
|
estrdup(char const *str)
|
||||||
{
|
{
|
||||||
return memcheck(strdup(str));
|
return memcheck(strdup(str));
|
||||||
@ -551,11 +554,10 @@ grow_nitems_alloc(ptrdiff_t *nitems_alloc, ptrdiff_t itemsize)
|
|||||||
#if defined ckd_add && defined ckd_mul
|
#if defined ckd_add && defined ckd_mul
|
||||||
ptrdiff_t product;
|
ptrdiff_t product;
|
||||||
if (!ckd_add(nitems_alloc, *nitems_alloc, addend)
|
if (!ckd_add(nitems_alloc, *nitems_alloc, addend)
|
||||||
&& !ckd_mul(&product, *nitems_alloc, itemsize) /* && product <= SIZE_MAX */)
|
&& !ckd_mul(&product, *nitems_alloc, itemsize) && product <= INDEX_MAX)
|
||||||
return product;
|
return product;
|
||||||
#else
|
#else
|
||||||
ptrdiff_t amax = min(PTRDIFF_MAX, SIZE_MAX);
|
if (*nitems_alloc <= ((INDEX_MAX - 1) / 3 * 2) / itemsize) {
|
||||||
if (*nitems_alloc <= ((amax - 1) / 3 * 2) / itemsize) {
|
|
||||||
*nitems_alloc += addend;
|
*nitems_alloc += addend;
|
||||||
return *nitems_alloc * itemsize;
|
return *nitems_alloc * itemsize;
|
||||||
}
|
}
|
||||||
@ -608,7 +610,7 @@ eat(int fnum, lineno num)
|
|||||||
eats(fnum, num, 0, -1);
|
eats(fnum, num, 0, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ATTRIBUTE_FORMAT((printf, 1, 0))
|
ATTRIBUTE_FORMAT((printf, 1, 0)) static void
|
||||||
verror(const char *const string, va_list args)
|
verror(const char *const string, va_list args)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -626,7 +628,7 @@ verror(const char *const string, va_list args)
|
|||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ATTRIBUTE_FORMAT((printf, 1, 2))
|
ATTRIBUTE_FORMAT((printf, 1, 2)) static void
|
||||||
error(const char *const string, ...)
|
error(const char *const string, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
@ -636,7 +638,7 @@ error(const char *const string, ...)
|
|||||||
errors = true;
|
errors = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ATTRIBUTE_FORMAT((printf, 1, 2))
|
ATTRIBUTE_FORMAT((printf, 1, 2)) static void
|
||||||
warning(const char *const string, ...)
|
warning(const char *const string, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
@ -666,7 +668,7 @@ close_file(FILE *stream, char const *dir, char const *name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ATTRIBUTE_NORETURN void
|
ATTRIBUTE_NORETURN static void
|
||||||
usage(FILE *stream, int status)
|
usage(FILE *stream, int status)
|
||||||
{
|
{
|
||||||
fprintf(stream,
|
fprintf(stream,
|
||||||
@ -1435,7 +1437,7 @@ static char *
|
|||||||
relname(char const *target, char const *linkname)
|
relname(char const *target, char const *linkname)
|
||||||
{
|
{
|
||||||
size_t i, taillen, dir_len = 0, dotdots = 0;
|
size_t i, taillen, dir_len = 0, dotdots = 0;
|
||||||
ptrdiff_t dotdotetcsize, linksize = min(PTRDIFF_MAX, SIZE_MAX);
|
ptrdiff_t dotdotetcsize, linksize = INDEX_MAX;
|
||||||
char const *f = target;
|
char const *f = target;
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
if (*linkname == '/') {
|
if (*linkname == '/') {
|
||||||
@ -1710,8 +1712,7 @@ infile(int fnum, char const *name)
|
|||||||
wantcont = false;
|
wantcont = false;
|
||||||
for (num = 1; ; ++num) {
|
for (num = 1; ; ++num) {
|
||||||
enum { bufsize_bound
|
enum { bufsize_bound
|
||||||
= (min(INT_MAX, min(PTRDIFF_MAX, SIZE_MAX))
|
= (min(INT_MAX, INDEX_MAX) / FORMAT_LEN_GROWTH_BOUND) };
|
||||||
/ FORMAT_LEN_GROWTH_BOUND) };
|
|
||||||
char buf[min(_POSIX2_LINE_MAX, bufsize_bound)];
|
char buf[min(_POSIX2_LINE_MAX, bufsize_bound)];
|
||||||
int nfields;
|
int nfields;
|
||||||
char *fields[MAX_FIELDS];
|
char *fields[MAX_FIELDS];
|
||||||
@ -3647,7 +3648,7 @@ lowerit(char a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* case-insensitive equality */
|
/* case-insensitive equality */
|
||||||
static ATTRIBUTE_REPRODUCIBLE bool
|
ATTRIBUTE_REPRODUCIBLE static bool
|
||||||
ciequal(register const char *ap, register const char *bp)
|
ciequal(register const char *ap, register const char *bp)
|
||||||
{
|
{
|
||||||
while (lowerit(*ap) == lowerit(*bp++))
|
while (lowerit(*ap) == lowerit(*bp++))
|
||||||
@ -3656,7 +3657,7 @@ ciequal(register const char *ap, register const char *bp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ATTRIBUTE_REPRODUCIBLE bool
|
ATTRIBUTE_REPRODUCIBLE static bool
|
||||||
itsabbr(register const char *abbr, register const char *word)
|
itsabbr(register const char *abbr, register const char *word)
|
||||||
{
|
{
|
||||||
if (lowerit(*abbr) != lowerit(*word))
|
if (lowerit(*abbr) != lowerit(*word))
|
||||||
@ -3672,7 +3673,7 @@ itsabbr(register const char *abbr, register const char *word)
|
|||||||
|
|
||||||
/* Return true if ABBR is an initial prefix of WORD, ignoring ASCII case. */
|
/* Return true if ABBR is an initial prefix of WORD, ignoring ASCII case. */
|
||||||
|
|
||||||
static ATTRIBUTE_REPRODUCIBLE bool
|
ATTRIBUTE_REPRODUCIBLE static bool
|
||||||
ciprefix(char const *abbr, char const *word)
|
ciprefix(char const *abbr, char const *word)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
@ -3775,14 +3776,14 @@ getfields(char *cp, char **array, int arrayelts)
|
|||||||
return nsubs;
|
return nsubs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ATTRIBUTE_NORETURN void
|
ATTRIBUTE_NORETURN static void
|
||||||
time_overflow(void)
|
time_overflow(void)
|
||||||
{
|
{
|
||||||
error(_("time overflow"));
|
error(_("time overflow"));
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ATTRIBUTE_REPRODUCIBLE zic_t
|
ATTRIBUTE_REPRODUCIBLE static zic_t
|
||||||
oadd(zic_t t1, zic_t t2)
|
oadd(zic_t t1, zic_t t2)
|
||||||
{
|
{
|
||||||
#ifdef ckd_add
|
#ifdef ckd_add
|
||||||
@ -3796,7 +3797,7 @@ oadd(zic_t t1, zic_t t2)
|
|||||||
time_overflow();
|
time_overflow();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ATTRIBUTE_REPRODUCIBLE zic_t
|
ATTRIBUTE_REPRODUCIBLE static zic_t
|
||||||
tadd(zic_t t1, zic_t t2)
|
tadd(zic_t t1, zic_t t2)
|
||||||
{
|
{
|
||||||
#ifdef ckd_add
|
#ifdef ckd_add
|
||||||
|
@ -21,6 +21,7 @@ FBSD_1.0 {
|
|||||||
gmtime;
|
gmtime;
|
||||||
gmtime_r;
|
gmtime_r;
|
||||||
offtime;
|
offtime;
|
||||||
|
offtime_r;
|
||||||
ctime;
|
ctime;
|
||||||
ctime_r;
|
ctime_r;
|
||||||
mktime;
|
mktime;
|
||||||
|
Loading…
Reference in New Issue
Block a user