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
|
||||
'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
|
||||
"Theory and pragmatics of the tz code and data"
|
||||
<https://www.iana.org/time-zones/repository/theory.html>.
|
||||
|
@ -35,22 +35,14 @@ DATAFORM= main
|
||||
|
||||
LOCALTIME= Factory
|
||||
|
||||
# The POSIXRULES macro controls interpretation of nonstandard and obsolete
|
||||
# POSIX-like TZ 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.
|
||||
#
|
||||
# The POSIXRULES macro controls interpretation of POSIX-like TZ
|
||||
# settings like TZ='EET-2EEST' that lack DST transition rules.
|
||||
# If POSIXRULES is '-', no template is installed; this is the default.
|
||||
#
|
||||
# Any other value for POSIXRULES is obsolete and should not be relied on, as:
|
||||
# * It does not work correctly in popular implementations such as GNU/Linux.
|
||||
# * It does not work even in tzcode, except for historical timestamps
|
||||
# that precede the last explicit transition in the POSIXRULES file.
|
||||
# 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,
|
||||
# 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).
|
||||
@ -63,7 +55,7 @@ LOCALTIME= Factory
|
||||
POSIXRULES= -
|
||||
|
||||
# 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.
|
||||
@ -211,7 +203,7 @@ LDLIBS=
|
||||
# -DHAVE_DECL_ENVIRON if <unistd.h> declares 'environ'
|
||||
# -DHAVE_DECL_TIMEGM=0 if <time.h> does not declare timegm
|
||||
# -DHAVE_DIRECT_H if mkdir needs <direct.h> (MS-Windows)
|
||||
# -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=0 to avoid using getrandom
|
||||
# -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
|
||||
# ctime_r and asctime_r incompatibly with the POSIX standard
|
||||
# (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_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
|
||||
@ -229,22 +221,24 @@ LDLIBS=
|
||||
# -DHAVE_POSIX_DECLS=0 if your system's include files do not declare
|
||||
# functions like 'link' or variables like 'tzname' required by POSIX
|
||||
# -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
|
||||
# __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_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_SYS_STAT_H=0 if <sys/stat.h> does not work*
|
||||
# -DHAVE_TZSET=0 if your system lacks a tzset function
|
||||
# -DHAVE_UNISTD_H=0 if <unistd.h> does not work*
|
||||
# -DHAVE_UTMPX_H=0 if <utmpx.h> does not work*
|
||||
# -Dlocale_t=XXX if your system uses XXX instead of locale_t
|
||||
# -DPORT_TO_C89 if tzcode should also run on C89 platforms+
|
||||
# -DRESERVE_STD_EXT_IDS if your platform reserves standard identifiers
|
||||
# with external linkage, e.g., applications cannot define 'localtime'.
|
||||
# -Dssize_t=long on hosts like MS-Windows that lack ssize_t
|
||||
# -DSUPPORT_C89 if the tzcode library should support C89 callers+
|
||||
# -DSUPPRESS_TZDIR to not prepend TZDIR to file names; this has
|
||||
# security implications and is not recommended for general use
|
||||
# -DTHREAD_SAFE to make localtime.c thread-safe, as POSIX requires;
|
||||
@ -256,7 +250,13 @@ LDLIBS=
|
||||
# -DTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory;
|
||||
# the default is system-supplied, typically "/usr/lib/locale"
|
||||
# -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified
|
||||
# DST transitions 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
|
||||
# other than simply getting garbage data
|
||||
# -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
|
||||
#
|
||||
# * 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'".
|
||||
GCC_INSTRUMENT = \
|
||||
@ -351,6 +353,7 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
|
||||
# functions to be added to the time conversion library.
|
||||
# "offtime" is like "gmtime" except that it accepts a second (long) argument
|
||||
# that gives an offset to add to the time_t when converting it.
|
||||
# "offtime_r" is to "offtime" what "gmtime_r" is to "gmtime".
|
||||
# "timelocal" is equivalent to "mktime".
|
||||
# "timeoff" is like "timegm" except that it accepts a second (long) argument
|
||||
# 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
|
||||
# to the end of the "CFLAGS=" line. Otherwise, the functions
|
||||
# "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.
|
||||
# The functions ending in "_z" (or "_rz") are like their unsuffixed
|
||||
# (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_CHAR= '[]'$(SAFE_CHARSET)'-]'
|
||||
|
||||
# These characters are Latin-1, and so are likely to be displayable
|
||||
# even in editors with limited character sets.
|
||||
UNUSUAL_OK_LATIN_1 = «°±»½¾×
|
||||
# This IPA symbol is represented in Unicode as the composition of
|
||||
# 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̯
|
||||
# These non-alphabetic, non-ASCII printable characters are Latin-1,
|
||||
# and so are likely displayable even in editors like XEmacs 21
|
||||
# that have limited display capabilities.
|
||||
UNUSUAL_OK_LATIN_1 = ¡¢£¤¥¦§¨©«¬®¯°±²³´¶·¸¹»¼½¾¿×÷
|
||||
# Non-ASCII non-letters that OK_CHAR allows, as these characters are
|
||||
# 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.
|
||||
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_sorted: backward backzone iso3166.tab zone.tab zone1970.tab
|
||||
check_sorted: backward backzone
|
||||
$(AWK) '/^Link/ {printf "%.5d %s\n", g, $$3} !/./ {g++}' \
|
||||
backward | LC_ALL=C sort -cu
|
||||
$(AWK) '/^Zone/ {print $$2}' backzone | LC_ALL=C sort -cu
|
||||
|
@ -1,5 +1,116 @@
|
||||
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
|
||||
|
||||
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
|
||||
"Expires" directive or "#expires" comment in the leapseconds file.
|
||||
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
|
||||
cannot be converted accurately in the presence of leap seconds, it
|
||||
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
|
||||
that omits leap second information for the range LO..B when LO
|
||||
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.
|
||||
|
||||
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
|
||||
has a nonnegative correction. Without the fix, the output file
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
(Thanks to Arthur David Olson for prototype code, and to Manuela
|
||||
Friedrich for debugging help.)
|
||||
@ -2311,7 +2422,7 @@ Release 2016g - 2016-09-13 08:56:38 -0700
|
||||
names internally.
|
||||
|
||||
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.
|
||||
(Thanks to Jon Skeet for suggesting that an option was needed,
|
||||
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
|
||||
'2016g-23-g50556e3-dirty' instead of the misleading '2016g'.
|
||||
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
|
||||
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,
|
||||
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.)
|
||||
|
||||
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
|
||||
|
||||
'make check' now checks better for properly-sorted data.
|
||||
'make check' now checks better for properly sorted data.
|
||||
|
||||
Changes affecting documentation and commentary
|
||||
|
||||
@ -3557,7 +3668,7 @@ Release 2014a - 2014-03-07 23:30:29 -0800
|
||||
|
||||
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.)
|
||||
|
||||
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
|
||||
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
|
||||
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,
|
||||
Antarctica/Palmer, Asia/Gaza, Asia/Hebron, Asia/Jerusalem,
|
||||
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
|
||||
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.
|
||||
Because of the change for San Luis noted above this change does not
|
||||
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".
|
||||
"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.)
|
||||
|
||||
Data changes affecting behavior of tzselect and similar programs
|
||||
|
||||
Country code BQ is now called the more-common name "Caribbean Netherlands"
|
||||
rather than the more-official "Bonaire, St Eustatius & Saba".
|
||||
Country code BQ is now called the more common name "Caribbean Netherlands"
|
||||
rather than the more official "Bonaire, St Eustatius & Saba".
|
||||
|
||||
Remove from zone.tab the names America/Montreal, America/Shiprock,
|
||||
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.
|
||||
(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.)
|
||||
|
||||
|
||||
@ -5322,7 +5433,7 @@ Release data1998g - 1998-08-11 03:28:35 -0000
|
||||
Release data1998f - 1998-07-20 13:50:00 -0000
|
||||
[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.
|
||||
|
||||
|
||||
|
@ -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];
|
||||
|
||||
/* 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 *
|
||||
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] = {
|
||||
"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_min, timeptr->tm_sec,
|
||||
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);
|
||||
else {
|
||||
errno = EOVERFLOW;
|
||||
@ -106,3 +117,17 @@ asctime(register const struct tm *timeptr)
|
||||
{
|
||||
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
|
||||
.\" 2009-05-17 by Arthur David Olson.
|
||||
.TH date 1
|
||||
.TH date 1 "" "Time Zone Database"
|
||||
.SH NAME
|
||||
date \- show and set date and time
|
||||
.SH SYNOPSIS
|
||||
@ -156,7 +156,8 @@ hexadecimal (leading 0x), preceded by an optional sign.
|
||||
.br
|
||||
/usr/share/zoneinfo timezone information directory
|
||||
.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
|
||||
/usr/share/zoneinfo/GMT for UTC leap seconds
|
||||
.sp
|
||||
|
@ -42,7 +42,7 @@ static void display(const char *, time_t);
|
||||
static void dogmt(void);
|
||||
static void errensure(void);
|
||||
static void timeout(FILE *, const char *, const struct tm *);
|
||||
static ATTRIBUTE_NORETURN void usage(void);
|
||||
ATTRIBUTE_NORETURN static void usage(void);
|
||||
|
||||
int
|
||||
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))
|
||||
errno = ERANGE;
|
||||
if (errno) {
|
||||
perror(optarg);
|
||||
char const *e = strerror(errno);
|
||||
fprintf(stderr, _("date: %s: %s\n"),
|
||||
optarg, e);
|
||||
errensure();
|
||||
exit(retval);
|
||||
}
|
||||
@ -124,10 +126,10 @@ dogmt(void)
|
||||
continue;
|
||||
#if defined ckd_add && defined ckd_mul
|
||||
if (!ckd_add(&n, n, 2) && !ckd_mul(&n, n, sizeof *fakeenv)
|
||||
&& n <= SIZE_MAX)
|
||||
&& n <= INDEX_MAX)
|
||||
fakeenv = malloc(n);
|
||||
#else
|
||||
if (n <= min(PTRDIFF_MAX, SIZE_MAX) / sizeof *fakeenv - 2)
|
||||
if (n <= INDEX_MAX / sizeof *fakeenv - 2)
|
||||
fakeenv = malloc((n + 2) * sizeof *fakeenv);
|
||||
#endif
|
||||
if (fakeenv == NULL) {
|
||||
@ -194,10 +196,9 @@ timeout(FILE *fp, char const *format, struct tm const *tmp)
|
||||
|
||||
for ( ; ; ) {
|
||||
#ifdef ckd_mul
|
||||
bool bigger = !ckd_mul(&size, size, 2) && size <= SIZE_MAX;
|
||||
bool bigger = !ckd_mul(&size, size, 2) && size <= INDEX_MAX;
|
||||
#else
|
||||
bool bigger = (size <= min(PTRDIFF_MAX, SIZE_MAX) / 2
|
||||
&& (size *= 2, true));
|
||||
bool bigger = size <= INDEX_MAX / 2 && (size *= 2, true);
|
||||
#endif
|
||||
char *newcp = bigger ? realloc(cp, size) : NULL;
|
||||
if (!newcp) {
|
||||
|
@ -47,10 +47,6 @@ static int lock(void) { return 0; }
|
||||
static void unlock(void) { }
|
||||
#endif
|
||||
|
||||
#ifndef TZ_ABBR_MAX_LEN
|
||||
# define TZ_ABBR_MAX_LEN 16
|
||||
#endif /* !defined TZ_ABBR_MAX_LEN */
|
||||
|
||||
#ifndef TZ_ABBR_CHAR_SET
|
||||
# define TZ_ABBR_CHAR_SET \
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
|
||||
@ -128,12 +124,11 @@ static char const UNSPEC[] = "-00";
|
||||
for ttunspecified to work without crashing. */
|
||||
enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 };
|
||||
|
||||
#ifdef TZNAME_MAX
|
||||
# define MY_TZNAME_MAX TZNAME_MAX
|
||||
#endif /* defined TZNAME_MAX */
|
||||
#ifndef TZNAME_MAX
|
||||
# define MY_TZNAME_MAX 255
|
||||
#endif /* !defined TZNAME_MAX */
|
||||
/* Limit to time zone abbreviation length in POSIX-style TZ strings.
|
||||
This is distinct from TZ_MAX_CHARS, which limits TZif file contents. */
|
||||
#ifndef TZNAME_MAXIMUM
|
||||
# define TZNAME_MAXIMUM 255
|
||||
#endif
|
||||
|
||||
struct state {
|
||||
int leapcnt;
|
||||
@ -146,7 +141,7 @@ struct state {
|
||||
unsigned char types[TZ_MAX_TIMES];
|
||||
struct ttinfo ttis[TZ_MAX_TYPES];
|
||||
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];
|
||||
|
||||
/* 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_key_t gmtime_key;
|
||||
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_key_t localtime_key;
|
||||
static int localtime_key_error;
|
||||
@ -213,9 +211,14 @@ static int localtime_key_error;
|
||||
** ctime, gmtime, localtime] return values in one of two static
|
||||
** objects: a broken-down time structure and an array of char.
|
||||
** Thanks to Paul Eggert for noting this.
|
||||
**
|
||||
** This requirement was removed in C99, so support it only if requested,
|
||||
** as support is more likely to lead to bugs in badly written programs.
|
||||
*/
|
||||
|
||||
#if SUPPORT_C89
|
||||
static struct tm tm;
|
||||
#endif
|
||||
|
||||
#if 2 <= HAVE_TZNAME + TZ_TIME_T
|
||||
char * tzname[2] = {
|
||||
@ -367,27 +370,28 @@ settzname(void)
|
||||
#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)
|
||||
{
|
||||
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)
|
||||
if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
|
||||
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 &&
|
||||
strcmp(cp, GRANDPARENTED) != 0)
|
||||
*(cp + TZ_ABBR_MAX_LEN) = '\0';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DETECT_TZ_CHANGES
|
||||
@ -898,7 +902,7 @@ is_digit(char c)
|
||||
** Return a pointer to that character.
|
||||
*/
|
||||
|
||||
static ATTRIBUTE_REPRODUCIBLE const char *
|
||||
ATTRIBUTE_REPRODUCIBLE static const char *
|
||||
getzname(register const char *strp)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
|
||||
static ATTRIBUTE_REPRODUCIBLE const char *
|
||||
ATTRIBUTE_REPRODUCIBLE static const char *
|
||||
getqzname(register const char *strp, const int delim)
|
||||
{
|
||||
register int c;
|
||||
@ -1199,14 +1203,12 @@ tzparse(const char *name, struct state *sp, struct state *basep)
|
||||
name = getzname(name);
|
||||
stdlen = name - stdname;
|
||||
}
|
||||
if (!stdlen)
|
||||
if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM))
|
||||
return false;
|
||||
name = getoffset(name, &stdoffset);
|
||||
if (name == NULL)
|
||||
return false;
|
||||
charcnt = stdlen + 1;
|
||||
if (sizeof sp->chars < charcnt)
|
||||
return false;
|
||||
if (basep) {
|
||||
if (0 < basep->timecnt)
|
||||
atlo = basep->ats[basep->timecnt - 1];
|
||||
@ -1233,11 +1235,9 @@ tzparse(const char *name, struct state *sp, struct state *basep)
|
||||
name = getzname(name);
|
||||
dstlen = name - dstname; /* length of DST abbr. */
|
||||
}
|
||||
if (!dstlen)
|
||||
if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM))
|
||||
return false;
|
||||
charcnt += dstlen + 1;
|
||||
if (sizeof sp->chars < charcnt)
|
||||
return false;
|
||||
if (*name != '\0' && *name != ',' && *name != ';') {
|
||||
name = getoffset(name, &dstoffset);
|
||||
if (name == NULL)
|
||||
@ -1511,7 +1511,7 @@ zoneinit(struct state *sp, char const *name)
|
||||
if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL))
|
||||
err = 0;
|
||||
if (err == 0)
|
||||
scrub_abbrs(sp);
|
||||
err = scrub_abbrs(sp);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@ -1732,7 +1732,8 @@ localsub(struct state const *sp, time_t const *timep, int_fast32_t setname,
|
||||
#if NETBSD_INSPIRED
|
||||
|
||||
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);
|
||||
}
|
||||
@ -1766,6 +1767,9 @@ localtime_key_init(void)
|
||||
struct tm *
|
||||
localtime(const time_t *timep)
|
||||
{
|
||||
#if !SUPPORT_C89
|
||||
static struct tm tm;
|
||||
#endif
|
||||
struct tm *p_tm = &tm;
|
||||
|
||||
if (__isthreaded != 0) {
|
||||
@ -1788,7 +1792,7 @@ localtime(const time_t *timep)
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@ -1821,7 +1825,7 @@ gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep,
|
||||
*/
|
||||
|
||||
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);
|
||||
return gmtsub(gmtptr, timep, 0, tmp);
|
||||
@ -1837,6 +1841,9 @@ gmtime_key_init(void)
|
||||
struct tm *
|
||||
gmtime(const time_t *timep)
|
||||
{
|
||||
#if !SUPPORT_C89
|
||||
static struct tm tm;
|
||||
#endif
|
||||
struct tm *p_tm = &tm;
|
||||
|
||||
if (__isthreaded != 0) {
|
||||
@ -1858,16 +1865,50 @@ gmtime(const time_t *timep)
|
||||
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 *
|
||||
offtime(const time_t *timep, long offset)
|
||||
{
|
||||
_once(&gmt_once, gmtcheck);
|
||||
return gmtsub(gmtptr, timep, offset, &tm);
|
||||
#if !SUPPORT_C89
|
||||
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
|
||||
@ -2003,27 +2044,6 @@ timesub(const time_t *timep, int_fast32_t offset,
|
||||
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:
|
||||
** 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
|
||||
|
||||
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);
|
||||
}
|
||||
@ -2487,7 +2507,7 @@ mktime(struct tm *tmp)
|
||||
return t;
|
||||
}
|
||||
|
||||
#ifdef STD_INSPIRED
|
||||
#if STD_INSPIRED
|
||||
time_t
|
||||
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??
|
||||
*/
|
||||
|
||||
#ifdef STD_INSPIRED
|
||||
#if STD_INSPIRED
|
||||
|
||||
/* NETBSD_INSPIRED_EXTERN functions are exported to callers if
|
||||
NETBSD_INSPIRED is defined, and are private otherwise. */
|
||||
@ -2628,7 +2648,7 @@ posix2time(time_t t)
|
||||
return t;
|
||||
}
|
||||
|
||||
#endif /* defined STD_INSPIRED */
|
||||
#endif /* STD_INSPIRED */
|
||||
|
||||
#if TZ_TIME_T
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 2009-05-17 by Arthur David Olson.
|
||||
.TH NEWCTIME 3
|
||||
.TH newctime 3 "" "Time Zone Database"
|
||||
.SH NAME
|
||||
asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
|
||||
.SH SYNOPSIS
|
||||
@ -11,13 +11,13 @@ asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
|
||||
.PP
|
||||
.BR "extern char *tzname[];" " /\(** (optional) \(**/"
|
||||
.PP
|
||||
.B char *ctime(time_t const *clock);
|
||||
.B [[deprecated]] char *ctime(time_t const *clock);
|
||||
.PP
|
||||
.B char *ctime_r(time_t const *clock, char *buf);
|
||||
.PP
|
||||
.B double difftime(time_t time1, time_t time0);
|
||||
.PP
|
||||
.B char *asctime(struct tm const *tm);
|
||||
.B [[deprecated]] char *asctime(struct tm const *tm);
|
||||
.PP
|
||||
.B "char *asctime_r(struct tm const *restrict tm,"
|
||||
.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.
|
||||
.PP
|
||||
The
|
||||
.B ctime
|
||||
function is deprecated starting in C23.
|
||||
Callers can use
|
||||
.B localtime_r
|
||||
and
|
||||
.B strftime
|
||||
instead.
|
||||
.PP
|
||||
The
|
||||
.B localtime
|
||||
and
|
||||
.B gmtime
|
||||
@ -128,6 +137,10 @@ converts a time value contained in a
|
||||
structure to a string,
|
||||
as shown in the above example,
|
||||
and returns a pointer to the string.
|
||||
This function is deprecated starting in C23.
|
||||
Callers can use
|
||||
.B strftime
|
||||
instead.
|
||||
.PP
|
||||
The
|
||||
.B mktime
|
||||
@ -283,7 +296,8 @@ continue to exist in this form in future releases of this code.
|
||||
.br
|
||||
/usr/share/zoneinfo/localtime local timezone file
|
||||
.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
|
||||
/usr/share/zoneinfo/GMT for UTC leap seconds
|
||||
.sp
|
||||
|
@ -35,7 +35,7 @@
|
||||
.\" from: @(#)strftime.3 5.12 (Berkeley) 6/29/91
|
||||
.\" $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
|
||||
strftime \- format date and time
|
||||
.SH SYNOPSIS
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 2009-05-17 by Arthur David Olson.
|
||||
.TH NEWTZSET 3
|
||||
.TH newtzset 3 "" "Time Zone Database"
|
||||
.SH NAME
|
||||
tzset \- initialize time conversion information
|
||||
.SH SYNOPSIS
|
||||
@ -333,7 +333,8 @@ from the rest of the specification.
|
||||
.br
|
||||
/usr/share/zoneinfo/localtime local timezone file
|
||||
.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
|
||||
/usr/share/zoneinfo/GMT for UTC leap seconds
|
||||
.sp
|
||||
|
@ -17,12 +17,25 @@
|
||||
** 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__
|
||||
# define __STDC_VERSION__ 0
|
||||
#endif
|
||||
|
||||
/* 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 false 0
|
||||
# define bool int
|
||||
@ -30,6 +43,10 @@
|
||||
# include <stdbool.h>
|
||||
#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
|
||||
** conversion package to increase confidence in the verification it provides.
|
||||
@ -52,19 +69,19 @@
|
||||
# define HAVE_DECL_ASCTIME_R 1
|
||||
#endif
|
||||
|
||||
#if !defined HAVE_GENERIC && defined __has_extension
|
||||
#if !defined HAVE__GENERIC && defined __has_extension
|
||||
# if __has_extension(c_generic_selections)
|
||||
# define HAVE_GENERIC 1
|
||||
# define HAVE__GENERIC 1
|
||||
# else
|
||||
# define HAVE_GENERIC 0
|
||||
# define HAVE__GENERIC 0
|
||||
# endif
|
||||
#endif
|
||||
/* _Generic is buggy in pre-4.9 GCC. */
|
||||
#if !defined HAVE_GENERIC && defined __GNUC__ && !defined __STRICT_ANSI__
|
||||
# define HAVE_GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
|
||||
#if !defined HAVE__GENERIC && defined __GNUC__ && !defined __STRICT_ANSI__
|
||||
# define HAVE__GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
|
||||
#endif
|
||||
#ifndef HAVE_GENERIC
|
||||
# define HAVE_GENERIC (201112 <= __STDC_VERSION__)
|
||||
#ifndef HAVE__GENERIC
|
||||
# define HAVE__GENERIC (201112 <= __STDC_VERSION__)
|
||||
#endif
|
||||
|
||||
#if !defined HAVE_GETTEXT && defined __has_include
|
||||
@ -100,10 +117,6 @@
|
||||
# define HAVE_STRDUP 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRTOLL
|
||||
# define HAVE_STRTOLL 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SYMLINK
|
||||
# define HAVE_SYMLINK 1
|
||||
#endif /* !defined HAVE_SYMLINK */
|
||||
@ -185,6 +198,9 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#if !PORT_TO_C89
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#include <limits.h> /* for CHAR_BIT et al. */
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -254,10 +270,12 @@
|
||||
# define R_OK 4
|
||||
#endif /* !defined R_OK */
|
||||
|
||||
#if PORT_TO_C89
|
||||
|
||||
/*
|
||||
** Define HAVE_STDINT_H's default value here, rather than at the
|
||||
** 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.
|
||||
*/
|
||||
#if !defined HAVE_STDINT_H && defined __has_include
|
||||
@ -334,6 +352,9 @@ typedef int int_fast32_t;
|
||||
#ifndef INTMAX_MAX
|
||||
# ifdef LLONG_MAX
|
||||
typedef long long intmax_t;
|
||||
# ifndef HAVE_STRTOLL
|
||||
# define HAVE_STRTOLL true
|
||||
# endif
|
||||
# if HAVE_STRTOLL
|
||||
# define strtoimax strtoll
|
||||
# endif
|
||||
@ -379,8 +400,10 @@ typedef unsigned long long uint_fast64_t;
|
||||
#ifndef UINTMAX_MAX
|
||||
# ifdef ULLONG_MAX
|
||||
typedef unsigned long long uintmax_t;
|
||||
# define UINTMAX_MAX ULLONG_MAX
|
||||
# else
|
||||
typedef unsigned long uintmax_t;
|
||||
# define UINTMAX_MAX ULONG_MAX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -396,6 +419,16 @@ typedef unsigned long uintmax_t;
|
||||
# define SIZE_MAX ((size_t) -1)
|
||||
#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
|
||||
hosts, unless compiled with -DHAVE_STDCKDINT_H=0 or with pre-C23 EDG. */
|
||||
#if !defined HAVE_STDCKDINT_H && defined __has_include
|
||||
@ -435,12 +468,25 @@ typedef unsigned long uintmax_t;
|
||||
|
||||
#if (defined __has_c_attribute \
|
||||
&& (202311 <= __STDC_VERSION__ || !defined __STRICT_ANSI__))
|
||||
# define HAVE_HAS_C_ATTRIBUTE true
|
||||
# define HAVE___HAS_C_ATTRIBUTE true
|
||||
#else
|
||||
# define HAVE_HAS_C_ATTRIBUTE false
|
||||
# define HAVE___HAS_C_ATTRIBUTE false
|
||||
#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)
|
||||
# define ATTRIBUTE_FALLTHROUGH [[fallthrough]]
|
||||
# endif
|
||||
@ -453,7 +499,7 @@ typedef unsigned long uintmax_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_HAS_C_ATTRIBUTE
|
||||
#if HAVE___HAS_C_ATTRIBUTE
|
||||
# if __has_c_attribute(maybe_unused)
|
||||
# define ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]]
|
||||
# endif
|
||||
@ -466,7 +512,7 @@ typedef unsigned long uintmax_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_HAS_C_ATTRIBUTE
|
||||
#if HAVE___HAS_C_ATTRIBUTE
|
||||
# if __has_c_attribute(noreturn)
|
||||
# define ATTRIBUTE_NORETURN [[noreturn]]
|
||||
# endif
|
||||
@ -481,7 +527,7 @@ typedef unsigned long uintmax_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_HAS_C_ATTRIBUTE
|
||||
#if HAVE___HAS_C_ATTRIBUTE
|
||||
# if __has_c_attribute(reproducible)
|
||||
# define ATTRIBUTE_REPRODUCIBLE [[reproducible]]
|
||||
# endif
|
||||
@ -494,7 +540,7 @@ typedef unsigned long uintmax_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_HAS_C_ATTRIBUTE
|
||||
#if HAVE___HAS_C_ATTRIBUTE
|
||||
# if __has_c_attribute(unsequenced)
|
||||
# define ATTRIBUTE_UNSEQUENCED [[unsequenced]]
|
||||
# endif
|
||||
@ -507,7 +553,8 @@ typedef unsigned long uintmax_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if __STDC_VERSION__ < 199901 && !defined restrict
|
||||
#if (__STDC_VERSION__ < 199901 && !defined restrict \
|
||||
&& (PORT_TO_C89 || defined _MSC_VER))
|
||||
# define restrict /* empty */
|
||||
#endif
|
||||
|
||||
@ -579,6 +626,8 @@ typedef time_tz tz_time_t;
|
||||
# define mktime_z tz_mktime_z
|
||||
# undef offtime
|
||||
# define offtime tz_offtime
|
||||
# undef offtime_r
|
||||
# define offtime_r tz_offtime_r
|
||||
# undef posix2time
|
||||
# define posix2time tz_posix2time
|
||||
# undef posix2time_z
|
||||
@ -624,11 +673,16 @@ typedef time_tz tz_time_t;
|
||||
# define altzone tz_altzone
|
||||
# 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 *ctime(time_t const *);
|
||||
DEPRECATED_IN_C23 char *ctime(time_t const *);
|
||||
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,
|
||||
struct tm const *restrict);
|
||||
# if HAVE_STRFTIME_L
|
||||
@ -691,10 +745,16 @@ extern long altzone;
|
||||
** 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
|
||||
struct tm *offtime(time_t const *, long);
|
||||
# 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
|
||||
time_t timelocal(struct tm *);
|
||||
# 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);
|
||||
timezone_t tzalloc(char const *);
|
||||
void tzfree(timezone_t);
|
||||
# ifdef STD_INSPIRED
|
||||
# if STD_INSPIRED
|
||||
# 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
|
||||
# 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
|
||||
@ -752,7 +812,7 @@ time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_REPRODUCIBLE;
|
||||
** 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 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
|
||||
either the compiler lacks support for _Generic or time_t is not one
|
||||
of the standard signed integer types. */
|
||||
#if HAVE_GENERIC
|
||||
#if HAVE__GENERIC
|
||||
# define TIME_T_MIN \
|
||||
_Generic((time_t) 0, \
|
||||
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, \
|
||||
default: TIME_T_MAX_NO_PADDING) \
|
||||
: (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
|
||||
# define TIME_T_MIN TIME_T_MIN_NO_PADDING
|
||||
# define TIME_T_MAX TIME_T_MAX_NO_PADDING
|
||||
enum { SIGNED_PADDING_CHECK_NEEDED = true };
|
||||
#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.
|
||||
@ -863,7 +936,7 @@ time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_REPRODUCIBLE;
|
||||
#if HAVE_INCOMPATIBLE_CTIME_R
|
||||
#undef asctime_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 *);
|
||||
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
||||
|
||||
|
@ -116,7 +116,8 @@ static char * _yconv(int, int, bool, bool, char *, char const *);
|
||||
|
||||
#if HAVE_STRFTIME_L
|
||||
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)
|
||||
{
|
||||
/* 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
|
||||
|
||||
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;
|
||||
int saved_errno = errno;
|
||||
|
@ -23,7 +23,7 @@
|
||||
<li><a href="#stability">Interface stability</a></li>
|
||||
<li><a href="#leapsec">Leap seconds</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>
|
||||
</nav>
|
||||
|
||||
@ -443,11 +443,11 @@ in decreasing order of importance:
|
||||
CAT/CAST Central Africa,
|
||||
CET/CEST/CEMT Central European,
|
||||
ChST Chamorro,
|
||||
CST/CDT/CWT/CPT/CDDT Central [North America],
|
||||
CST/CDT/CWT/CPT Central [North America],
|
||||
CST/CDT China,
|
||||
GMT/BST/IST/BDST Greenwich,
|
||||
EAT East Africa,
|
||||
EST/EDT/EWT/EPT/EDDT Eastern [North America],
|
||||
EST/EDT/EWT/EPT Eastern [North America],
|
||||
EET/EEST Eastern European,
|
||||
GST/GDT Guam,
|
||||
HST/HDT/HWT/HPT Hawaii,
|
||||
@ -460,13 +460,13 @@ in decreasing order of importance:
|
||||
MET/MEST Middle European (a backward-compatibility alias for
|
||||
Central European),
|
||||
MSK/MSD Moscow,
|
||||
MST/MDT/MWT/MPT/MDDT Mountain,
|
||||
MST/MDT/MWT/MPT Mountain,
|
||||
NST/NDT/NWT/NPT/NDDT Newfoundland,
|
||||
NST/NDT/NWT/NPT Nome,
|
||||
NZMT/NZST New Zealand through 1945,
|
||||
NZST/NZDT New Zealand 1946–present,
|
||||
PKT/PKST Pakistan,
|
||||
PST/PDT/PWT/PPT/PDDT Pacific,
|
||||
PST/PDT/PWT/PPT Pacific,
|
||||
PST/PDT Philippine,
|
||||
SAST South Africa,
|
||||
SST Samoa,
|
||||
@ -494,7 +494,7 @@ in decreasing order of importance:
|
||||
<p>
|
||||
<small>These abbreviations are:
|
||||
AMT Asunción, Athens;
|
||||
BMT Baghdad, Bangkok, Batavia, Bermuda, Bern, Bogotá, Bridgetown,
|
||||
BMT Baghdad, Bangkok, Batavia, Bermuda, Bern, Bogotá,
|
||||
Brussels, Bucharest;
|
||||
CMT Calamarca, Caracas, Chisinau, Colón, Córdoba;
|
||||
DMT Dublin/Dunsink;
|
||||
@ -506,12 +506,13 @@ in decreasing order of importance:
|
||||
IMT Irkutsk, Istanbul;
|
||||
JMT Jerusalem;
|
||||
KMT Kaunas, Kyiv, Kingston;
|
||||
LMT Lima, Lisbon, local, Luanda;
|
||||
LMT Lima, Lisbon, local;
|
||||
MMT Macassar, Madras, Malé, Managua, Minsk, Monrovia, Montevideo,
|
||||
Moratuwa, Moscow;
|
||||
PLMT Phù Liễn;
|
||||
PMT Paramaribo, Paris, Perm, Pontianak, Prague;
|
||||
PMMT Port Moresby;
|
||||
PPMT Port-au-Prince;
|
||||
QMT Quito;
|
||||
RMT Rangoon, Riga, Rome;
|
||||
SDMT Santo Domingo;
|
||||
@ -519,8 +520,7 @@ in decreasing order of importance:
|
||||
SMT Santiago, Simferopol, Singapore, Stanley;
|
||||
TBMT Tbilisi;
|
||||
TMT Tallinn, Tehran;
|
||||
WMT Warsaw;
|
||||
ZMT Zomba.</small>
|
||||
WMT Warsaw.</small>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@ -791,7 +791,7 @@ href="https://www.dissentmagazine.org/blog/booked-a-global-history-of-time-vanes
|
||||
with days starting at midnight.
|
||||
Although <abbr>UT</abbr> equals <abbr>UTC</abbr> for modern
|
||||
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.
|
||||
Since <abbr>UT</abbr>, <abbr>UT1</abbr>, etc. disagree slightly,
|
||||
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>
|
||||
The relationship between POSIX time (that is, <abbr>UTC</abbr> but
|
||||
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
|
||||
clock officially stops during an inserted leap second, at least one
|
||||
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.
|
||||
Also, POSIX <code>TZ</code> strings cannot deal with daylight
|
||||
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.
|
||||
</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>
|
||||
specifies the beginning and end of <abbr>DST</abbr>.
|
||||
If this is absent, the system supplies its own ruleset
|
||||
for <abbr>DST</abbr>, and its rules can differ from year to year;
|
||||
typically <abbr>US</abbr> <abbr>DST</abbr> rules are used.
|
||||
for <abbr>DST</abbr>, typically current <abbr>US</abbr>
|
||||
<abbr>DST</abbr> rules.
|
||||
</dd>
|
||||
<dt><var>time</var></dt><dd>
|
||||
takes the form
|
||||
@ -974,10 +975,11 @@ an older <code>zic</code>.
|
||||
Traditionally the current <abbr>US</abbr> <abbr>DST</abbr> rules
|
||||
were used to interpret such values, but this meant that the
|
||||
<abbr>US</abbr> <abbr>DST</abbr> rules were compiled into each
|
||||
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
|
||||
States in 1987), all programs that did time conversion had to be
|
||||
recompiled to ensure proper results.
|
||||
States in 1987 and again in 2007), all packages that
|
||||
interpreted <code>TZ</code> values had to be updated
|
||||
to ensure proper results.
|
||||
</li>
|
||||
<li>
|
||||
The <code>TZ</code> environment variable is process-global, which
|
||||
@ -1173,7 +1175,7 @@ The vestigial <abbr>API</abbr>s are:
|
||||
</li>
|
||||
<li>
|
||||
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.
|
||||
They are not in any sense "standard compatible" – some are
|
||||
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
|
||||
recent releases.
|
||||
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.
|
||||
<a href="tz-link.html#download">Downloading
|
||||
the <code><abbr>tz</abbr></code> database</a> describes how releases
|
||||
@ -1268,6 +1270,18 @@ between now and the future time.
|
||||
|
||||
<section>
|
||||
<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>
|
||||
The <code><abbr>tz</abbr></code> code and data can account for leap seconds,
|
||||
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>
|
||||
software that adjusts the kernel clock.
|
||||
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.
|
||||
</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,
|
||||
as opposed to POSIX <code>time_t</code> counts which exclude leap seconds.
|
||||
This modified timescale is converted to <abbr>UTC</abbr>
|
||||
@ -1348,7 +1362,15 @@ They sometimes disagree.
|
||||
</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>
|
||||
Some people's work schedules have used
|
||||
<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
|
||||
.\" 1996-06-05 by Arthur David Olson.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 15, 2022
|
||||
.Dt TIME2POSIX 3
|
||||
.Os
|
||||
|
@ -478,22 +478,35 @@ Supernaw.</td></tr>
|
||||
<tr><td>Total Time</td><td>1:16:20</td></tr>
|
||||
<tr><td><a href="https://www.allmusic.com/album/chicago-transit-authority-mw0000189364">AMG Rating</a></td><td>4 stars</td></tr>
|
||||
<tr><td>Notes</td><td>Includes the song "Does Anybody Really Know What Time It Is?"</td></tr>
|
||||
<tr><td> </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>
|
||||
<h2>Comics</h2>
|
||||
<ul>
|
||||
<li>
|
||||
The webcomic <em>xkcd</em> has the strip
|
||||
"<a href="https://xkcd.com/673/">The Sun</a>" (2009-12-09) and the panels
|
||||
The webcomic <em>xkcd</em> has the strips
|
||||
"<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/1061/">EST</a>" (2012-05-28),
|
||||
"<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/1655/">Doomsday Clock</a>" (2016-03-14),
|
||||
"<a href="https://xkcd.com/1799/">Bad Map Projection: Time Zones</a>"
|
||||
(2017-02-15),
|
||||
"<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),
|
||||
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
|
||||
"<a href="https://what-if.xkcd.com/26/">Leap Seconds</a>" (2012-12-31).
|
||||
</li>
|
||||
|
@ -548,8 +548,8 @@ a <code>SAVE</code> of zero.
|
||||
<ul>
|
||||
|
||||
<li>The <a href="https://en.wikipedia.org/wiki/Tz_database">tz
|
||||
database</a> gives abbreviations for time zones in <i>popular
|
||||
usage</i>, which is not necessarily “correct” by law. For
|
||||
database</a> gives abbreviations for time zones
|
||||
in popular English-language usage. For
|
||||
example, the last line in
|
||||
<code>Zone</code> <code>Pacific/Honolulu</code> (shown below) gives
|
||||
“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
|
||||
<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
|
||||
ahead of Greenwich. By convention, <code>-00</code> is used in a
|
||||
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="#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="#coordinating">Coordinating with governments and distributors</a></li>
|
||||
<li><a href="#commentary">Commentary on the <code><abbr>tz</abbr></code> database</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@ -169,14 +170,14 @@ through <samp>zzz</samp>, and so on).
|
||||
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
|
||||
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
|
||||
"<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>,
|
||||
and are also available in an
|
||||
<a href="ftp://ftp.iana.org/tz/releases/"><abbr
|
||||
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
|
||||
retrieved from <a href="https://github.com">GitHub</a> via the shell
|
||||
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>.
|
||||
</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
|
||||
propagated to clients via operating system updates, so
|
||||
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>
|
||||
</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>
|
||||
<h2 id="commentary">Commentary on the <code><abbr>tz</abbr></code> database</h2>
|
||||
<ul>
|
||||
@ -384,7 +417,7 @@ running the command <code>make rearguard_tarballs</code> and compiling
|
||||
from the resulting tarballs instead.</p>
|
||||
<ul>
|
||||
<li><a href="https://sourceforge.net/projects/vzic/">Vzic</a> is a <a
|
||||
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
|
||||
<code><abbr>tz</abbr></code> source into iCalendar-compatible VTIMEZONE files.
|
||||
Vzic is freely
|
||||
@ -409,7 +442,7 @@ License. DateTime::TimeZone also contains a script
|
||||
transition in the <code><abbr>tz</abbr></code> database.</li>
|
||||
<li>The <a href="https://howardhinnant.github.io/date/tz.html">Time Zone
|
||||
Database Parser</a> is a
|
||||
<a href="https://en.wikipedia.org/wiki/C%2B%2B">C++</a> parser and
|
||||
<a href="https://en.wikipedia.org/wiki/C++">C++</a> parser and
|
||||
runtime library with <a
|
||||
href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0355r7.html">API</a>
|
||||
adopted by
|
||||
@ -419,7 +452,7 @@ It is freely available under the
|
||||
<abbr title="Massachusetts Institute of Technology">MIT</abbr> license.</li>
|
||||
<li><a id="ICU" href="https://icu.unicode.org">International Components for
|
||||
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
|
||||
has a compiler from <code><abbr>tz</abbr></code> source
|
||||
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
|
||||
href="https://www.dia.govt.nz/Daylight-Saving-History">History of
|
||||
Daylight Saving</a>.</dd>
|
||||
<dt>Palestine</dt>
|
||||
<dd>The Ministry of Telecom and IT publishes a <a
|
||||
href="https://mtit.pna.ps/Site/TimeZoon"
|
||||
hreflang="ar">history of clock changes (in Arabic)</a>.</dd>
|
||||
<dt>Portugal</dt>
|
||||
<dd>The Lisbon Astronomical Observatory publishes a
|
||||
<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
|
||||
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
|
||||
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
|
||||
title="Network Time Protocol">NTP</abbr>: The Network
|
||||
Time Protocol</a> (Internet <abbr>RFC</abbr> 5905)
|
||||
@ -1050,7 +1087,7 @@ and to
|
||||
In practice the two configurations also agree for timestamps before
|
||||
1972 even though the historical situation is messy, partly because
|
||||
neither <abbr>UTC</abbr> nor <abbr>TAI</abbr>
|
||||
is well-defined for sufficiently-old timestamps.</li>
|
||||
is well-defined for sufficiently old timestamps.</li>
|
||||
<li><a href="https://developers.google.com/time/smear">Leap Smear</a>
|
||||
discusses how to gradually adjust <abbr>POSIX</abbr> clocks near a
|
||||
leap second so that they disagree with <abbr>UTC</abbr> by at most a
|
||||
@ -1078,8 +1115,12 @@ leap second: its history and possible future</a>.
|
||||
<a href="https://www.ucolick.org/~sla/leapsecs/"><abbr>UTC</abbr>
|
||||
might be redefined
|
||||
without Leap Seconds</a> gives pointers on this
|
||||
contentious issue, which was active until 2015 and could become active
|
||||
again.</li>
|
||||
contentious issue.
|
||||
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>
|
||||
</section>
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 1996-06-05 by Arthur David Olson.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 15, 2022
|
||||
.Dt TZFILE 5
|
||||
.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
|
||||
type after the last transition time if present in the eight-byte data;
|
||||
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
|
||||
type must specify a daylight-saving time abbreviated
|
||||
.Dq "WEST"
|
||||
|
@ -105,20 +105,24 @@ struct tzhead {
|
||||
*/
|
||||
|
||||
#ifndef TZ_MAX_TIMES
|
||||
/* This must be at least 242 for Europe/London with 'zic -b fat'. */
|
||||
# define TZ_MAX_TIMES 2000
|
||||
#endif /* !defined TZ_MAX_TIMES */
|
||||
|
||||
#ifndef TZ_MAX_TYPES
|
||||
/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */
|
||||
/* 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 */
|
||||
#endif /* !defined TZ_MAX_TYPES */
|
||||
|
||||
#ifndef TZ_MAX_CHARS
|
||||
/* This must be at least 40 for America/Anchorage. */
|
||||
# define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
|
||||
/* (limited by what unsigned chars can hold) */
|
||||
#endif /* !defined TZ_MAX_CHARS */
|
||||
|
||||
#ifndef TZ_MAX_LEAPS
|
||||
/* 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 */
|
||||
#endif /* !defined TZ_MAX_LEAPS */
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 2009-05-17 by Arthur David Olson.
|
||||
.TH TZSELECT 8
|
||||
.TH tzselect 8 "" "Time Zone Database"
|
||||
.SH NAME
|
||||
tzselect \- select a timezone
|
||||
.SH SYNOPSIS
|
||||
|
@ -39,7 +39,7 @@ REPORT_BUGS_TO=tz@iana.org
|
||||
: ${AWK=awk}
|
||||
: ${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 '-'.
|
||||
say() {
|
||||
printf '%s\n' "$1"
|
||||
@ -82,8 +82,8 @@ Report bugs to $REPORT_BUGS_TO."
|
||||
|
||||
# Ask the user to select from the function's arguments,
|
||||
# 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,
|
||||
# falling back on a less-nice but portable substitute otherwise.
|
||||
# Exit on EOF or I/O error. Use the shell's nicer 'select' builtin if
|
||||
# available, falling back on a portable substitute otherwise.
|
||||
if
|
||||
case $BASH_VERSION in
|
||||
?*) : ;;
|
||||
@ -197,16 +197,65 @@ 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,
|
||||
# with each column preceded by its distance from 'here'.
|
||||
output_distances='
|
||||
# with each row preceded by its distance from 'here'.
|
||||
# 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 {
|
||||
FS = "\t"
|
||||
while (getline <TZ_COUNTRY_TABLE)
|
||||
if ($0 ~ /^[^#]/)
|
||||
country[$1] = $2
|
||||
country["US"] = "US" # Otherwise the strings get too long.
|
||||
if (!output_times) {
|
||||
while (getline <TZ_COUNTRY_TABLE)
|
||||
if ($0 ~ /^[^#]/)
|
||||
country[$1] = $2
|
||||
country["US"] = "US" # Otherwise the strings get too long.
|
||||
}
|
||||
}
|
||||
function abs(x) {
|
||||
return x < 0 ? -x : x;
|
||||
@ -268,18 +317,35 @@ output_distances='
|
||||
coord_long = convert_longitude(coord)
|
||||
}
|
||||
/^[^#]/ {
|
||||
here_lat = convert_latitude($2)
|
||||
here_long = convert_longitude($2)
|
||||
inline[inlines++] = $0
|
||||
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
|
||||
sep = "\t"
|
||||
ncc = split($1, cc, /,/)
|
||||
split("", item_seen)
|
||||
item_seen[""] = 1
|
||||
for (i = 1; i <= ncc; i++) {
|
||||
line = line sep country[cc[i]]
|
||||
sep = ", "
|
||||
item = cc_used[cc[i]] <= 1 ? country[cc[i]] : $4
|
||||
if (item_seen[item]++) continue
|
||||
line = line sep item
|
||||
sep = "; "
|
||||
}
|
||||
if (NF == 4)
|
||||
line = line " - " $4
|
||||
printf "%g\t%s\n", dist(coord_lat, coord_long, here_lat, here_long), line
|
||||
if (output_times) {
|
||||
fmt = "TZ='\''%s'\'' date +'\''%d %%Y %%m %%d %%H:%%M %%a %%b\t%s'\''\n"
|
||||
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.
|
||||
|
||||
echo >&2 'Please select a continent, ocean, "coord", or "TZ".'
|
||||
echo >&2 'Please select a continent, ocean, "coord", "TZ", or "time".'
|
||||
|
||||
quoted_continents=`
|
||||
$AWK '
|
||||
@ -331,7 +397,8 @@ while
|
||||
eval '
|
||||
doselect '"$quoted_continents"' \
|
||||
"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
|
||||
case $continent in
|
||||
Americas) continent=America;;
|
||||
@ -384,74 +451,99 @@ while
|
||||
distance_table=`$AWK \
|
||||
-v coord="$coord" \
|
||||
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||
"$output_distances" <"$TZ_ZONE_TABLE" |
|
||||
"$output_distances_or_times" <"$TZ_ZONE_TABLE" |
|
||||
sort -n |
|
||||
sed "${location_limit}q"
|
||||
`
|
||||
regions=`say "$distance_table" | $AWK '
|
||||
BEGIN { FS = "\t" }
|
||||
{ print $NF }
|
||||
regions=`$AWK \
|
||||
-v distance_table="$distance_table" '
|
||||
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' \
|
||||
"of distance from $coord".
|
||||
doselect $regions
|
||||
region=$select_result
|
||||
TZ=`say "$distance_table" | $AWK -v region="$region" '
|
||||
BEGIN { FS="\t" }
|
||||
$NF == region { print $4 }
|
||||
TZ=`$AWK \
|
||||
-v distance_table="$distance_table" \
|
||||
-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.
|
||||
countries=`$AWK \
|
||||
case $continent in
|
||||
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 TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||
'
|
||||
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
|
||||
}
|
||||
}
|
||||
' <"$TZ_ZONE_TABLE" | sort -f`
|
||||
|
||||
"$output_country_list" \
|
||||
<"$TZ_ZONE_TABLE" | sort -f
|
||||
`;;
|
||||
esac
|
||||
|
||||
# If there's more than one country, ask the user which one.
|
||||
case $countries in
|
||||
@ -459,6 +551,7 @@ while
|
||||
echo >&2 'Please select a country' \
|
||||
'whose clocks agree with yours.'
|
||||
doselect $countries
|
||||
country_result=$select_result
|
||||
country=$select_result;;
|
||||
*)
|
||||
country=$countries
|
||||
@ -466,10 +559,15 @@ while
|
||||
|
||||
|
||||
# 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 TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||
'
|
||||
'
|
||||
BEGIN {
|
||||
FS = "\t"
|
||||
cc = country
|
||||
@ -482,7 +580,8 @@ while
|
||||
}
|
||||
/^#/ { next }
|
||||
$1 ~ cc { print $4 }
|
||||
' <"$TZ_ZONE_TABLE"`
|
||||
'
|
||||
`
|
||||
|
||||
|
||||
# If there's more than one region, ask the user which one.
|
||||
@ -490,17 +589,20 @@ while
|
||||
*"$newline"*)
|
||||
echo >&2 'Please select one of the following timezones.'
|
||||
doselect $regions
|
||||
region=$select_result;;
|
||||
*)
|
||||
region=$regions
|
||||
region=$select_result
|
||||
esac
|
||||
|
||||
# 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 region="$region" \
|
||||
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
|
||||
'
|
||||
'
|
||||
BEGIN {
|
||||
FS = "\t"
|
||||
cc = country
|
||||
@ -512,8 +614,9 @@ while
|
||||
}
|
||||
}
|
||||
/^#/ { next }
|
||||
$1 ~ cc && $4 == region { print $3 }
|
||||
' <"$TZ_ZONE_TABLE"`
|
||||
$1 ~ cc && ($4 == region || !region) { print $3 }
|
||||
'
|
||||
`;;
|
||||
esac
|
||||
|
||||
# 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.
|
||||
|
||||
echo >&2 ""
|
||||
echo >&2 "The following information has been given:"
|
||||
echo >&2 "Based on the following information:"
|
||||
echo >&2 ""
|
||||
case $country%$region%$coord in
|
||||
?*%?*%) say >&2 " $country$newline $region";;
|
||||
?*%%) say >&2 " $country";;
|
||||
%?*%?*) say >&2 " coord $coord$newline $region";;
|
||||
%%?*) say >&2 " coord $coord";;
|
||||
case $time%$country_result%$region%$coord in
|
||||
?*%?*%?*%)
|
||||
say >&2 " $time$newline $country_result$newline $region";;
|
||||
?*%?*%%|?*%%?*%) say >&2 " $time$newline $country_result$region";;
|
||||
?*%%%) 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'"
|
||||
esac
|
||||
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?"
|
||||
|
||||
doselect Yes No
|
||||
|
@ -1 +1 @@
|
||||
2022g
|
||||
2023c
|
||||
|
@ -1,8 +1,5 @@
|
||||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 2009-05-17 by Arthur David Olson.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 15, 2022
|
||||
.Dt ZDUMP 8
|
||||
.Os
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
# define HAVE_SNPRINTF (199901 <= __STDC_VERSION__)
|
||||
# define HAVE_SNPRINTF (!PORT_TO_C89 || 199901 <= __STDC_VERSION__)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_LOCALTIME_R
|
||||
@ -89,7 +89,7 @@ static bool warned;
|
||||
static bool errout;
|
||||
|
||||
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 time_t hunt(timezone_t, time_t, time_t, bool);
|
||||
static void show(timezone_t, char *, time_t, bool);
|
||||
@ -97,7 +97,7 @@ static void showextrema(timezone_t, char *, time_t, struct tm *, time_t);
|
||||
static void showtrans(char const *, struct tm const *, time_t, char const *,
|
||||
char const *);
|
||||
static const char *tformat(void);
|
||||
static time_t yeartot(intmax_t) ATTRIBUTE_REPRODUCIBLE;
|
||||
ATTRIBUTE_REPRODUCIBLE static time_t yeartot(intmax_t);
|
||||
|
||||
/* Is C an ASCII digit? */
|
||||
static bool
|
||||
@ -125,7 +125,7 @@ is_alpha(char a)
|
||||
}
|
||||
}
|
||||
|
||||
static ATTRIBUTE_NORETURN void
|
||||
ATTRIBUTE_NORETURN static void
|
||||
size_overflow(void)
|
||||
{
|
||||
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
|
||||
or size_t. */
|
||||
static ATTRIBUTE_REPRODUCIBLE size_t
|
||||
sumsize(size_t a, size_t b)
|
||||
or size_t. A and B are both nonnegative. */
|
||||
ATTRIBUTE_REPRODUCIBLE static ptrdiff_t
|
||||
sumsize(ptrdiff_t a, ptrdiff_t b)
|
||||
{
|
||||
#ifdef ckd_add
|
||||
size_t sum;
|
||||
if (!ckd_add(&sum, a, b))
|
||||
ptrdiff_t sum;
|
||||
if (!ckd_add(&sum, a, b) && sum <= INDEX_MAX)
|
||||
return sum;
|
||||
#else
|
||||
if (a <= SIZE_MAX && b <= SIZE_MAX - a)
|
||||
if (a <= INDEX_MAX && b <= INDEX_MAX - a)
|
||||
return a + b;
|
||||
#endif
|
||||
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
|
||||
on failure. SIZE should be nonzero. */
|
||||
static void * ATTRIBUTE_MALLOC
|
||||
xmalloc(size_t size)
|
||||
on failure. SIZE should be positive. */
|
||||
ATTRIBUTE_MALLOC static void *
|
||||
xmalloc(ptrdiff_t size)
|
||||
{
|
||||
void *p = malloc(size);
|
||||
if (!p) {
|
||||
@ -216,7 +228,7 @@ localtime_r(time_t *tp, struct tm *tmp)
|
||||
# undef localtime_rz
|
||||
# define localtime_rz zdump_localtime_rz
|
||||
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);
|
||||
}
|
||||
@ -241,7 +253,8 @@ tzalloc(char const *val)
|
||||
{
|
||||
# if HAVE_SETENV
|
||||
if (setenv("TZ", val, 1) != 0) {
|
||||
perror("setenv");
|
||||
char const *e = strerror(errno);
|
||||
fprintf(stderr, _("%s: setenv: %s\n"), progname, e);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
tzset();
|
||||
@ -253,18 +266,18 @@ tzalloc(char const *val)
|
||||
static ptrdiff_t fakeenv0size;
|
||||
void *freeable = NULL;
|
||||
char **env = fakeenv, **initial_environ;
|
||||
size_t valsize = strlen(val) + 1;
|
||||
ptrdiff_t valsize = xstrsize(val);
|
||||
if (fakeenv0size < valsize) {
|
||||
char **e = environ, **to;
|
||||
ptrdiff_t initial_nenvptrs = 1; /* Counting the trailing NULL pointer. */
|
||||
|
||||
while (*e++) {
|
||||
# ifdef ckd_add
|
||||
if (ckd_add(&initial_nenvptrs, initial_envptrs, 1)
|
||||
|| SIZE_MAX < initial_envptrs)
|
||||
if (ckd_add(&initial_nenvptrs, initial_nenvptrs, 1)
|
||||
|| INDEX_MAX < initial_nenvptrs)
|
||||
size_overflow();
|
||||
# else
|
||||
if (initial_nenvptrs == min(PTRDIFF_MAX, SIZE_MAX) / sizeof *environ)
|
||||
if (initial_nenvptrs == INDEX_MAX / sizeof *environ)
|
||||
size_overflow();
|
||||
initial_nenvptrs++;
|
||||
# endif
|
||||
@ -291,7 +304,7 @@ tzalloc(char const *val)
|
||||
}
|
||||
|
||||
static void
|
||||
tzfree(timezone_t initial_environ)
|
||||
tzfree(ATTRIBUTE_MAYBE_UNUSED timezone_t initial_environ)
|
||||
{
|
||||
# if !HAVE_SETENV
|
||||
environ = initial_environ;
|
||||
@ -315,14 +328,16 @@ gmtzinit(void)
|
||||
"Link GMT GMT0" line in the "backward" file, and which
|
||||
should work on all POSIX platforms. The rest of zdump does not
|
||||
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. */
|
||||
gmtz = tzalloc("GMT");
|
||||
if (!gmtz) {
|
||||
static char const gmt0[] = "GMT0";
|
||||
gmtz = tzalloc(gmt0);
|
||||
if (!gmtz) {
|
||||
perror(gmt0);
|
||||
char const *e = strerror(errno);
|
||||
fprintf(stderr, _("%s: unknown timezone '%s': %s\n"),
|
||||
progname, gmt0, e);
|
||||
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
|
||||
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.
|
||||
Exit on memory allocation failure. */
|
||||
static char const *
|
||||
@ -412,13 +427,13 @@ saveabbr(char **buf, ptrdiff_t *bufalloc, struct tm const *tmp)
|
||||
if (HAVE_LOCALTIME_RZ)
|
||||
return ab;
|
||||
else {
|
||||
size_t ablen = strlen(ab);
|
||||
if ((size_t)*bufalloc <= ablen) {
|
||||
ptrdiff_t absize = xstrsize(ab);
|
||||
if (*bufalloc < absize) {
|
||||
free(*buf);
|
||||
|
||||
/* Make the new buffer at least twice as long as the old,
|
||||
to avoid O(N**2) behavior on repeated calls. */
|
||||
*bufalloc = sumsize(*bufalloc, ablen + 1);
|
||||
*bufalloc = sumsize(*bufalloc, absize);
|
||||
|
||||
*buf = xmalloc(*bufalloc);
|
||||
}
|
||||
@ -587,7 +602,9 @@ main(int argc, char *argv[])
|
||||
struct tm tm, newtm;
|
||||
bool tm_ok;
|
||||
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;
|
||||
}
|
||||
if (now) {
|
||||
@ -733,13 +750,9 @@ hunt(timezone_t tz, time_t lot, time_t hit, bool only_ok)
|
||||
|
||||
for ( ; ; ) {
|
||||
/* T = average of LOT and HIT, rounding down.
|
||||
Avoid overflow, even on oddball C89 platforms
|
||||
where / rounds down and TIME_T_MIN == -TIME_T_MAX
|
||||
so lot / 2 + hit / 2 might overflow. */
|
||||
time_t t = (lot / 2
|
||||
- ((lot % 2 + hit % 2) < 0)
|
||||
+ ((lot % 2 + hit % 2) == 2)
|
||||
+ hit / 2);
|
||||
Avoid overflow. */
|
||||
int rem_sum = lot % 2 + hit % 2;
|
||||
time_t t = (rem_sum == 2) - (rem_sum < 0) + lot / 2 + hit / 2;
|
||||
if (t == lot)
|
||||
break;
|
||||
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>
|
||||
|
||||
/* 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, ...)
|
||||
{
|
||||
int n;
|
||||
@ -1174,7 +1187,7 @@ abbr(struct tm const *tmp)
|
||||
static const char *
|
||||
tformat(void)
|
||||
{
|
||||
#if HAVE_GENERIC
|
||||
#if HAVE__GENERIC
|
||||
/* C11-style _Generic is more likely to return the correct
|
||||
format when distinct types have the same size. */
|
||||
char const *fmt =
|
||||
|
@ -1,8 +1,5 @@
|
||||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 2009-05-17 by Arthur David Olson.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 21, 2023
|
||||
.Dt ZIC 8
|
||||
.Os
|
||||
@ -112,7 +109,11 @@ will act as if the input contained a link line of the form
|
||||
Link \fItimezone\fP posixrules
|
||||
.Ed
|
||||
.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,
|
||||
and it should not be combined with
|
||||
.Fl b Cm slim
|
||||
@ -135,7 +136,7 @@ to timestamps in the range from
|
||||
.Ar lo
|
||||
and
|
||||
.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).
|
||||
Omitted counts default to extreme values.
|
||||
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
|
||||
long-term future of a timezone, because the future cannot be summarized as
|
||||
an extended POSIX TZ string.
|
||||
For example, as of 2019 this problem
|
||||
occurs for Iran's daylight-saving rules for the predicted future, as
|
||||
these rules are based on the Iranian calendar, which cannot be
|
||||
represented.
|
||||
For example, as of 2023 this problem
|
||||
occurs for Morocco's daylight-saving rules, as these rules are based
|
||||
on predictions for when Ramadan will be observed, something that
|
||||
an extended POSIX TZ string cannot represent.
|
||||
.It
|
||||
The output contains data that may not be handled properly by client
|
||||
code designed for older
|
||||
|
@ -66,8 +66,10 @@ enum { FORMAT_LEN_GROWTH_BOUND = 5 };
|
||||
# define MKDIR_UMASK 0755
|
||||
#endif
|
||||
|
||||
/* The minimum alignment of a type, for pre-C23 platforms. */
|
||||
#if __STDC_VERSION__ < 201112
|
||||
/* The minimum alignment of a type, for pre-C23 platforms.
|
||||
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)
|
||||
#elif __STDC_VERSION__ < 202311
|
||||
# include <stdalign.h>
|
||||
@ -461,49 +463,50 @@ static char roll[TZ_MAX_LEAPS];
|
||||
** Memory allocation.
|
||||
*/
|
||||
|
||||
static ATTRIBUTE_NORETURN void
|
||||
ATTRIBUTE_NORETURN static void
|
||||
memory_exhausted(const char *msg)
|
||||
{
|
||||
fprintf(stderr, _("%s: Memory exhausted: %s\n"), progname, msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static ATTRIBUTE_NORETURN void
|
||||
ATTRIBUTE_NORETURN static void
|
||||
size_overflow(void)
|
||||
{
|
||||
memory_exhausted(_("size overflow"));
|
||||
}
|
||||
|
||||
static ATTRIBUTE_REPRODUCIBLE size_t
|
||||
ATTRIBUTE_REPRODUCIBLE static ptrdiff_t
|
||||
size_sum(size_t a, size_t b)
|
||||
{
|
||||
#ifdef ckd_add
|
||||
size_t sum;
|
||||
if (!ckd_add(&sum, a, b))
|
||||
ptrdiff_t sum;
|
||||
if (!ckd_add(&sum, a, b) && sum <= INDEX_MAX)
|
||||
return sum;
|
||||
#else
|
||||
if (b <= SIZE_MAX - a)
|
||||
if (a <= INDEX_MAX && b <= INDEX_MAX - a)
|
||||
return a + b;
|
||||
#endif
|
||||
size_overflow();
|
||||
}
|
||||
|
||||
static ATTRIBUTE_REPRODUCIBLE size_t
|
||||
size_product(size_t nitems, size_t itemsize)
|
||||
ATTRIBUTE_REPRODUCIBLE static ptrdiff_t
|
||||
size_product(ptrdiff_t nitems, ptrdiff_t itemsize)
|
||||
{
|
||||
#ifdef ckd_mul
|
||||
size_t product;
|
||||
if (!ckd_mul(&product, nitems, itemsize))
|
||||
ptrdiff_t product;
|
||||
if (!ckd_mul(&product, nitems, itemsize) && product <= INDEX_MAX)
|
||||
return product;
|
||||
#else
|
||||
if (nitems <= SIZE_MAX / itemsize)
|
||||
ptrdiff_t nitems_max = INDEX_MAX / itemsize;
|
||||
if (nitems <= nitems_max)
|
||||
return nitems * itemsize;
|
||||
#endif
|
||||
size_overflow();
|
||||
}
|
||||
|
||||
static ATTRIBUTE_REPRODUCIBLE size_t
|
||||
align_to(size_t size, size_t alignment)
|
||||
ATTRIBUTE_REPRODUCIBLE static ptrdiff_t
|
||||
align_to(ptrdiff_t size, ptrdiff_t alignment)
|
||||
{
|
||||
size_t lo_bits = alignment - 1, sum = size_sum(size, lo_bits);
|
||||
return sum & ~lo_bits;
|
||||
@ -526,7 +529,7 @@ memcheck(void *ptr)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void * ATTRIBUTE_MALLOC
|
||||
ATTRIBUTE_MALLOC static void *
|
||||
emalloc(size_t size)
|
||||
{
|
||||
return memcheck(malloc(size));
|
||||
@ -538,7 +541,7 @@ erealloc(void *ptr, size_t size)
|
||||
return memcheck(realloc(ptr, size));
|
||||
}
|
||||
|
||||
static char * ATTRIBUTE_MALLOC
|
||||
ATTRIBUTE_MALLOC static char *
|
||||
estrdup(char const *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
|
||||
ptrdiff_t product;
|
||||
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;
|
||||
#else
|
||||
ptrdiff_t amax = min(PTRDIFF_MAX, SIZE_MAX);
|
||||
if (*nitems_alloc <= ((amax - 1) / 3 * 2) / itemsize) {
|
||||
if (*nitems_alloc <= ((INDEX_MAX - 1) / 3 * 2) / itemsize) {
|
||||
*nitems_alloc += addend;
|
||||
return *nitems_alloc * itemsize;
|
||||
}
|
||||
@ -608,7 +610,7 @@ eat(int fnum, lineno num)
|
||||
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)
|
||||
{
|
||||
/*
|
||||
@ -626,7 +628,7 @@ verror(const char *const string, va_list args)
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static void ATTRIBUTE_FORMAT((printf, 1, 2))
|
||||
ATTRIBUTE_FORMAT((printf, 1, 2)) static void
|
||||
error(const char *const string, ...)
|
||||
{
|
||||
va_list args;
|
||||
@ -636,7 +638,7 @@ error(const char *const string, ...)
|
||||
errors = true;
|
||||
}
|
||||
|
||||
static void ATTRIBUTE_FORMAT((printf, 1, 2))
|
||||
ATTRIBUTE_FORMAT((printf, 1, 2)) static void
|
||||
warning(const char *const string, ...)
|
||||
{
|
||||
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)
|
||||
{
|
||||
fprintf(stream,
|
||||
@ -1435,7 +1437,7 @@ static char *
|
||||
relname(char const *target, char const *linkname)
|
||||
{
|
||||
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 *result = NULL;
|
||||
if (*linkname == '/') {
|
||||
@ -1710,8 +1712,7 @@ infile(int fnum, char const *name)
|
||||
wantcont = false;
|
||||
for (num = 1; ; ++num) {
|
||||
enum { bufsize_bound
|
||||
= (min(INT_MAX, min(PTRDIFF_MAX, SIZE_MAX))
|
||||
/ FORMAT_LEN_GROWTH_BOUND) };
|
||||
= (min(INT_MAX, INDEX_MAX) / FORMAT_LEN_GROWTH_BOUND) };
|
||||
char buf[min(_POSIX2_LINE_MAX, bufsize_bound)];
|
||||
int nfields;
|
||||
char *fields[MAX_FIELDS];
|
||||
@ -3647,7 +3648,7 @@ lowerit(char a)
|
||||
}
|
||||
|
||||
/* case-insensitive equality */
|
||||
static ATTRIBUTE_REPRODUCIBLE bool
|
||||
ATTRIBUTE_REPRODUCIBLE static bool
|
||||
ciequal(register const char *ap, register const char *bp)
|
||||
{
|
||||
while (lowerit(*ap) == lowerit(*bp++))
|
||||
@ -3656,7 +3657,7 @@ ciequal(register const char *ap, register const char *bp)
|
||||
return false;
|
||||
}
|
||||
|
||||
static ATTRIBUTE_REPRODUCIBLE bool
|
||||
ATTRIBUTE_REPRODUCIBLE static bool
|
||||
itsabbr(register const char *abbr, register const char *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. */
|
||||
|
||||
static ATTRIBUTE_REPRODUCIBLE bool
|
||||
ATTRIBUTE_REPRODUCIBLE static bool
|
||||
ciprefix(char const *abbr, char const *word)
|
||||
{
|
||||
do
|
||||
@ -3775,14 +3776,14 @@ getfields(char *cp, char **array, int arrayelts)
|
||||
return nsubs;
|
||||
}
|
||||
|
||||
static ATTRIBUTE_NORETURN void
|
||||
ATTRIBUTE_NORETURN static void
|
||||
time_overflow(void)
|
||||
{
|
||||
error(_("time overflow"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static ATTRIBUTE_REPRODUCIBLE zic_t
|
||||
ATTRIBUTE_REPRODUCIBLE static zic_t
|
||||
oadd(zic_t t1, zic_t t2)
|
||||
{
|
||||
#ifdef ckd_add
|
||||
@ -3796,7 +3797,7 @@ oadd(zic_t t1, zic_t t2)
|
||||
time_overflow();
|
||||
}
|
||||
|
||||
static ATTRIBUTE_REPRODUCIBLE zic_t
|
||||
ATTRIBUTE_REPRODUCIBLE static zic_t
|
||||
tadd(zic_t t1, zic_t t2)
|
||||
{
|
||||
#ifdef ckd_add
|
||||
|
@ -21,6 +21,7 @@ FBSD_1.0 {
|
||||
gmtime;
|
||||
gmtime_r;
|
||||
offtime;
|
||||
offtime_r;
|
||||
ctime;
|
||||
ctime_r;
|
||||
mktime;
|
||||
|
Loading…
Reference in New Issue
Block a user