Update tzcode to 2025b
MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D52103
This commit is contained in:
+17
-15
@@ -137,7 +137,7 @@ TIME_T_ALTERNATIVES_TAIL = int_least32_t.ck uint_least32_t.ck \
|
|||||||
uint_least64_t.ck
|
uint_least64_t.ck
|
||||||
|
|
||||||
# What kind of TZif data files to generate. (TZif is the binary time
|
# What kind of TZif data files to generate. (TZif is the binary time
|
||||||
# zone data format that zic generates; see Internet RFC 8536.)
|
# zone data format that zic generates; see Internet RFC 9636.)
|
||||||
# If you want only POSIX time, with time values interpreted as
|
# If you want only POSIX time, with time values interpreted as
|
||||||
# seconds since the epoch (not counting leap seconds), use
|
# seconds since the epoch (not counting leap seconds), use
|
||||||
# REDO= posix_only
|
# REDO= posix_only
|
||||||
@@ -255,6 +255,7 @@ LDLIBS=
|
|||||||
# -DHAVE_UNISTD_H=0 if <unistd.h> does not work*
|
# -DHAVE_UNISTD_H=0 if <unistd.h> does not work*
|
||||||
# -DHAVE_UTMPX_H=0 if <utmpx.h> does not work*
|
# -DHAVE_UTMPX_H=0 if <utmpx.h> does not work*
|
||||||
# -Dlocale_t=XXX if your system uses XXX instead of locale_t
|
# -Dlocale_t=XXX if your system uses XXX instead of locale_t
|
||||||
|
# -DMKTIME_MIGHT_OVERFLOW if mktime might fail due to time_t overflow
|
||||||
# -DPORT_TO_C89 if tzcode should also run on mostly-C89 platforms+
|
# -DPORT_TO_C89 if tzcode should also run on mostly-C89 platforms+
|
||||||
# Typically it is better to use a later standard. For example,
|
# Typically it is better to use a later standard. For example,
|
||||||
# with GCC 4.9.4 (2016), prefer '-std=gnu11' to '-DPORT_TO_C89'.
|
# with GCC 4.9.4 (2016), prefer '-std=gnu11' to '-DPORT_TO_C89'.
|
||||||
@@ -262,7 +263,7 @@ LDLIBS=
|
|||||||
# feature (integers at least 64 bits wide) and maybe more.
|
# feature (integers at least 64 bits wide) and maybe more.
|
||||||
# -DRESERVE_STD_EXT_IDS if your platform reserves standard identifiers
|
# -DRESERVE_STD_EXT_IDS if your platform reserves standard identifiers
|
||||||
# with external linkage, e.g., applications cannot define 'localtime'.
|
# with external linkage, e.g., applications cannot define 'localtime'.
|
||||||
# -Dssize_t=long on hosts like MS-Windows that lack ssize_t
|
# -Dssize_t=int on hosts like MS-Windows that lack ssize_t
|
||||||
# -DSUPPORT_C89=0 if the tzcode library should not support C89 callers
|
# -DSUPPORT_C89=0 if the tzcode library should not support C89 callers
|
||||||
# Although -DSUPPORT_C89=0 might work around latent bugs in callers,
|
# Although -DSUPPORT_C89=0 might work around latent bugs in callers,
|
||||||
# it does not conform to POSIX.
|
# it does not conform to POSIX.
|
||||||
@@ -285,7 +286,7 @@ LDLIBS=
|
|||||||
# This mishandles some past timestamps, as US DST rules have changed.
|
# This mishandles some past timestamps, as US DST rules have changed.
|
||||||
# It also mishandles settings like TZ='EET-2EEST' for eastern Europe,
|
# It also mishandles settings like TZ='EET-2EEST' for eastern Europe,
|
||||||
# as Europe and US DST rules differ.
|
# as Europe and US DST rules differ.
|
||||||
# -DTZNAME_MAXIMUM=N to limit time zone abbreviations to N bytes (default 255)
|
# -DTZNAME_MAXIMUM=N to limit time zone abbreviations to N bytes (default 254)
|
||||||
# -DUNINIT_TRAP if reading uninitialized storage can cause problems
|
# -DUNINIT_TRAP if reading uninitialized storage can cause problems
|
||||||
# other than simply getting garbage data
|
# other than simply getting garbage data
|
||||||
# -DUSE_LTZ=0 to build zdump with the system time zone library
|
# -DUSE_LTZ=0 to build zdump with the system time zone library
|
||||||
@@ -319,7 +320,8 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 \
|
|||||||
$(GCC_INSTRUMENT) \
|
$(GCC_INSTRUMENT) \
|
||||||
-Wall -Wextra \
|
-Wall -Wextra \
|
||||||
-Walloc-size-larger-than=100000 -Warray-bounds=2 \
|
-Walloc-size-larger-than=100000 -Warray-bounds=2 \
|
||||||
-Wbad-function-cast -Wbidi-chars=any,ucn -Wcast-align=strict -Wdate-time \
|
-Wbad-function-cast -Wbidi-chars=any,ucn -Wcast-align=strict -Wcast-qual \
|
||||||
|
-Wdate-time \
|
||||||
-Wdeclaration-after-statement -Wdouble-promotion \
|
-Wdeclaration-after-statement -Wdouble-promotion \
|
||||||
-Wduplicated-branches -Wduplicated-cond -Wflex-array-member-not-at-end \
|
-Wduplicated-branches -Wduplicated-cond -Wflex-array-member-not-at-end \
|
||||||
-Wformat=2 -Wformat-overflow=2 -Wformat-signedness -Wformat-truncation \
|
-Wformat=2 -Wformat-overflow=2 -Wformat-signedness -Wformat-truncation \
|
||||||
@@ -336,7 +338,7 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 \
|
|||||||
-Wsuggest-attribute=noreturn -Wsuggest-attribute=pure \
|
-Wsuggest-attribute=noreturn -Wsuggest-attribute=pure \
|
||||||
-Wtrampolines -Wundef -Wunused-macros -Wuse-after-free=3 \
|
-Wtrampolines -Wundef -Wunused-macros -Wuse-after-free=3 \
|
||||||
-Wvariadic-macros -Wvla -Wwrite-strings \
|
-Wvariadic-macros -Wvla -Wwrite-strings \
|
||||||
-Wno-format-nonliteral -Wno-sign-compare
|
-Wno-format-nonliteral -Wno-sign-compare -Wno-type-limits
|
||||||
#
|
#
|
||||||
# If your system has a "GMT offset" field in its "struct tm"s
|
# If your system has a "GMT offset" field in its "struct tm"s
|
||||||
# (or if you decide to add such a field in your system's "time.h" file),
|
# (or if you decide to add such a field in your system's "time.h" file),
|
||||||
@@ -614,8 +616,8 @@ TZS_YEAR= 2050
|
|||||||
TZS_CUTOFF_FLAG= -c $(TZS_YEAR)
|
TZS_CUTOFF_FLAG= -c $(TZS_YEAR)
|
||||||
TZS= to$(TZS_YEAR).tzs
|
TZS= to$(TZS_YEAR).tzs
|
||||||
TZS_NEW= to$(TZS_YEAR)new.tzs
|
TZS_NEW= to$(TZS_YEAR)new.tzs
|
||||||
TZS_DEPS= $(YDATA) asctime.c localtime.c \
|
TZS_DEPS= $(YDATA) localtime.c private.h \
|
||||||
private.h tzfile.h zdump.c zic.c
|
strftime.c tzfile.h zdump.c zic.c
|
||||||
TZDATA_DIST = $(COMMON) $(DATA) $(MISC)
|
TZDATA_DIST = $(COMMON) $(DATA) $(MISC)
|
||||||
# EIGHT_YARDS is just a yard short of the whole ENCHILADA.
|
# EIGHT_YARDS is just a yard short of the whole ENCHILADA.
|
||||||
EIGHT_YARDS = $(TZDATA_DIST) $(DOCS) $(SOURCES) tzdata.zi
|
EIGHT_YARDS = $(TZDATA_DIST) $(DOCS) $(SOURCES) tzdata.zi
|
||||||
@@ -855,10 +857,10 @@ tzselect: tzselect.ksh version
|
|||||||
chmod +x $@.out
|
chmod +x $@.out
|
||||||
mv $@.out $@
|
mv $@.out $@
|
||||||
|
|
||||||
check: check_mild back.ck
|
check: check_mild back.ck now.ck
|
||||||
check_mild: check_web check_zishrink \
|
check_mild: check_web check_zishrink \
|
||||||
character-set.ck white-space.ck links.ck mainguard.ck \
|
character-set.ck white-space.ck links.ck mainguard.ck \
|
||||||
name-lengths.ck now.ck slashed-abbrs.ck sorted.ck \
|
name-lengths.ck slashed-abbrs.ck sorted.ck \
|
||||||
tables.ck ziguard.ck tzs.ck
|
tables.ck ziguard.ck tzs.ck
|
||||||
|
|
||||||
# True if UTF8_LOCALE does not work;
|
# True if UTF8_LOCALE does not work;
|
||||||
@@ -1103,7 +1105,7 @@ set-timestamps.out: $(EIGHT_YARDS)
|
|||||||
touch -md @1 test.out; then \
|
touch -md @1 test.out; then \
|
||||||
rm -f test.out && \
|
rm -f test.out && \
|
||||||
for file in $$files; do \
|
for file in $$files; do \
|
||||||
if git diff --quiet $$file; then \
|
if git diff --quiet HEAD $$file; then \
|
||||||
time=$$(TZ=UTC0 git log -1 \
|
time=$$(TZ=UTC0 git log -1 \
|
||||||
--format='tformat:%cd' \
|
--format='tformat:%cd' \
|
||||||
--date='format:%Y-%m-%dT%H:%M:%SZ' \
|
--date='format:%Y-%m-%dT%H:%M:%SZ' \
|
||||||
@@ -1354,13 +1356,13 @@ long-long.ck unsigned.ck: $(VERSION_DEPS)
|
|||||||
zonenames: tzdata.zi
|
zonenames: tzdata.zi
|
||||||
@$(AWK) '/^Z/ { print $$2 } /^L/ { print $$3 }' tzdata.zi
|
@$(AWK) '/^Z/ { print $$2 } /^L/ { print $$3 }' tzdata.zi
|
||||||
|
|
||||||
asctime.o: private.h tzfile.h
|
asctime.o: private.h
|
||||||
date.o: private.h
|
date.o: private.h
|
||||||
difftime.o: private.h
|
difftime.o: private.h
|
||||||
localtime.o: private.h tzfile.h tzdir.h
|
localtime.o: private.h tzdir.h tzfile.h
|
||||||
strftime.o: private.h tzfile.h
|
strftime.o: localtime.c private.h tzdir.h tzfile.h
|
||||||
zdump.o: version.h
|
zdump.o: private.h version.h
|
||||||
zic.o: private.h tzfile.h tzdir.h version.h
|
zic.o: private.h tzdir.h tzfile.h version.h
|
||||||
|
|
||||||
.PHONY: ALL INSTALL all
|
.PHONY: ALL INSTALL all
|
||||||
.PHONY: check check_mild check_time_t_alternatives
|
.PHONY: check check_mild check_time_t_alternatives
|
||||||
|
|||||||
+106
-3
@@ -1,5 +1,108 @@
|
|||||||
News for the tz database
|
News for the tz database
|
||||||
|
|
||||||
|
Release 2025b - 2025-03-22 13:40:46 -0700
|
||||||
|
|
||||||
|
Briefly:
|
||||||
|
New zone for Aysén Region in Chile which moves from -04/-03 to -03.
|
||||||
|
|
||||||
|
Changes to future timestamps
|
||||||
|
|
||||||
|
Chile's Aysén Region moves from -04/-03 to -03 year-round, joining
|
||||||
|
Magallanes Region. The region will not change its clocks on
|
||||||
|
2025-04-05 at 24:00, diverging from America/Santiago and creating a
|
||||||
|
new zone America/Coyhaique. (Thanks to Yonathan Dossow.) Model
|
||||||
|
this as a change to standard offset effective 2025-03-20.
|
||||||
|
|
||||||
|
Changes to past timestamps
|
||||||
|
|
||||||
|
Iran switched from +04 to +0330 on 1978-11-10 at 24:00, not at
|
||||||
|
year end. (Thanks to Roozbeh Pournader.)
|
||||||
|
|
||||||
|
Changes to code
|
||||||
|
|
||||||
|
'zic -l TIMEZONE -d . -l /some/other/file/system' no longer
|
||||||
|
attempts to create an incorrect symlink, and no longer has a
|
||||||
|
read buffer underflow. (Problem reported by Evgeniy Gorbanev.)
|
||||||
|
|
||||||
|
|
||||||
|
Release 2025a - 2025-01-15 10:47:24 -0800
|
||||||
|
|
||||||
|
Briefly:
|
||||||
|
Paraguay adopted permanent -03 starting spring 2024.
|
||||||
|
Improve pre-1991 data for the Philippines.
|
||||||
|
Etc/Unknown is now reserved.
|
||||||
|
|
||||||
|
Changes to future timestamps
|
||||||
|
|
||||||
|
Paraguay stopped changing its clocks after the spring-forward
|
||||||
|
transition on 2024-10-06, so it is now permanently at -03.
|
||||||
|
(Thanks to Heitor David Pinto and Even Scharning.)
|
||||||
|
This affects timestamps starting 2025-03-22, as well as the
|
||||||
|
obsolescent tm_isdst flags starting 2024-10-15.
|
||||||
|
|
||||||
|
Changes to past timestamps
|
||||||
|
|
||||||
|
Correct timestamps for the Philippines before 1900, and from 1937
|
||||||
|
through 1990. (Thanks to P Chan for the heads-up and citations.)
|
||||||
|
This includes adjusting local mean time before 1899; fixing
|
||||||
|
transitions in September 1899, January 1937, and June 1954; adding
|
||||||
|
transitions in December 1941, November 1945, March and September
|
||||||
|
1977, and May and July 1990; and removing incorrect transitions in
|
||||||
|
March and September 1978.
|
||||||
|
|
||||||
|
Changes to data
|
||||||
|
|
||||||
|
Add zone1970.tab lines for the Concordia and Eyre Bird Observatory
|
||||||
|
research stations. (Thanks to Derick Rethans and Jule Dabars.)
|
||||||
|
|
||||||
|
Changes to code
|
||||||
|
|
||||||
|
strftime %s now generates the correct numeric string even when the
|
||||||
|
represented number does not fit into time_t. This is better than
|
||||||
|
generating the numeric equivalent of (time_t) -1, as strftime did
|
||||||
|
in TZDB releases 96a (when %s was introduced) through 2020a and in
|
||||||
|
releases 2022b through 2024b. It is also better than failing and
|
||||||
|
returning 0, as strftime did in releases 2020b through 2022a.
|
||||||
|
|
||||||
|
strftime now outputs an invalid conversion specifier as-is,
|
||||||
|
instead of eliding the leading '%', which confused debugging.
|
||||||
|
|
||||||
|
An invalid TZ now generates the time zone abbreviation "-00", not
|
||||||
|
"UTC", to help the user see that an error has occurred. (Thanks
|
||||||
|
to Arthur David Olson for suggesting a "wrong result".)
|
||||||
|
|
||||||
|
mktime and timeoff no longer incorrectly fail merely because a
|
||||||
|
struct tm component near INT_MIN or INT_MAX overflows when a
|
||||||
|
lower-order component carries into it.
|
||||||
|
|
||||||
|
TZNAME_MAXIMUM, the maximum number of bytes in a proleptic TZ
|
||||||
|
string's time zone abbreviation, now defaults to 254 not 255.
|
||||||
|
This helps reduce the size of internal state from 25480 to 21384
|
||||||
|
on common platforms. This change should not be a problem, as
|
||||||
|
nobody uses such long "abbreviations" and the longstanding tzcode
|
||||||
|
maximum was 16 until release 2023a. For those who prefer no
|
||||||
|
arbitrary limits, you can now specify TZNAME_MAXIMUM values up to
|
||||||
|
PTRDIFF_MAX, a limit forced by C anyway; formerly tzcode silently
|
||||||
|
misbehaved unless TZNAME_MAXIMUM was less than INT_MAX.
|
||||||
|
|
||||||
|
tzset and related functions no longer leak a file descriptor if
|
||||||
|
another thread forks or execs at about the same time and if the
|
||||||
|
platform has O_CLOFORK and O_CLOEXEC respectively. Also, the
|
||||||
|
functions no longer let a TZif file become a controlling terminal.
|
||||||
|
|
||||||
|
'zdump -' now reads TZif data from /dev/stdin.
|
||||||
|
(From a question by Arthur David Olson.)
|
||||||
|
|
||||||
|
Changes to documentation
|
||||||
|
|
||||||
|
The name Etc/Unknown is now reserved: it will not be used by TZDB.
|
||||||
|
This is for compatibility with CLDR, which uses the string
|
||||||
|
"Etc/Unknown" for an unknown or invalid timezone. (Thanks to
|
||||||
|
Justin Grant, Mark Davis, and Guy Harris.)
|
||||||
|
|
||||||
|
Cite Internet RFC 9636, which obsoletes RFC 8536 for TZif format.
|
||||||
|
|
||||||
|
|
||||||
Release 2024b - 2024-09-04 12:27:47 -0700
|
Release 2024b - 2024-09-04 12:27:47 -0700
|
||||||
|
|
||||||
Briefly:
|
Briefly:
|
||||||
@@ -116,7 +219,7 @@ Release 2024b - 2024-09-04 12:27:47 -0700
|
|||||||
Changes to commentary
|
Changes to commentary
|
||||||
|
|
||||||
Commentary about historical transitions in Portugal and her former
|
Commentary about historical transitions in Portugal and her former
|
||||||
colonies has been expanded with links to many relevant legislation.
|
colonies has been expanded with links to relevant legislation.
|
||||||
(Thanks to Tim Parenti.)
|
(Thanks to Tim Parenti.)
|
||||||
|
|
||||||
|
|
||||||
@@ -204,10 +307,10 @@ Release 2023d - 2023-12-21 20:02:24 -0800
|
|||||||
changing its time zone from -01/+00 to -02/-01 at the same moment
|
changing its time zone from -01/+00 to -02/-01 at the same moment
|
||||||
as the spring-forward transition. Its clocks will therefore not
|
as the spring-forward transition. Its clocks will therefore not
|
||||||
spring forward as previously scheduled. The time zone change
|
spring forward as previously scheduled. The time zone change
|
||||||
reverts to its common practice before 1981.
|
reverts to its common practice before 1981. (Thanks to Jule Dabars.)
|
||||||
|
|
||||||
Fix predictions for DST transitions in Palestine in 2072-2075,
|
Fix predictions for DST transitions in Palestine in 2072-2075,
|
||||||
correcting a typo introduced in 2023a.
|
correcting a typo introduced in 2023a. (Thanks to Jule Dabars.)
|
||||||
|
|
||||||
Changes to past and future timestamps
|
Changes to past and future timestamps
|
||||||
|
|
||||||
|
|||||||
+68
-54
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Avoid the temptation to punt entirely to strftime;
|
** Avoid the temptation to punt entirely to strftime;
|
||||||
|
** strftime can behave badly when tm components are out of range, and
|
||||||
** the output of strftime is supposed to be locale specific
|
** the output of strftime is supposed to be locale specific
|
||||||
** whereas the output of asctime is supposed to be constant.
|
** whereas the output of asctime is supposed to be constant.
|
||||||
*/
|
*/
|
||||||
@@ -18,27 +19,6 @@
|
|||||||
#include "un-namespace.h"
|
#include "un-namespace.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
/*
|
|
||||||
** All years associated with 32-bit time_t values are exactly four digits long;
|
|
||||||
** some years associated with 64-bit time_t values are not.
|
|
||||||
** Vintage programs are coded for years that are always four digits long
|
|
||||||
** and may assume that the newline always lands in the same place.
|
|
||||||
** For years that are less than four digits, we pad the output with
|
|
||||||
** leading zeroes to get the newline in the traditional place.
|
|
||||||
** The -4 ensures that we get four characters of output even if
|
|
||||||
** we call a strftime variant that produces fewer characters for some years.
|
|
||||||
** This conforms to recent ISO C and POSIX standards, which say behavior
|
|
||||||
** is undefined when the year is less than 1000 or greater than 9999.
|
|
||||||
*/
|
|
||||||
static char const ASCTIME_FMT[] = "%s %s%3d %.2d:%.2d:%.2d %-4s\n";
|
|
||||||
/*
|
|
||||||
** For years that are more than four digits we put extra spaces before the year
|
|
||||||
** so that code trying to overwrite the newline won't end up overwriting
|
|
||||||
** a digit within a year and truncating the year (operating on the assumption
|
|
||||||
** that no output is better than wrong output).
|
|
||||||
*/
|
|
||||||
static char const ASCTIME_FMT_B[] = "%s %s%3d %.2d:%.2d:%.2d %s\n";
|
|
||||||
|
|
||||||
enum { STD_ASCTIME_BUF_SIZE = 26 };
|
enum { STD_ASCTIME_BUF_SIZE = 26 };
|
||||||
/*
|
/*
|
||||||
** Big enough for something such as
|
** Big enough for something such as
|
||||||
@@ -52,14 +32,24 @@ enum { STD_ASCTIME_BUF_SIZE = 26 };
|
|||||||
*/
|
*/
|
||||||
static char buf_asctime[2*3 + 5*INT_STRLEN_MAXIMUM(int) + 7 + 2 + 1 + 1];
|
static char buf_asctime[2*3 + 5*INT_STRLEN_MAXIMUM(int) + 7 + 2 + 1 + 1];
|
||||||
|
|
||||||
/* A similar buffer for ctime.
|
/* On pre-C99 platforms, a snprintf substitute good enough for us. */
|
||||||
C89 requires that they be the same buffer.
|
#if !HAVE_SNPRINTF
|
||||||
This requirement was removed in C99, so support it only if requested,
|
# include <stdarg.h>
|
||||||
as support is more likely to lead to bugs in badly written programs. */
|
ATTRIBUTE_FORMAT((printf, 3, 4)) static int
|
||||||
#if SUPPORT_C89
|
my_snprintf(char *s, size_t size, char const *format, ...)
|
||||||
# define buf_ctime buf_asctime
|
{
|
||||||
#else
|
int n;
|
||||||
static char buf_ctime[sizeof buf_asctime];
|
va_list args;
|
||||||
|
char stackbuf[sizeof buf_asctime];
|
||||||
|
va_start(args, format);
|
||||||
|
n = vsprintf(stackbuf, format, args);
|
||||||
|
va_end (args);
|
||||||
|
if (0 <= n && n < size)
|
||||||
|
memcpy (s, stackbuf, n + 1);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
# undef snprintf
|
||||||
|
# define snprintf my_snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Publish asctime_r and ctime_r only when supporting older POSIX. */
|
/* Publish asctime_r and ctime_r only when supporting older POSIX. */
|
||||||
@@ -84,14 +74,19 @@ asctime_r(struct tm const *restrict timeptr, char *restrict buf)
|
|||||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||||
};
|
};
|
||||||
const char * wn;
|
register const char * wn;
|
||||||
const char * mn;
|
register const char * mn;
|
||||||
char year[INT_STRLEN_MAXIMUM(int) + 2];
|
int year, mday, hour, min, sec;
|
||||||
char result[sizeof buf_asctime];
|
long long_TM_YEAR_BASE = TM_YEAR_BASE;
|
||||||
|
size_t bufsize = (buf == buf_asctime
|
||||||
|
? sizeof buf_asctime : STD_ASCTIME_BUF_SIZE);
|
||||||
|
|
||||||
if (timeptr == NULL) {
|
if (timeptr == NULL) {
|
||||||
|
strcpy(buf, "??? ??? ?? ??:??:?? ????\n");
|
||||||
|
/* Set errno now, since strcpy might change it in
|
||||||
|
POSIX.1-2017 and earlier. */
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return strcpy(buf, "??? ??? ?? ??:??:?? ????\n");
|
return buf;
|
||||||
}
|
}
|
||||||
if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
|
if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
|
||||||
wn = "???";
|
wn = "???";
|
||||||
@@ -99,25 +94,41 @@ asctime_r(struct tm const *restrict timeptr, char *restrict buf)
|
|||||||
if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
|
if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
|
||||||
mn = "???";
|
mn = "???";
|
||||||
else mn = mon_name[timeptr->tm_mon];
|
else mn = mon_name[timeptr->tm_mon];
|
||||||
/*
|
|
||||||
** Use strftime's %Y to generate the year, to avoid overflow problems
|
year = timeptr->tm_year;
|
||||||
** when computing timeptr->tm_year + TM_YEAR_BASE.
|
mday = timeptr->tm_mday;
|
||||||
** Assume that strftime is unaffected by other out-of-range members
|
hour = timeptr->tm_hour;
|
||||||
** (e.g., timeptr->tm_mday) when processing "%Y".
|
min = timeptr->tm_min;
|
||||||
*/
|
sec = timeptr->tm_sec;
|
||||||
strftime(year, sizeof year, "%Y", timeptr);
|
|
||||||
/*
|
/* Vintage programs are coded for years that are always four bytes long
|
||||||
** We avoid using snprintf since it's not available on all systems.
|
and may assume that the newline always lands in the same place.
|
||||||
*/
|
For years that are less than four bytes, pad the output with
|
||||||
sprintf(result,
|
leading zeroes to get the newline in the traditional place.
|
||||||
((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B),
|
For years longer than four bytes, put extra spaces before the year
|
||||||
wn, mn,
|
so that vintage code trying to overwrite the newline
|
||||||
timeptr->tm_mday, timeptr->tm_hour,
|
won't overwrite a digit within a year and truncate the year,
|
||||||
timeptr->tm_min, timeptr->tm_sec,
|
using the principle that no output is better than wrong output.
|
||||||
year);
|
This conforms to ISO C and POSIX standards, which say behavior
|
||||||
if (strlen(result) < STD_ASCTIME_BUF_SIZE
|
is undefined when the year is less than 1000 or greater than 9999.
|
||||||
|| buf == buf_ctime || buf == buf_asctime)
|
|
||||||
return strcpy(buf, result);
|
Also, avoid overflow when formatting tm_year + TM_YEAR_BASE. */
|
||||||
|
|
||||||
|
if ((year <= LONG_MAX - TM_YEAR_BASE
|
||||||
|
? snprintf (buf, bufsize,
|
||||||
|
((-999 - TM_YEAR_BASE <= year
|
||||||
|
&& year <= 9999 - TM_YEAR_BASE)
|
||||||
|
? "%s %s%3d %.2d:%.2d:%.2d %04ld\n"
|
||||||
|
: "%s %s%3d %.2d:%.2d:%.2d %ld\n"),
|
||||||
|
wn, mn, mday, hour, min, sec,
|
||||||
|
year + long_TM_YEAR_BASE)
|
||||||
|
: snprintf (buf, bufsize,
|
||||||
|
"%s %s%3d %.2d:%.2d:%.2d %d%d\n",
|
||||||
|
wn, mn, mday, hour, min, sec,
|
||||||
|
year / 10 + TM_YEAR_BASE / 10,
|
||||||
|
year % 10))
|
||||||
|
< bufsize)
|
||||||
|
return buf;
|
||||||
else {
|
else {
|
||||||
errno = EOVERFLOW;
|
errno = EOVERFLOW;
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -142,5 +153,8 @@ ctime_r(const time_t *timep, char *buf)
|
|||||||
char *
|
char *
|
||||||
ctime(const time_t *timep)
|
ctime(const time_t *timep)
|
||||||
{
|
{
|
||||||
return ctime_r(timep, buf_ctime);
|
/* Do not call localtime_r, as C23 requires ctime to initialize the
|
||||||
|
static storage that localtime updates. */
|
||||||
|
struct tm *tmp = localtime(timep);
|
||||||
|
return tmp ? asctime(tmp) : NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-101
@@ -6,15 +6,13 @@ date \- show and set date and time
|
|||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.if n .nh
|
.if n .nh
|
||||||
.if n .na
|
.if n .na
|
||||||
.ie \n(.g .ds - \f(CR-\fP
|
|
||||||
.el .ds - \-
|
|
||||||
.B date
|
.B date
|
||||||
[
|
[
|
||||||
.B \*-u
|
.B \-u
|
||||||
] [
|
] [
|
||||||
.B \*-c
|
.B \-c
|
||||||
] [
|
] [
|
||||||
.B \*-r
|
.B \-r
|
||||||
.I seconds
|
.I seconds
|
||||||
] [
|
] [
|
||||||
.BI + format
|
.BI + format
|
||||||
@@ -35,7 +33,7 @@ command
|
|||||||
without arguments writes the date and time to the standard output in
|
without arguments writes the date and time to the standard output in
|
||||||
the form
|
the form
|
||||||
.ce 1
|
.ce 1
|
||||||
Wed Mar 8 14:54:40 EST 1989
|
Sat Mar 8 14:54:40 EST 2025
|
||||||
.br
|
.br
|
||||||
with
|
with
|
||||||
.B EST
|
.B EST
|
||||||
@@ -49,99 +47,24 @@ If a command-line argument starts with a plus sign (\c
|
|||||||
.q "\fB+\fP" ),
|
.q "\fB+\fP" ),
|
||||||
the rest of the argument is used as a
|
the rest of the argument is used as a
|
||||||
.I format
|
.I format
|
||||||
that controls what appears in the output.
|
that is processed by
|
||||||
In the format, when a percent sign (\c
|
.BR strftime (3)
|
||||||
.q "\fB%\fP"
|
to determine what to output;
|
||||||
appears,
|
a newline character is appended.
|
||||||
it and the character after it are not output,
|
For example, the shell command:
|
||||||
but rather identify part of the date or time
|
.ce 1
|
||||||
to be output in a particular way
|
date +"%Y\-%m\-%d %H:%M:%S %z"
|
||||||
(or identify a special character to output):
|
.br
|
||||||
.nf
|
outputs a line like
|
||||||
.sp
|
.q "2025\-03\-08 14:54:40 \-0500"
|
||||||
.if t .in +.5i
|
instead.
|
||||||
.if n .in +2
|
|
||||||
.ta \w'%M\0\0'u +\w'Wed Mar 8 14:54:40 EST 1989\0\0'u
|
|
||||||
Sample output Explanation
|
|
||||||
%a Wed Abbreviated weekday name*
|
|
||||||
%A Wednesday Full weekday name*
|
|
||||||
%b Mar Abbreviated month name*
|
|
||||||
%B March Full month name*
|
|
||||||
%c Wed Mar 08 14:54:40 1989 Date and time*
|
|
||||||
%C 19 Century
|
|
||||||
%d 08 Day of month (always two digits)
|
|
||||||
%D 03/08/89 Month/day/year (eight characters)
|
|
||||||
%e 8 Day of month (leading zero blanked)
|
|
||||||
%h Mar Abbreviated month name*
|
|
||||||
%H 14 24-hour-clock hour (two digits)
|
|
||||||
%I 02 12-hour-clock hour (two digits)
|
|
||||||
%j 067 Julian day number (three digits)
|
|
||||||
%k 2 12-hour-clock hour (leading zero blanked)
|
|
||||||
%l 14 24-hour-clock hour (leading zero blanked)
|
|
||||||
%m 03 Month number (two digits)
|
|
||||||
%M 54 Minute (two digits)
|
|
||||||
%n \\n newline character
|
|
||||||
%p PM AM/PM designation
|
|
||||||
%r 02:54:40 PM Hour:minute:second AM/PM designation
|
|
||||||
%R 14:54 Hour:minute
|
|
||||||
%S 40 Second (two digits)
|
|
||||||
%t \\t tab character
|
|
||||||
%T 14:54:40 Hour:minute:second
|
|
||||||
%U 10 Sunday-based week number (two digits)
|
|
||||||
%w 3 Day number (one digit, Sunday is 0)
|
|
||||||
%W 10 Monday-based week number (two digits)
|
|
||||||
%x 03/08/89 Date*
|
|
||||||
%X 14:54:40 Time*
|
|
||||||
%y 89 Last two digits of year
|
|
||||||
%Y 1989 Year in full
|
|
||||||
%z -0500 Numeric time zone
|
|
||||||
%Z EST Time zone abbreviation
|
|
||||||
%+ Wed Mar 8 14:54:40 EST 1989 Default output format*
|
|
||||||
.if t .in -.5i
|
|
||||||
.if n .in -2
|
|
||||||
* The exact output depends on the locale.
|
|
||||||
.sp
|
|
||||||
.fi
|
|
||||||
If a character other than one of those shown above appears after
|
|
||||||
a percent sign in the format,
|
|
||||||
that following character is output.
|
|
||||||
All other characters in the format are copied unchanged to the output;
|
|
||||||
a newline character is always added at the end of the output.
|
|
||||||
.PP
|
|
||||||
In Sunday-based week numbering,
|
|
||||||
the first Sunday of the year begins week 1;
|
|
||||||
days preceding it are part of
|
|
||||||
.q "week 0" .
|
|
||||||
In Monday-based week numbering,
|
|
||||||
the first Monday of the year begins week 1.
|
|
||||||
.PP
|
|
||||||
To set the date, use a command line argument with one of the following forms:
|
|
||||||
.nf
|
|
||||||
.if t .in +.5i
|
|
||||||
.if n .in +2
|
|
||||||
.ta \w'198903081454\0'u
|
|
||||||
1454 24-hour-clock hours (first two digits) and minutes
|
|
||||||
081454 Month day (first two digits), hours, and minutes
|
|
||||||
03081454 Month (two digits, January is 01), month day, hours, minutes
|
|
||||||
8903081454 Year, month, month day, hours, minutes
|
|
||||||
0308145489 Month, month day, hours, minutes, year
|
|
||||||
(on System V-compatible systems)
|
|
||||||
030814541989 Month, month day, hours, minutes, four-digit year
|
|
||||||
198903081454 Four-digit year, month, month day, hours, minutes
|
|
||||||
.if t .in -.5i
|
|
||||||
.if n .in -2
|
|
||||||
.fi
|
|
||||||
If the century, year, month, or month day is not given,
|
|
||||||
the current value is used.
|
|
||||||
Any of the above forms may be followed by a period and two digits that give
|
|
||||||
the seconds part of the new time; if no seconds are given, zero is assumed.
|
|
||||||
.PP
|
.PP
|
||||||
These options are available:
|
These options are available:
|
||||||
.TP
|
.TP
|
||||||
.BR \*-u " or " \*-c
|
.BR \-u " or " \-c
|
||||||
Use Universal Time when setting and showing the date and time.
|
Use Universal Time when setting and showing the date and time.
|
||||||
.TP
|
.TP
|
||||||
.BI "\*-r " seconds
|
.BI "\-r " seconds
|
||||||
Output the date that corresponds to
|
Output the date that corresponds to
|
||||||
.I seconds
|
.I seconds
|
||||||
past the epoch of 1970-01-01 00:00:00 UTC, where
|
past the epoch of 1970-01-01 00:00:00 UTC, where
|
||||||
@@ -149,16 +72,13 @@ past the epoch of 1970-01-01 00:00:00 UTC, where
|
|||||||
should be an integer, either decimal, octal (leading 0), or
|
should be an integer, either decimal, octal (leading 0), or
|
||||||
hexadecimal (leading 0x), preceded by an optional sign.
|
hexadecimal (leading 0x), preceded by an optional sign.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.ta \w'/usr/share/zoneinfo/posixrules\0\0'u
|
.ta \w'/usr/share/zoneinfo/Etc/UTC\0\0'u
|
||||||
/etc/localtime local timezone file
|
/etc/localtime local timezone file
|
||||||
.br
|
.br
|
||||||
/usr/lib/locale/\f2L\fP/LC_TIME description of time locale \f2L\fP
|
/usr/lib/locale/\f2L\fP/LC_TIME description of time locale \f2L\fP
|
||||||
.br
|
.br
|
||||||
/usr/share/zoneinfo timezone directory
|
/usr/share/zoneinfo timezone directory
|
||||||
.br
|
.br
|
||||||
/usr/share/zoneinfo/posixrules default DST rules (obsolete)
|
/usr/share/zoneinfo/Etc/UTC for UTC leap seconds
|
||||||
.br
|
.SH SEE ALSO
|
||||||
/usr/share/zoneinfo/GMT for UTC leap seconds
|
.BR strftime (3).
|
||||||
.PP
|
|
||||||
If /usr/share/zoneinfo/GMT is absent,
|
|
||||||
UTC leap seconds are loaded from /usr/share/zoneinfo/GMT0 if present.
|
|
||||||
|
|||||||
+373
-212
File diff suppressed because it is too large
Load Diff
+76
-84
@@ -5,43 +5,34 @@
|
|||||||
asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
|
asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.ie \n(.g .ds - \f(CR-\fP
|
|
||||||
.el .ds - \-
|
|
||||||
.B #include <time.h>
|
.B #include <time.h>
|
||||||
.PP
|
.PP
|
||||||
.B [[deprecated]] char *ctime(time_t const *clock);
|
|
||||||
.PP
|
|
||||||
/* Only in POSIX.1-2017 and earlier. */
|
|
||||||
.B char *ctime_r(time_t const *clock, char *buf);
|
|
||||||
.PP
|
|
||||||
.B double difftime(time_t time1, time_t time0);
|
|
||||||
.PP
|
|
||||||
.B [[deprecated]] char *asctime(struct tm const *tm);
|
|
||||||
.PP
|
|
||||||
/* Only in POSIX.1-2017 and earlier. */
|
|
||||||
.B "char *asctime_r(struct tm const *restrict tm,"
|
|
||||||
.B " char *restrict result);"
|
|
||||||
.PP
|
|
||||||
.B struct tm *localtime(time_t const *clock);
|
.B struct tm *localtime(time_t const *clock);
|
||||||
.PP
|
|
||||||
.B "struct tm *localtime_r(time_t const *restrict clock,"
|
.B "struct tm *localtime_r(time_t const *restrict clock,"
|
||||||
.B " struct tm *restrict result);"
|
.B " struct tm *restrict result);"
|
||||||
.PP
|
|
||||||
.B "struct tm *localtime_rz(timezone_t restrict zone,"
|
.B "struct tm *localtime_rz(timezone_t restrict zone,"
|
||||||
.B " time_t const *restrict clock,"
|
.B " time_t const *restrict clock,"
|
||||||
.B " struct tm *restrict result);"
|
.B " struct tm *restrict result);"
|
||||||
.PP
|
.PP
|
||||||
.B struct tm *gmtime(time_t const *clock);
|
.B struct tm *gmtime(time_t const *clock);
|
||||||
.PP
|
|
||||||
.B "struct tm *gmtime_r(time_t const *restrict clock,"
|
.B "struct tm *gmtime_r(time_t const *restrict clock,"
|
||||||
.B " struct tm *restrict result);"
|
.B " struct tm *restrict result);"
|
||||||
.PP
|
.PP
|
||||||
.B time_t mktime(struct tm *tm);
|
.B time_t mktime(struct tm *tm);
|
||||||
.PP
|
|
||||||
.B "time_t mktime_z(timezone_t restrict zone,"
|
.B "time_t mktime_z(timezone_t restrict zone,"
|
||||||
.B " struct tm *restrict tm);"
|
.B " struct tm *restrict tm);"
|
||||||
.PP
|
.PP
|
||||||
.B cc ... \*-ltz
|
.B double difftime(time_t time1, time_t time0);
|
||||||
|
.PP
|
||||||
|
.B [[deprecated]] char *asctime(struct tm const *tm);
|
||||||
|
.B [[deprecated]] char *ctime(time_t const *clock);
|
||||||
|
.PP
|
||||||
|
/* Only in POSIX.1-2017 and earlier. */
|
||||||
|
.B char *ctime_r(time_t const *clock, char *buf);
|
||||||
|
.B "char *asctime_r(struct tm const *restrict tm,"
|
||||||
|
.B " char *restrict result);"
|
||||||
|
.PP
|
||||||
|
.B cc ... \-ltz
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.ie '\(en'' .ds en \-
|
.ie '\(en'' .ds en \-
|
||||||
@@ -54,30 +45,26 @@ asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
|
|||||||
\\$3\*(lq\\$1\*(rq\\$2
|
\\$3\*(lq\\$1\*(rq\\$2
|
||||||
..
|
..
|
||||||
The
|
The
|
||||||
.B ctime
|
.B localtime
|
||||||
function
|
and
|
||||||
converts a long integer, pointed to by
|
.B gmtime
|
||||||
|
functions
|
||||||
|
convert an integer, pointed to by
|
||||||
.IR clock ,
|
.IR clock ,
|
||||||
and returns a pointer to a
|
and
|
||||||
string of the form
|
return pointers to
|
||||||
.br
|
.q "tm"
|
||||||
.ce
|
structures, described below.
|
||||||
.eo
|
If the integer is out of range for conversion,
|
||||||
Thu Nov 24 18:22:48 1986\n\0
|
these functions return a null pointer.
|
||||||
.br
|
The
|
||||||
.ec
|
.B localtime
|
||||||
Years requiring fewer than four characters are padded with leading zeroes.
|
function
|
||||||
For years longer than four characters, the string is of the form
|
corrects for the time zone and any time zone adjustments
|
||||||
.br
|
(such as Daylight Saving Time in the United States).
|
||||||
.ce
|
The
|
||||||
.eo
|
.B gmtime
|
||||||
Thu Nov 24 18:22:48 81986\n\0
|
function converts to Coordinated Universal Time.
|
||||||
.ec
|
|
||||||
.br
|
|
||||||
with five spaces before the year.
|
|
||||||
These unusual formats are designed to make it less likely that older
|
|
||||||
software that expects exactly 26 bytes of output will mistakenly output
|
|
||||||
misleading values for out-of-range years.
|
|
||||||
.PP
|
.PP
|
||||||
The
|
The
|
||||||
.BI * clock
|
.BI * clock
|
||||||
@@ -91,47 +78,6 @@ introduction of UTC and are some other flavor of Universal Time (UT).
|
|||||||
Some implementations support leap seconds, in contradiction to POSIX.
|
Some implementations support leap seconds, in contradiction to POSIX.
|
||||||
.PP
|
.PP
|
||||||
The
|
The
|
||||||
.B ctime
|
|
||||||
function is deprecated starting in C23.
|
|
||||||
Callers can use
|
|
||||||
.B localtime_r
|
|
||||||
and
|
|
||||||
.B strftime
|
|
||||||
instead.
|
|
||||||
.PP
|
|
||||||
The
|
|
||||||
.B localtime
|
|
||||||
and
|
|
||||||
.B gmtime
|
|
||||||
functions
|
|
||||||
return pointers to
|
|
||||||
.q "tm"
|
|
||||||
structures, described below.
|
|
||||||
The
|
|
||||||
.B localtime
|
|
||||||
function
|
|
||||||
corrects for the time zone and any time zone adjustments
|
|
||||||
(such as Daylight Saving Time in the United States).
|
|
||||||
.PP
|
|
||||||
The
|
|
||||||
.B gmtime
|
|
||||||
function
|
|
||||||
converts to Coordinated Universal Time.
|
|
||||||
.PP
|
|
||||||
The
|
|
||||||
.B asctime
|
|
||||||
function
|
|
||||||
converts a time value contained in a
|
|
||||||
.q "tm"
|
|
||||||
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
|
.B mktime
|
||||||
function
|
function
|
||||||
converts the broken-down time,
|
converts the broken-down time,
|
||||||
@@ -204,6 +150,52 @@ returns the difference between two calendar times,
|
|||||||
expressed in seconds.
|
expressed in seconds.
|
||||||
.PP
|
.PP
|
||||||
The
|
The
|
||||||
|
.B asctime
|
||||||
|
function
|
||||||
|
converts a time value contained in a
|
||||||
|
.q "tm"
|
||||||
|
structure to a pointer to a
|
||||||
|
string of the form
|
||||||
|
.br
|
||||||
|
.ce
|
||||||
|
.eo
|
||||||
|
Thu Nov 24 18:22:48 1986\n\0
|
||||||
|
.br
|
||||||
|
.ec
|
||||||
|
Years requiring fewer than four characters are padded with leading zeroes.
|
||||||
|
For years longer than four characters, the string is of the form
|
||||||
|
.br
|
||||||
|
.ce
|
||||||
|
.eo
|
||||||
|
Thu Nov 24 18:22:48 81986\n\0
|
||||||
|
.ec
|
||||||
|
.br
|
||||||
|
with five spaces before the year.
|
||||||
|
This unusual format is designed to make it less likely that older
|
||||||
|
software that expects exactly 26 bytes of output will mistakenly output
|
||||||
|
misleading values for out-of-range years.
|
||||||
|
This function is deprecated starting in C23.
|
||||||
|
Callers can use
|
||||||
|
.B strftime
|
||||||
|
instead.
|
||||||
|
.PP
|
||||||
|
The
|
||||||
|
.B ctime
|
||||||
|
function is equivalent to calliing
|
||||||
|
.B localtime
|
||||||
|
and then calling
|
||||||
|
.B asctime
|
||||||
|
on the result.
|
||||||
|
Like
|
||||||
|
.BR asctime ,
|
||||||
|
this function is deprecated starting in C23.
|
||||||
|
Callers can use
|
||||||
|
.B localtime
|
||||||
|
and
|
||||||
|
.B strftime
|
||||||
|
instead.
|
||||||
|
.PP
|
||||||
|
The
|
||||||
.BR ctime_r ,
|
.BR ctime_r ,
|
||||||
.BR localtime_r ,
|
.BR localtime_r ,
|
||||||
.BR gmtime_r ,
|
.BR gmtime_r ,
|
||||||
|
|||||||
@@ -40,8 +40,6 @@
|
|||||||
strftime \- format date and time
|
strftime \- format date and time
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.ie \n(.g .ds - \f(CR-\fP
|
|
||||||
.el .ds - \-
|
|
||||||
.B #include <time.h>
|
.B #include <time.h>
|
||||||
.PP
|
.PP
|
||||||
.B "size_t strftime(char *restrict buf, size_t maxsize,"
|
.B "size_t strftime(char *restrict buf, size_t maxsize,"
|
||||||
@@ -93,7 +91,7 @@ If a bracketed member name is followed by
|
|||||||
.B strftime
|
.B strftime
|
||||||
can use the named member even though POSIX.1-2024 does not list it;
|
can use the named member even though POSIX.1-2024 does not list it;
|
||||||
if the name is followed by
|
if the name is followed by
|
||||||
.q \*- ,
|
.q \- ,
|
||||||
.B strftime
|
.B strftime
|
||||||
ignores the member even though POSIX.1-2024 lists it
|
ignores the member even though POSIX.1-2024 lists it
|
||||||
which means portable code should set it.
|
which means portable code should set it.
|
||||||
@@ -139,11 +137,14 @@ is replaced by the locale's appropriate date and time representation.
|
|||||||
.IR tm_sec ,
|
.IR tm_sec ,
|
||||||
.IR tm_gmtoff ,
|
.IR tm_gmtoff ,
|
||||||
.IR tm_zone ,
|
.IR tm_zone ,
|
||||||
.IR tm_isdst \*-].
|
.IR tm_isdst \-].
|
||||||
.TP
|
.TP
|
||||||
%D
|
%D
|
||||||
is equivalent to
|
is equivalent to
|
||||||
.c %m/%d/%y .
|
.c %m/%d/%y .
|
||||||
|
Although used in the United States for current dates,
|
||||||
|
this format is ambiguous elsewhere
|
||||||
|
and for dates that might involve other centuries.
|
||||||
.RI [ tm_year ,
|
.RI [ tm_year ,
|
||||||
.IR tm_mon ,
|
.IR tm_mon ,
|
||||||
.IR tm_mday ]
|
.IR tm_mday ]
|
||||||
@@ -167,6 +168,8 @@ is equivalent to
|
|||||||
.TP
|
.TP
|
||||||
%G
|
%G
|
||||||
is replaced by the ISO 8601 year with century as a decimal number.
|
is replaced by the ISO 8601 year with century as a decimal number.
|
||||||
|
This is the year that includes the greater part of the week.
|
||||||
|
(Monday as the first day of a week).
|
||||||
See also the
|
See also the
|
||||||
.c %V
|
.c %V
|
||||||
conversion specification.
|
conversion specification.
|
||||||
@@ -176,11 +179,7 @@ conversion specification.
|
|||||||
.TP
|
.TP
|
||||||
%g
|
%g
|
||||||
is replaced by the ISO 8601 year without century as a decimal number [00,99].
|
is replaced by the ISO 8601 year without century as a decimal number [00,99].
|
||||||
This is the year that includes the greater part of the week.
|
Since it omits the century, it is ambiguous for dates.
|
||||||
(Monday as the first day of a week).
|
|
||||||
See also the
|
|
||||||
.c %V
|
|
||||||
conversion specification.
|
|
||||||
.RI [ tm_year ,
|
.RI [ tm_year ,
|
||||||
.IR tm_yday ,
|
.IR tm_yday ,
|
||||||
.IR tm_wday ]
|
.IR tm_wday ]
|
||||||
@@ -249,9 +248,22 @@ of leap seconds.
|
|||||||
is replaced by the number of seconds since the Epoch (see
|
is replaced by the number of seconds since the Epoch (see
|
||||||
.BR ctime (3)).
|
.BR ctime (3)).
|
||||||
Although %s is reliable in this implementation,
|
Although %s is reliable in this implementation,
|
||||||
it can have glitches on other platforms (notably platforms lacking
|
it can have glitches on other platforms
|
||||||
.IR tm_gmtoff ),
|
(notably obsolescent platforms lacking
|
||||||
so portable code should format a
|
.I tm_gmtoff
|
||||||
|
or where
|
||||||
|
.B time_t
|
||||||
|
is no wider than int), and POSIX allows
|
||||||
|
.B strftime
|
||||||
|
to set
|
||||||
|
.B errno
|
||||||
|
to
|
||||||
|
.B EINVAL
|
||||||
|
or
|
||||||
|
.B EOVERFLOW
|
||||||
|
and return 0 if the number of seconds would be negative or out of range for
|
||||||
|
.BR time_t .
|
||||||
|
Portable code should therefore format a
|
||||||
.B time_t
|
.B time_t
|
||||||
value directly via something like
|
value directly via something like
|
||||||
.B sprintf
|
.B sprintf
|
||||||
@@ -267,7 +279,7 @@ with "%s".
|
|||||||
.IR tm_min ,
|
.IR tm_min ,
|
||||||
.IR tm_sec ,
|
.IR tm_sec ,
|
||||||
.IR tm_gmtoff +,
|
.IR tm_gmtoff +,
|
||||||
.IR tm_isdst \*-].
|
.IR tm_isdst \-].
|
||||||
.TP
|
.TP
|
||||||
%T
|
%T
|
||||||
is replaced by the time in the format
|
is replaced by the time in the format
|
||||||
@@ -284,7 +296,7 @@ is replaced by the week number of the year (Sunday as the first day of
|
|||||||
the week) as a decimal number [00,53].
|
the week) as a decimal number [00,53].
|
||||||
.RI [ tm_wday ,
|
.RI [ tm_wday ,
|
||||||
.IR tm_yday ,
|
.IR tm_yday ,
|
||||||
.IR tm_year \*-]
|
.IR tm_year \-]
|
||||||
.TP
|
.TP
|
||||||
%u
|
%u
|
||||||
is replaced by the weekday (Monday as the first day of the week)
|
is replaced by the weekday (Monday as the first day of the week)
|
||||||
@@ -318,31 +330,33 @@ as a decimal number [0,6].
|
|||||||
.TP
|
.TP
|
||||||
%X
|
%X
|
||||||
is replaced by the locale's appropriate time representation.
|
is replaced by the locale's appropriate time representation.
|
||||||
.RI [ tm_year \*-,
|
.RI [ tm_year \-,
|
||||||
.IR tm_yday \*-,
|
.IR tm_yday \-,
|
||||||
.IR tm_mon \*-,
|
.IR tm_mon \-,
|
||||||
.IR tm_mday \*-,
|
.IR tm_mday \-,
|
||||||
.IR tm_wday \*-,
|
.IR tm_wday \-,
|
||||||
.IR tm_hour ,
|
.IR tm_hour ,
|
||||||
.IR tm_min ,
|
.IR tm_min ,
|
||||||
.IR tm_sec ,
|
.IR tm_sec ,
|
||||||
.IR tm_gmtoff ,
|
.IR tm_gmtoff ,
|
||||||
.IR tm_zone ,
|
.IR tm_zone ,
|
||||||
.IR tm_isdst \*-].
|
.IR tm_isdst \-].
|
||||||
.TP
|
.TP
|
||||||
%x
|
%x
|
||||||
is replaced by the locale's appropriate date representation.
|
is replaced by the locale's appropriate date representation.
|
||||||
|
This format can be ambiguous for dates, e.g.,
|
||||||
|
it can generate "01/02/03" in the C locale.
|
||||||
.RI [ tm_year ,
|
.RI [ tm_year ,
|
||||||
.IR tm_yday ,
|
.IR tm_yday ,
|
||||||
.IR tm_mon ,
|
.IR tm_mon ,
|
||||||
.IR tm_mday ,
|
.IR tm_mday ,
|
||||||
.IR tm_wday ,
|
.IR tm_wday ,
|
||||||
.IR tm_hour \*-,
|
.IR tm_hour \-,
|
||||||
.IR tm_min \*-,
|
.IR tm_min \-,
|
||||||
.IR tm_sec \*-,
|
.IR tm_sec \-,
|
||||||
.IR tm_gmtoff \*-,
|
.IR tm_gmtoff \-,
|
||||||
.IR tm_zone \*-,
|
.IR tm_zone \-,
|
||||||
.IR tm_isdst \*-].
|
.IR tm_isdst \-].
|
||||||
.TP
|
.TP
|
||||||
%Y
|
%Y
|
||||||
is replaced by the year with century as a decimal number.
|
is replaced by the year with century as a decimal number.
|
||||||
@@ -350,28 +364,29 @@ is replaced by the year with century as a decimal number.
|
|||||||
.TP
|
.TP
|
||||||
%y
|
%y
|
||||||
is replaced by the year without century as a decimal number [00,99].
|
is replaced by the year without century as a decimal number [00,99].
|
||||||
|
Since it omits the century, it is ambiguous for dates.
|
||||||
.RI [ tm_year ]
|
.RI [ tm_year ]
|
||||||
.TP
|
.TP
|
||||||
%Z
|
%Z
|
||||||
is replaced by the time zone abbreviation,
|
is replaced by the time zone abbreviation,
|
||||||
or by the empty string if this is not determinable.
|
or by the empty string if this is not determinable.
|
||||||
.RI [ tm_zone ,
|
.RI [ tm_zone ,
|
||||||
.IR tm_isdst \*-]
|
.IR tm_isdst \-]
|
||||||
.TP
|
.TP
|
||||||
%z
|
%z
|
||||||
is replaced by the offset from the Prime Meridian
|
is replaced by the offset from the Prime Meridian
|
||||||
in the format +HHMM or \*-HHMM (ISO 8601) as appropriate,
|
in the format +HHMM or \-HHMM (ISO 8601) as appropriate,
|
||||||
with positive values representing locations east of Greenwich,
|
with positive values representing locations east of Greenwich,
|
||||||
or by the empty string if this is not determinable.
|
or by the empty string if this is not determinable.
|
||||||
The numeric time zone abbreviation \*-0000 is used when the time is
|
The numeric time zone abbreviation \-0000 is used when the time is
|
||||||
Universal Time
|
Universal Time
|
||||||
but local time is indeterminate; by convention this is used for
|
but local time is indeterminate; by convention this is used for
|
||||||
locations while uninhabited, and corresponds to a zero offset when the
|
locations while uninhabited, and corresponds to a zero offset when the
|
||||||
time zone abbreviation begins with
|
time zone abbreviation begins with
|
||||||
.q "\*-" .
|
.q "\-" .
|
||||||
.RI [ tm_gmtoff ,
|
.RI [ tm_gmtoff ,
|
||||||
.IR tm_zone +,
|
.IR tm_zone +,
|
||||||
.IR tm_isdst \*-]
|
.IR tm_isdst \-]
|
||||||
.TP
|
.TP
|
||||||
%%
|
%%
|
||||||
is replaced by a single %.
|
is replaced by a single %.
|
||||||
@@ -418,15 +433,6 @@ This function fails if:
|
|||||||
The total number of resulting bytes, including the terminating
|
The total number of resulting bytes, including the terminating
|
||||||
NUL character, is more than
|
NUL character, is more than
|
||||||
.IR maxsize .
|
.IR maxsize .
|
||||||
.PP
|
|
||||||
This function may fail if:
|
|
||||||
.TP
|
|
||||||
[EOVERFLOW]
|
|
||||||
The format includes an
|
|
||||||
.c %s
|
|
||||||
conversion and the number of seconds since the Epoch cannot be represented
|
|
||||||
in a
|
|
||||||
.c time_t .
|
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR date (1),
|
.BR date (1),
|
||||||
.BR getenv (3),
|
.BR getenv (3),
|
||||||
|
|||||||
+11
-13
@@ -5,8 +5,6 @@
|
|||||||
tzset \- initialize time conversion information
|
tzset \- initialize time conversion information
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.ie \n(.g .ds - \f(CR-\fP
|
|
||||||
.el .ds - \-
|
|
||||||
.B #include <time.h>
|
.B #include <time.h>
|
||||||
.PP
|
.PP
|
||||||
.BI "timezone_t tzalloc(char const *" TZ );
|
.BI "timezone_t tzalloc(char const *" TZ );
|
||||||
@@ -23,7 +21,7 @@ tzset \- initialize time conversion information
|
|||||||
.br
|
.br
|
||||||
.B extern int daylight;
|
.B extern int daylight;
|
||||||
.PP
|
.PP
|
||||||
.B cc ... \*-ltz
|
.B cc ... \-ltz
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.ie '\(en'' .ds en \-
|
.ie '\(en'' .ds en \-
|
||||||
@@ -110,7 +108,7 @@ except a leading colon
|
|||||||
digits, comma
|
digits, comma
|
||||||
.RB ( , ),
|
.RB ( , ),
|
||||||
ASCII minus
|
ASCII minus
|
||||||
.RB ( \*- ),
|
.RB ( \- ),
|
||||||
ASCII plus
|
ASCII plus
|
||||||
.RB ( + ),
|
.RB ( + ),
|
||||||
and NUL bytes are allowed.
|
and NUL bytes are allowed.
|
||||||
@@ -150,7 +148,7 @@ daylight saving time is assumed to be one hour ahead of standard time. One or
|
|||||||
more digits may be used; the value is always interpreted as a decimal
|
more digits may be used; the value is always interpreted as a decimal
|
||||||
number. The hour must be between zero and 24, and the minutes (and
|
number. The hour must be between zero and 24, and the minutes (and
|
||||||
seconds) \*(en if present \*(en between zero and 59. If preceded by a
|
seconds) \*(en if present \*(en between zero and 59. If preceded by a
|
||||||
.q "\*-" ,
|
.q "\-" ,
|
||||||
the time zone shall be east of the Prime Meridian; otherwise it shall be
|
the time zone shall be east of the Prime Meridian; otherwise it shall be
|
||||||
west (which may be indicated by an optional preceding
|
west (which may be indicated by an optional preceding
|
||||||
.q "+" .
|
.q "+" .
|
||||||
@@ -239,7 +237,7 @@ values that directly specify the timezone.
|
|||||||
stands for US Eastern Standard
|
stands for US Eastern Standard
|
||||||
Time (EST), 5 hours behind UT, without daylight saving.
|
Time (EST), 5 hours behind UT, without daylight saving.
|
||||||
.TP
|
.TP
|
||||||
.B <+12>\*-12<+13>,M11.1.0,M1.2.1/147
|
.B <+12>\-12<+13>,M11.1.0,M1.2.1/147
|
||||||
stands for Fiji time, 12 hours ahead
|
stands for Fiji time, 12 hours ahead
|
||||||
of UT, springing forward on November's first Sunday at 02:00, and
|
of UT, springing forward on November's first Sunday at 02:00, and
|
||||||
falling back on January's second Monday at 147:00 (i.e., 03:00 on the
|
falling back on January's second Monday at 147:00 (i.e., 03:00 on the
|
||||||
@@ -249,34 +247,34 @@ and daylight saving time are
|
|||||||
and
|
and
|
||||||
.q "+13".
|
.q "+13".
|
||||||
.TP
|
.TP
|
||||||
.B IST\*-2IDT,M3.4.4/26,M10.5.0
|
.B IST\-2IDT,M3.4.4/26,M10.5.0
|
||||||
stands for Israel Standard Time (IST) and Israel Daylight Time (IDT),
|
stands for Israel Standard Time (IST) and Israel Daylight Time (IDT),
|
||||||
2 hours ahead of UT, springing forward on March's fourth
|
2 hours ahead of UT, springing forward on March's fourth
|
||||||
Thursday at 26:00 (i.e., 02:00 on the first Friday on or after March
|
Thursday at 26:00 (i.e., 02:00 on the first Friday on or after March
|
||||||
23), and falling back on October's last Sunday at 02:00.
|
23), and falling back on October's last Sunday at 02:00.
|
||||||
.TP
|
.TP
|
||||||
.B <\*-04>4<\*-03>,J1/0,J365/25
|
.B <\-04>4<\-03>,J1/0,J365/25
|
||||||
stands for permanent daylight saving time, 3 hours behind UT with
|
stands for permanent daylight saving time, 3 hours behind UT with
|
||||||
abbreviation
|
abbreviation
|
||||||
.q "\*-03".
|
.q "\-03".
|
||||||
There is a dummy fall-back transition on December 31 at 25:00 daylight
|
There is a dummy fall-back transition on December 31 at 25:00 daylight
|
||||||
saving time (i.e., 24:00 standard time, equivalent to January 1 at
|
saving time (i.e., 24:00 standard time, equivalent to January 1 at
|
||||||
00:00 standard time), and a simultaneous spring-forward transition on
|
00:00 standard time), and a simultaneous spring-forward transition on
|
||||||
January 1 at 00:00 standard time, so daylight saving time is in effect
|
January 1 at 00:00 standard time, so daylight saving time is in effect
|
||||||
all year and the initial
|
all year and the initial
|
||||||
.B <\*-04>
|
.B <\-04>
|
||||||
is a placeholder.
|
is a placeholder.
|
||||||
.TP
|
.TP
|
||||||
.B <\*-03>3<\*-02>,M3.5.0/\*-2,M10.5.0/\*-1
|
.B <\-03>3<\-02>,M3.5.0/\-2,M10.5.0/\-1
|
||||||
stands for time in western Greenland, 3 hours behind UT, where clocks
|
stands for time in western Greenland, 3 hours behind UT, where clocks
|
||||||
follow the EU rules of
|
follow the EU rules of
|
||||||
springing forward on March's last Sunday at 01:00 UT (\-02:00 local
|
springing forward on March's last Sunday at 01:00 UT (\-02:00 local
|
||||||
time, i.e., 22:00 the previous day) and falling back on October's last
|
time, i.e., 22:00 the previous day) and falling back on October's last
|
||||||
Sunday at 01:00 UT (\-01:00 local time, i.e., 23:00 the previous day).
|
Sunday at 01:00 UT (\-01:00 local time, i.e., 23:00 the previous day).
|
||||||
The abbreviations for standard and daylight saving time are
|
The abbreviations for standard and daylight saving time are
|
||||||
.q "\*-03"
|
.q "\-03"
|
||||||
and
|
and
|
||||||
.q "\*-02".
|
.q "\-02".
|
||||||
.PP
|
.PP
|
||||||
If
|
If
|
||||||
.I TZ
|
.I TZ
|
||||||
|
|||||||
+82
-37
@@ -37,6 +37,38 @@
|
|||||||
# define SUPPORT_C89 1
|
# define SUPPORT_C89 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* The following feature-test macros should be defined before
|
||||||
|
any #include of a system header. */
|
||||||
|
|
||||||
|
/* Enable tm_gmtoff, tm_zone, and environ on GNUish systems. */
|
||||||
|
#define _GNU_SOURCE 1
|
||||||
|
/* Fix asctime_r on Solaris 11. */
|
||||||
|
#define _POSIX_PTHREAD_SEMANTICS 1
|
||||||
|
/* Enable strtoimax on pre-C99 Solaris 11. */
|
||||||
|
#define __EXTENSIONS__ 1
|
||||||
|
/* Cause MS-Windows headers to define POSIX names. */
|
||||||
|
#define _CRT_DECLARE_NONSTDC_NAMES 1
|
||||||
|
/* Prevent MS-Windows headers from defining min and max. */
|
||||||
|
#define NOMINMAX 1
|
||||||
|
|
||||||
|
/* On GNUish systems where time_t might be 32 or 64 bits, use 64.
|
||||||
|
On these platforms _FILE_OFFSET_BITS must also be 64; otherwise
|
||||||
|
setting _TIME_BITS to 64 does not work. The code does not
|
||||||
|
otherwise rely on _FILE_OFFSET_BITS being 64, since it does not
|
||||||
|
use off_t or functions like 'stat' that depend on off_t. */
|
||||||
|
#ifndef _TIME_BITS
|
||||||
|
# ifndef _FILE_OFFSET_BITS
|
||||||
|
# define _FILE_OFFSET_BITS 64
|
||||||
|
# endif
|
||||||
|
# if _FILE_OFFSET_BITS == 64
|
||||||
|
# define _TIME_BITS 64
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* End of feature-test macro definitions. */
|
||||||
|
|
||||||
|
|
||||||
#ifndef __STDC_VERSION__
|
#ifndef __STDC_VERSION__
|
||||||
# define __STDC_VERSION__ 0
|
# define __STDC_VERSION__ 0
|
||||||
#endif
|
#endif
|
||||||
@@ -51,6 +83,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __STDC_VERSION__ < 202311
|
#if __STDC_VERSION__ < 202311
|
||||||
|
# undef static_assert
|
||||||
# define static_assert(cond) extern int static_assert_check[(cond) ? 1 : -1]
|
# define static_assert(cond) extern int static_assert_check[(cond) ? 1 : -1]
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -87,11 +120,11 @@
|
|||||||
|
|
||||||
#if !defined HAVE_GETTEXT && defined __has_include
|
#if !defined HAVE_GETTEXT && defined __has_include
|
||||||
# if __has_include(<libintl.h>)
|
# if __has_include(<libintl.h>)
|
||||||
# define HAVE_GETTEXT true
|
# define HAVE_GETTEXT 1
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_GETTEXT
|
#ifndef HAVE_GETTEXT
|
||||||
# define HAVE_GETTEXT false
|
# define HAVE_GETTEXT 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_INCOMPATIBLE_CTIME_R
|
#ifndef HAVE_INCOMPATIBLE_CTIME_R
|
||||||
@@ -124,20 +157,20 @@
|
|||||||
|
|
||||||
#if !defined HAVE_SYS_STAT_H && defined __has_include
|
#if !defined HAVE_SYS_STAT_H && defined __has_include
|
||||||
# if !__has_include(<sys/stat.h>)
|
# if !__has_include(<sys/stat.h>)
|
||||||
# define HAVE_SYS_STAT_H false
|
# define HAVE_SYS_STAT_H 0
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_SYS_STAT_H
|
#ifndef HAVE_SYS_STAT_H
|
||||||
# define HAVE_SYS_STAT_H true
|
# define HAVE_SYS_STAT_H 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined HAVE_UNISTD_H && defined __has_include
|
#if !defined HAVE_UNISTD_H && defined __has_include
|
||||||
# if !__has_include(<unistd.h>)
|
# if !__has_include(<unistd.h>)
|
||||||
# define HAVE_UNISTD_H false
|
# define HAVE_UNISTD_H 0
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_UNISTD_H
|
#ifndef HAVE_UNISTD_H
|
||||||
# define HAVE_UNISTD_H true
|
# define HAVE_UNISTD_H 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NETBSD_INSPIRED
|
#ifndef NETBSD_INSPIRED
|
||||||
@@ -149,25 +182,6 @@
|
|||||||
# define ctime_r _incompatible_ctime_r
|
# define ctime_r _incompatible_ctime_r
|
||||||
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
||||||
|
|
||||||
/* Enable tm_gmtoff, tm_zone, and environ on GNUish systems. */
|
|
||||||
#define _GNU_SOURCE 1
|
|
||||||
/* Fix asctime_r on Solaris 11. */
|
|
||||||
#define _POSIX_PTHREAD_SEMANTICS 1
|
|
||||||
/* Enable strtoimax on pre-C99 Solaris 11. */
|
|
||||||
#define __EXTENSIONS__ 1
|
|
||||||
|
|
||||||
/* On GNUish systems where time_t might be 32 or 64 bits, use 64.
|
|
||||||
On these platforms _FILE_OFFSET_BITS must also be 64; otherwise
|
|
||||||
setting _TIME_BITS to 64 does not work. The code does not
|
|
||||||
otherwise rely on _FILE_OFFSET_BITS being 64, since it does not
|
|
||||||
use off_t or functions like 'stat' that depend on off_t. */
|
|
||||||
#ifndef _FILE_OFFSET_BITS
|
|
||||||
# define _FILE_OFFSET_BITS 64
|
|
||||||
#endif
|
|
||||||
#if !defined _TIME_BITS && _FILE_OFFSET_BITS == 64
|
|
||||||
# define _TIME_BITS 64
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Nested includes
|
** Nested includes
|
||||||
*/
|
*/
|
||||||
@@ -260,6 +274,10 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_SNPRINTF
|
||||||
|
# define HAVE_SNPRINTF (!PORT_TO_C89 || 199901 <= __STDC_VERSION__)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_STRFTIME_L
|
#ifndef HAVE_STRFTIME_L
|
||||||
# if _POSIX_VERSION < 200809
|
# if _POSIX_VERSION < 200809
|
||||||
# define HAVE_STRFTIME_L 0
|
# define HAVE_STRFTIME_L 0
|
||||||
@@ -305,7 +323,7 @@
|
|||||||
** stdint.h, even with pre-C99 compilers.
|
** stdint.h, even with pre-C99 compilers.
|
||||||
*/
|
*/
|
||||||
#if !defined HAVE_STDINT_H && defined __has_include
|
#if !defined HAVE_STDINT_H && defined __has_include
|
||||||
# define HAVE_STDINT_H true /* C23 __has_include implies C99 stdint.h. */
|
# define HAVE_STDINT_H 1 /* C23 __has_include implies C99 stdint.h. */
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_STDINT_H
|
#ifndef HAVE_STDINT_H
|
||||||
# define HAVE_STDINT_H \
|
# define HAVE_STDINT_H \
|
||||||
@@ -375,11 +393,15 @@ typedef int int_fast32_t;
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef INT_LEAST32_MAX
|
||||||
|
typedef int_fast32_t int_least32_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef INTMAX_MAX
|
#ifndef INTMAX_MAX
|
||||||
# ifdef LLONG_MAX
|
# ifdef LLONG_MAX
|
||||||
typedef long long intmax_t;
|
typedef long long intmax_t;
|
||||||
# ifndef HAVE_STRTOLL
|
# ifndef HAVE_STRTOLL
|
||||||
# define HAVE_STRTOLL true
|
# define HAVE_STRTOLL 1
|
||||||
# endif
|
# endif
|
||||||
# if HAVE_STRTOLL
|
# if HAVE_STRTOLL
|
||||||
# define strtoimax strtoll
|
# define strtoimax strtoll
|
||||||
@@ -459,7 +481,7 @@ typedef unsigned long uintmax_t;
|
|||||||
hosts, unless compiled with -DHAVE_STDCKDINT_H=0 or with pre-C23 EDG. */
|
hosts, unless compiled with -DHAVE_STDCKDINT_H=0 or with pre-C23 EDG. */
|
||||||
#if !defined HAVE_STDCKDINT_H && defined __has_include
|
#if !defined HAVE_STDCKDINT_H && defined __has_include
|
||||||
# if __has_include(<stdckdint.h>)
|
# if __has_include(<stdckdint.h>)
|
||||||
# define HAVE_STDCKDINT_H true
|
# define HAVE_STDCKDINT_H 1
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_STDCKDINT_H
|
#ifdef HAVE_STDCKDINT_H
|
||||||
@@ -554,13 +576,26 @@ typedef unsigned long uintmax_t;
|
|||||||
# define ATTRIBUTE_REPRODUCIBLE /* empty */
|
# define ATTRIBUTE_REPRODUCIBLE /* empty */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE___HAS_C_ATTRIBUTE
|
||||||
|
# if __has_c_attribute(unsequenced)
|
||||||
|
# define ATTRIBUTE_UNSEQUENCED [[unsequenced]]
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#ifndef ATTRIBUTE_UNSEQUENCED
|
||||||
|
# define ATTRIBUTE_UNSEQUENCED /* empty */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* GCC attributes that are useful in tzcode.
|
/* GCC attributes that are useful in tzcode.
|
||||||
|
__attribute__((const)) is stricter than [[unsequenced]],
|
||||||
|
so the latter is an adequate substitute in non-GCC C23 platforms.
|
||||||
__attribute__((pure)) is stricter than [[reproducible]],
|
__attribute__((pure)) is stricter than [[reproducible]],
|
||||||
so the latter is an adequate substitute in non-GCC C23 platforms. */
|
so the latter is an adequate substitute in non-GCC C23 platforms. */
|
||||||
#if __GNUC__ < 3
|
#if __GNUC__ < 3
|
||||||
|
# define ATTRIBUTE_CONST ATTRIBUTE_UNSEQUENCED
|
||||||
# define ATTRIBUTE_FORMAT(spec) /* empty */
|
# define ATTRIBUTE_FORMAT(spec) /* empty */
|
||||||
# define ATTRIBUTE_PURE ATTRIBUTE_REPRODUCIBLE
|
# define ATTRIBUTE_PURE ATTRIBUTE_REPRODUCIBLE
|
||||||
#else
|
#else
|
||||||
|
# define ATTRIBUTE_CONST __attribute__((const))
|
||||||
# define ATTRIBUTE_FORMAT(spec) __attribute__((format spec))
|
# define ATTRIBUTE_FORMAT(spec) __attribute__((format spec))
|
||||||
# define ATTRIBUTE_PURE __attribute__((pure))
|
# define ATTRIBUTE_PURE __attribute__((pure))
|
||||||
#endif
|
#endif
|
||||||
@@ -593,6 +628,12 @@ typedef unsigned long uintmax_t;
|
|||||||
# define RESERVE_STD_EXT_IDS 0
|
# define RESERVE_STD_EXT_IDS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef time_tz
|
||||||
|
# define defined_time_tz true
|
||||||
|
#else
|
||||||
|
# define defined_time_tz false
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If standard C identifiers with external linkage (e.g., localtime)
|
/* If standard C identifiers with external linkage (e.g., localtime)
|
||||||
are reserved and are not already being renamed anyway, rename them
|
are reserved and are not already being renamed anyway, rename them
|
||||||
as if compiling with '-Dtime_tz=time_t'. */
|
as if compiling with '-Dtime_tz=time_t'. */
|
||||||
@@ -608,9 +649,9 @@ typedef unsigned long uintmax_t;
|
|||||||
** typical platforms.
|
** typical platforms.
|
||||||
*/
|
*/
|
||||||
#if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
|
#if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
|
||||||
# define TZ_TIME_T 1
|
# define TZ_TIME_T true
|
||||||
#else
|
#else
|
||||||
# define TZ_TIME_T 0
|
# define TZ_TIME_T false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined LOCALTIME_IMPLEMENTATION && TZ_TIME_T
|
#if defined LOCALTIME_IMPLEMENTATION && TZ_TIME_T
|
||||||
@@ -707,7 +748,7 @@ DEPRECATED_IN_C23 char *ctime(time_t const *);
|
|||||||
char *asctime_r(struct tm const *restrict, char *restrict);
|
char *asctime_r(struct tm const *restrict, char *restrict);
|
||||||
char *ctime_r(time_t const *, char *);
|
char *ctime_r(time_t const *, char *);
|
||||||
#endif
|
#endif
|
||||||
double difftime(time_t, time_t);
|
ATTRIBUTE_CONST double difftime(time_t, time_t);
|
||||||
size_t strftime(char *restrict, size_t, char const *restrict,
|
size_t strftime(char *restrict, size_t, char const *restrict,
|
||||||
struct tm const *restrict);
|
struct tm const *restrict);
|
||||||
# if HAVE_STRFTIME_L
|
# if HAVE_STRFTIME_L
|
||||||
@@ -729,9 +770,9 @@ void tzset(void);
|
|||||||
|| defined __GLIBC__ || defined __tm_zone /* musl */ \
|
|| defined __GLIBC__ || defined __tm_zone /* musl */ \
|
||||||
|| defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
|
|| defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
|
||||||
|| (defined __APPLE__ && defined __MACH__))
|
|| (defined __APPLE__ && defined __MACH__))
|
||||||
# define HAVE_DECL_TIMEGM true
|
# define HAVE_DECL_TIMEGM 1
|
||||||
# else
|
# else
|
||||||
# define HAVE_DECL_TIMEGM false
|
# define HAVE_DECL_TIMEGM 0
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if !HAVE_DECL_TIMEGM && !defined timegm
|
#if !HAVE_DECL_TIMEGM && !defined timegm
|
||||||
@@ -771,7 +812,11 @@ extern long altzone;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef STD_INSPIRED
|
#ifndef STD_INSPIRED
|
||||||
# define STD_INSPIRED 0
|
# ifdef __NetBSD__
|
||||||
|
# define STD_INSPIRED 1
|
||||||
|
# else
|
||||||
|
# define STD_INSPIRED 0
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if STD_INSPIRED
|
#if STD_INSPIRED
|
||||||
# if TZ_TIME_T || !defined offtime
|
# if TZ_TIME_T || !defined offtime
|
||||||
@@ -880,7 +925,7 @@ ATTRIBUTE_PURE time_t time2posix_z(timezone_t, time_t);
|
|||||||
default: TIME_T_MAX_NO_PADDING) \
|
default: TIME_T_MAX_NO_PADDING) \
|
||||||
: (time_t) -1)
|
: (time_t) -1)
|
||||||
enum { SIGNED_PADDING_CHECK_NEEDED
|
enum { SIGNED_PADDING_CHECK_NEEDED
|
||||||
= _Generic((time_t) 0,
|
= _Generic((time_t) 0,
|
||||||
signed char: false, short: false,
|
signed char: false, short: false,
|
||||||
int: false, long: false, long long: false,
|
int: false, long: false, long long: false,
|
||||||
default: true) };
|
default: true) };
|
||||||
@@ -927,8 +972,8 @@ static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED
|
|||||||
# define UNINIT_TRAP 0
|
# define UNINIT_TRAP 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* localtime.c sometimes needs access to timeoff if it is not already public.
|
/* strftime.c sometimes needs access to timeoff if it is not already public.
|
||||||
tz_private_timeoff should be used only by localtime.c. */
|
tz_private_timeoff should be used only by localtime.c and strftime.c. */
|
||||||
#if (!defined EXTERN_TIMEOFF \
|
#if (!defined EXTERN_TIMEOFF \
|
||||||
&& defined TM_GMTOFF && (200809 < _POSIX_VERSION || ! UNINIT_TRAP))
|
&& defined TM_GMTOFF && (200809 < _POSIX_VERSION || ! UNINIT_TRAP))
|
||||||
# ifndef timeoff
|
# ifndef timeoff
|
||||||
|
|||||||
+67
-16
@@ -39,8 +39,63 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* If true, the value returned by an idealized unlimited-range mktime
|
||||||
|
always fits into an integer type with bounds MIN and MAX.
|
||||||
|
If false, the value might not fit.
|
||||||
|
This macro is usable in #if if its arguments are.
|
||||||
|
Add or subtract 2**31 - 1 for the maximum UT offset allowed in a TZif file,
|
||||||
|
divide by the maximum number of non-leap seconds in a year,
|
||||||
|
divide again by two just to be safe,
|
||||||
|
and account for the tm_year origin (1900) and time_t origin (1970). */
|
||||||
|
#define MKTIME_FITS_IN(min, max) \
|
||||||
|
((min) < 0 \
|
||||||
|
&& ((min) + 0x7fffffff) / 366 / 24 / 60 / 60 / 2 + 1970 - 1900 < INT_MIN \
|
||||||
|
&& INT_MAX < ((max) - 0x7fffffff) / 366 / 24 / 60 / 60 / 2 + 1970 - 1900)
|
||||||
|
|
||||||
|
/* MKTIME_MIGHT_OVERFLOW is true if mktime can fail due to time_t overflow
|
||||||
|
or if it is not known whether mktime can fail,
|
||||||
|
and is false if mktime definitely cannot fail.
|
||||||
|
This macro is usable in #if, and so does not use TIME_T_MAX or sizeof.
|
||||||
|
If the builder has not configured this macro, guess based on what
|
||||||
|
known platforms do. When in doubt, guess true. */
|
||||||
|
#ifndef MKTIME_MIGHT_OVERFLOW
|
||||||
|
# if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
|
||||||
|
# include <sys/param.h>
|
||||||
|
# endif
|
||||||
|
# if ((/* The following heuristics assume native time_t. */ \
|
||||||
|
defined_time_tz) \
|
||||||
|
|| ((/* Traditional time_t is 'long', so if 'long' is not wide enough \
|
||||||
|
assume overflow unless we're on a known-safe host. */ \
|
||||||
|
!MKTIME_FITS_IN(LONG_MIN, LONG_MAX)) \
|
||||||
|
&& (/* GNU C Library 2.29 (2019-02-01) and later has 64-bit time_t \
|
||||||
|
if __TIMESIZE is 64. */ \
|
||||||
|
!defined __TIMESIZE || __TIMESIZE < 64) \
|
||||||
|
&& (/* FreeBSD 12 r320347 (__FreeBSD_version 1200036; 2017-06-26), \
|
||||||
|
and later has 64-bit time_t on all platforms but i386 which \
|
||||||
|
is currently scheduled for end-of-life on 2028-11-30. */ \
|
||||||
|
!defined __FreeBSD_version || __FreeBSD_version < 1200036 \
|
||||||
|
|| defined __i386) \
|
||||||
|
&& (/* NetBSD 6.0 (2012-10-17) and later has 64-bit time_t. */ \
|
||||||
|
!defined __NetBSD_Version__ || __NetBSD_Version__ < 600000000) \
|
||||||
|
&& (/* OpenBSD 5.5 (2014-05-01) and later has 64-bit time_t. */ \
|
||||||
|
!defined OpenBSD || OpenBSD < 201405)))
|
||||||
|
# define MKTIME_MIGHT_OVERFLOW 1
|
||||||
|
# else
|
||||||
|
# define MKTIME_MIGHT_OVERFLOW 0
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
/* Check that MKTIME_MIGHT_OVERFLOW is consistent with time_t's range. */
|
||||||
|
static_assert(MKTIME_MIGHT_OVERFLOW
|
||||||
|
|| MKTIME_FITS_IN(TIME_T_MIN, TIME_T_MAX));
|
||||||
|
|
||||||
|
#if MKTIME_MIGHT_OVERFLOW
|
||||||
|
/* Do this after system includes as it redefines time_t, mktime, timeoff. */
|
||||||
|
# define USE_TIMEX_T true
|
||||||
|
# include "localtime.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DEPRECATE_TWO_DIGIT_YEARS
|
#ifndef DEPRECATE_TWO_DIGIT_YEARS
|
||||||
# define DEPRECATE_TWO_DIGIT_YEARS false
|
# define DEPRECATE_TWO_DIGIT_YEARS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct lc_time_T {
|
struct lc_time_T {
|
||||||
@@ -135,10 +190,6 @@ strftime(char *restrict s, size_t maxsize, char const *restrict format,
|
|||||||
|
|
||||||
tzset();
|
tzset();
|
||||||
p = _fmt(format, t, s, s + maxsize, &warn);
|
p = _fmt(format, t, s, s + maxsize, &warn);
|
||||||
if (!p) {
|
|
||||||
errno = EOVERFLOW;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (DEPRECATE_TWO_DIGIT_YEARS
|
if (DEPRECATE_TWO_DIGIT_YEARS
|
||||||
&& warn != IN_NONE && getenv(YEAR_2000_NAME)) {
|
&& warn != IN_NONE && getenv(YEAR_2000_NAME)) {
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
@@ -170,7 +221,12 @@ _fmt(const char *format, const struct tm *t, char *pt,
|
|||||||
if (*format == '%') {
|
if (*format == '%') {
|
||||||
label:
|
label:
|
||||||
switch (*++format) {
|
switch (*++format) {
|
||||||
case '\0':
|
default:
|
||||||
|
/* Output unknown conversion specifiers as-is,
|
||||||
|
to aid debugging. This includes '%' at
|
||||||
|
format end. This conforms to C23 section
|
||||||
|
7.29.3.5 paragraph 6, which says behavior
|
||||||
|
is undefined here. */
|
||||||
--format;
|
--format;
|
||||||
break;
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
@@ -327,16 +383,17 @@ _fmt(const char *format, const struct tm *t, char *pt,
|
|||||||
tm.tm_mday = t->tm_mday;
|
tm.tm_mday = t->tm_mday;
|
||||||
tm.tm_mon = t->tm_mon;
|
tm.tm_mon = t->tm_mon;
|
||||||
tm.tm_year = t->tm_year;
|
tm.tm_year = t->tm_year;
|
||||||
|
|
||||||
|
/* Get the time_t value for TM.
|
||||||
|
Native time_t, or its redefinition
|
||||||
|
by localtime.c above, is wide enough
|
||||||
|
so that this cannot overflow. */
|
||||||
#ifdef TM_GMTOFF
|
#ifdef TM_GMTOFF
|
||||||
mkt = timeoff(&tm, t->TM_GMTOFF);
|
mkt = timeoff(&tm, t->TM_GMTOFF);
|
||||||
#else
|
#else
|
||||||
tm.tm_isdst = t->tm_isdst;
|
tm.tm_isdst = t->tm_isdst;
|
||||||
mkt = mktime(&tm);
|
mkt = mktime(&tm);
|
||||||
#endif
|
#endif
|
||||||
/* If mktime fails, %s expands to the
|
|
||||||
value of (time_t) -1 as a failure
|
|
||||||
marker; this is better in practice
|
|
||||||
than strftime failing. */
|
|
||||||
if (TYPE_SIGNED(time_t)) {
|
if (TYPE_SIGNED(time_t)) {
|
||||||
intmax_t n = mkt;
|
intmax_t n = mkt;
|
||||||
sprintf(buf, "%"PRIdMAX, n);
|
sprintf(buf, "%"PRIdMAX, n);
|
||||||
@@ -590,12 +647,6 @@ _fmt(const char *format, const struct tm *t, char *pt,
|
|||||||
warnp);
|
warnp);
|
||||||
continue;
|
continue;
|
||||||
case '%':
|
case '%':
|
||||||
/*
|
|
||||||
** X311J/88-090 (4.12.3.5): if conversion char is
|
|
||||||
** undefined, behavior is undefined. Print out the
|
|
||||||
** character itself as printf(3) also does.
|
|
||||||
*/
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-13
@@ -123,8 +123,9 @@ If geolocation information is available, a selection interface can
|
|||||||
locate the user on a timezone map or prioritize names that are
|
locate the user on a timezone map or prioritize names that are
|
||||||
geographically close. For an example selection interface, see the
|
geographically close. For an example selection interface, see the
|
||||||
<code>tzselect</code> program in the <code><abbr>tz</abbr></code> code.
|
<code>tzselect</code> program in the <code><abbr>tz</abbr></code> code.
|
||||||
The <a href="https://cldr.unicode.org">Unicode Common Locale Data
|
Unicode's <a href="https://cldr.unicode.org">Common Locale Data
|
||||||
Repository</a> contains data that may be useful for other selection
|
Repository (<abbr>CLDR</abbr>)</a>
|
||||||
|
contains data that may be useful for other selection
|
||||||
interfaces; it maps timezone names like <code>Europe/Prague</code> to
|
interfaces; it maps timezone names like <code>Europe/Prague</code> to
|
||||||
locale-dependent strings like "Prague", "Praha", "Прага", and "布拉格".
|
locale-dependent strings like "Prague", "Praha", "Прага", and "布拉格".
|
||||||
</p>
|
</p>
|
||||||
@@ -200,6 +201,8 @@ in decreasing order of importance:
|
|||||||
<li>
|
<li>
|
||||||
A name must not be empty, or contain '<code>//</code>', or
|
A name must not be empty, or contain '<code>//</code>', or
|
||||||
start or end with '<code>/</code>'.
|
start or end with '<code>/</code>'.
|
||||||
|
Also, a name must not be '<code>Etc/Unknown</code>', as
|
||||||
|
<abbr>CLDR</abbr> uses that string for an unknown or invalid timezone.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Do not use names that differ only in case.
|
Do not use names that differ only in case.
|
||||||
@@ -220,10 +223,18 @@ in decreasing order of importance:
|
|||||||
do not need locations, since local time is not defined there.
|
do not need locations, since local time is not defined there.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
If all the clocks in a timezone have agreed since 1970,
|
If all clocks in a region have agreed since 1970,
|
||||||
do not bother to include more than one timezone
|
give them just one name even if some of the clocks disagreed before 1970,
|
||||||
even if some of the clocks disagreed before 1970.
|
or reside in different countries or in notable or faraway locations.
|
||||||
Otherwise these tables would become annoyingly large.
|
Otherwise these tables would become annoyingly large.
|
||||||
|
For example, do not create a name <code>Indian/Crozet</code>
|
||||||
|
as a near-duplicate or alias of <code>Asia/Dubai</code>
|
||||||
|
merely because they are different countries or territories,
|
||||||
|
or their clocks disagreed before 1970, or the
|
||||||
|
<a href="https://en.wikipedia.org/wiki/Crozet_Islands">Crozet Islands</a>
|
||||||
|
are notable in their own right,
|
||||||
|
or the Crozet Islands are not adjacent to other locations
|
||||||
|
that use <code>Asia/Dubai</code>.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
If boundaries between regions are fluid, such as during a war or
|
If boundaries between regions are fluid, such as during a war or
|
||||||
@@ -579,10 +590,10 @@ in decreasing order of importance:
|
|||||||
locations while uninhabited.
|
locations while uninhabited.
|
||||||
The leading '<code>-</code>' is a flag that the <abbr>UT</abbr> offset is in
|
The leading '<code>-</code>' is a flag that the <abbr>UT</abbr> offset is in
|
||||||
some sense undefined; this notation is derived
|
some sense undefined; this notation is derived
|
||||||
from <a href="https://datatracker.ietf.org/doc/html/rfc3339">Internet
|
from <a href="https://www.rfc-editor.org/rfc/rfc3339">Internet
|
||||||
<abbr title="Request For Comments">RFC</abbr> 3339</a>.
|
<abbr title="Request For Comments">RFC</abbr> 3339</a>.
|
||||||
(The abbreviation 'Z' that
|
(The abbreviation 'Z' that
|
||||||
<a href="https://datatracker.ietf.org/doc/html/rfc9557">Internet
|
<a href="https://www.rfc-editor.org/rfc/rfc9557">Internet
|
||||||
<abbr>RFC</abbr> 9557</a> uses for this concept
|
<abbr>RFC</abbr> 9557</a> uses for this concept
|
||||||
would violate the POSIX requirement
|
would violate the POSIX requirement
|
||||||
of at least three characters in an abbreviation.)
|
of at least three characters in an abbreviation.)
|
||||||
@@ -1115,8 +1126,8 @@ However POSIX.1-2024, like earlier POSIX editions, has some limitations:
|
|||||||
the name of a file from which time-related information is read.
|
the name of a file from which time-related information is read.
|
||||||
The file's format is <dfn><abbr>TZif</abbr></dfn>,
|
The file's format is <dfn><abbr>TZif</abbr></dfn>,
|
||||||
a timezone information format that contains binary data; see
|
a timezone information format that contains binary data; see
|
||||||
<a href="https://datatracker.ietf.org/doc/html/8536">Internet
|
<a href="https://www.rfc-editor.org/rfc/9636">Internet
|
||||||
<abbr>RFC</abbr> 8536</a>.
|
<abbr>RFC</abbr> 9636</a>.
|
||||||
The daylight saving time rules to be used for a
|
The daylight saving time rules to be used for a
|
||||||
particular timezone are encoded in the
|
particular timezone are encoded in the
|
||||||
<abbr>TZif</abbr> file; the format of the file allows <abbr>US</abbr>,
|
<abbr>TZif</abbr> file; the format of the file allows <abbr>US</abbr>,
|
||||||
@@ -1201,12 +1212,15 @@ The vestigial <abbr>API</abbr>s are:
|
|||||||
The <code>tm_isdst</code> member is almost never needed and most of
|
The <code>tm_isdst</code> member is almost never needed and most of
|
||||||
its uses should be discouraged in favor of the abovementioned
|
its uses should be discouraged in favor of the abovementioned
|
||||||
<abbr>API</abbr>s.
|
<abbr>API</abbr>s.
|
||||||
|
It was intended as an index into the <code>tzname</code> variable,
|
||||||
|
but as mentioned previously that usage is obsolete.
|
||||||
Although it can still be used in arguments to
|
Although it can still be used in arguments to
|
||||||
<code>mktime</code> to disambiguate timestamps near
|
<code>mktime</code> to disambiguate timestamps near
|
||||||
a <abbr>DST</abbr> transition when the clock jumps back on
|
a <abbr>DST</abbr> transition when the clock jumps back on
|
||||||
platforms lacking <code>tm_gmtoff</code>, this
|
platforms lacking <code>tm_gmtoff</code>, this
|
||||||
disambiguation does not work when standard time itself jumps back,
|
disambiguation works only for proleptic <code>TZ</code> strings;
|
||||||
which can occur when a location changes to a time zone with a
|
it does not work in general for geographical timezones,
|
||||||
|
such as when a location changes to a time zone with a
|
||||||
lesser <abbr>UT</abbr> offset.
|
lesser <abbr>UT</abbr> offset.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -1223,8 +1237,8 @@ The vestigial <abbr>API</abbr>s are:
|
|||||||
Programs that in the past used the <code>timezone</code> function
|
Programs that in the past used the <code>timezone</code> function
|
||||||
may now examine <code>localtime(&clock)->tm_zone</code>
|
may now examine <code>localtime(&clock)->tm_zone</code>
|
||||||
(if <code>TM_ZONE</code> is defined) or
|
(if <code>TM_ZONE</code> is defined) or
|
||||||
<code>tzname[localtime(&clock)->tm_isdst]</code>
|
use <code>strftime</code> with a <code>%Z</code> conversion specification
|
||||||
(if <code>HAVE_TZNAME</code> is nonzero) to learn the correct time
|
to learn the correct time
|
||||||
zone abbreviation to use.
|
zone abbreviation to use.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
|||||||
+30
-15
@@ -194,9 +194,9 @@ After obtaining the code and data files, see the
|
|||||||
The code lets you compile the <code><abbr>tz</abbr></code> source files into
|
The code lets you compile the <code><abbr>tz</abbr></code> source files into
|
||||||
machine-readable binary files, one for each location. The binary files
|
machine-readable binary files, one for each location. The binary files
|
||||||
are in a special format specified by
|
are in a special format specified by
|
||||||
<a href="https://datatracker.ietf.org/doc/html/8536">The
|
<a href="https://www.rfc-editor.org/rfc/9636">The
|
||||||
Time Zone Information Format (<abbr>TZif</abbr>)</a>
|
Time Zone Information Format (<abbr>TZif</abbr>)</a>
|
||||||
(Internet <abbr title="Request For Comments">RFC</abbr> 8536).
|
(Internet <abbr title="Request For Comments">RFC</abbr> 9636).
|
||||||
The code also lets
|
The code also lets
|
||||||
you read a <abbr>TZif</abbr> file and interpret timestamps for that
|
you read a <abbr>TZif</abbr> file and interpret timestamps for that
|
||||||
location.</p>
|
location.</p>
|
||||||
@@ -260,7 +260,7 @@ Studio Code</a>.
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
For further information about updates, please see
|
For further information about updates, please see
|
||||||
<a href="https://datatracker.ietf.org/doc/html/rfc6557">Procedures for
|
<a href="https://www.rfc-editor.org/rfc/rfc6557">Procedures for
|
||||||
Maintaining the Time Zone Database</a> (Internet <abbr>RFC</abbr> 6557).
|
Maintaining the Time Zone Database</a> (Internet <abbr>RFC</abbr> 6557).
|
||||||
More detail can be
|
More detail can be
|
||||||
found in <a href="theory.html">Theory and pragmatics of the
|
found in <a href="theory.html">Theory and pragmatics of the
|
||||||
@@ -379,26 +379,26 @@ calculates the current time difference between locations.</li>
|
|||||||
<li>The <a href="https://www.ietf.org">Internet Engineering Task Force</a>'s
|
<li>The <a href="https://www.ietf.org">Internet Engineering Task Force</a>'s
|
||||||
<a href="https://datatracker.ietf.org/wg/tzdist/charter/">Time Zone Data
|
<a href="https://datatracker.ietf.org/wg/tzdist/charter/">Time Zone Data
|
||||||
Distribution Service (tzdist) working group</a> defined <a
|
Distribution Service (tzdist) working group</a> defined <a
|
||||||
href="https://datatracker.ietf.org/doc/html/rfc7808">TZDIST</a>
|
href="https://www.rfc-editor.org/rfc/rfc7808">TZDIST</a>
|
||||||
(Internet <abbr>RFC</abbr> 7808), a time zone data distribution service,
|
(Internet <abbr>RFC</abbr> 7808), a time zone data distribution service,
|
||||||
along with <a href="https://datatracker.ietf.org/doc/html/rfc7809">CalDAV</a>
|
along with <a href="https://www.rfc-editor.org/rfc/rfc7809">CalDAV</a>
|
||||||
(Internet <abbr>RFC</abbr> 7809), a calendar access protocol for
|
(Internet <abbr>RFC</abbr> 7809), a calendar access protocol for
|
||||||
transferring time zone data by reference.
|
transferring time zone data by reference.
|
||||||
<a href="https://devguide.calconnect.org/Time-Zones/TZDS/">TZDIST
|
<a href="https://devguide.calconnect.org/Time-Zones/TZDS/">TZDIST
|
||||||
implementations</a> are available.
|
implementations</a> are available.
|
||||||
The <a href="https://www.ietf.org/mailman/listinfo/tzdist-bis">tzdist-bis
|
The <a href="https://www.ietf.org/mailman/listinfo/tzdist-bis">tzdist-bis
|
||||||
mailing list</a> discusses possible extensions.</li>
|
mailing list</a> discusses possible extensions.</li>
|
||||||
<li>The <a href="https://datatracker.ietf.org/doc/html/rfc5545">
|
<li>The <a href="https://www.rfc-editor.org/rfc/rfc5545">
|
||||||
Internet Calendaring and Scheduling Core Object Specification
|
Internet Calendaring and Scheduling Core Object Specification
|
||||||
(iCalendar)</a> (Internet <abbr>RFC</abbr> 5445)
|
(iCalendar)</a> (Internet <abbr>RFC</abbr> 5445)
|
||||||
covers time zone
|
covers time zone
|
||||||
data; see its VTIMEZONE calendar component.
|
data; see its VTIMEZONE calendar component.
|
||||||
The iCalendar format requires specialized parsers and generators; a
|
The iCalendar format requires specialized parsers and generators; a
|
||||||
variant <a href="https://datatracker.ietf.org/doc/html/rfc6321">xCal</a>
|
variant <a href="https://www.rfc-editor.org/rfc/rfc6321">xCal</a>
|
||||||
(Internet <abbr>RFC</abbr> 6321) uses
|
(Internet <abbr>RFC</abbr> 6321) uses
|
||||||
<a href="https://www.w3.org/XML/"><abbr
|
<a href="https://www.w3.org/XML/"><abbr
|
||||||
title="Extensible Markup Language">XML</abbr></a> format, and a variant
|
title="Extensible Markup Language">XML</abbr></a> format, and a variant
|
||||||
<a href="https://datatracker.ietf.org/doc/html/rfc7265">jCal</a>
|
<a href="https://www.rfc-editor.org/rfc/rfc7265">jCal</a>
|
||||||
(Internet <abbr>RFC</abbr> 7265)
|
(Internet <abbr>RFC</abbr> 7265)
|
||||||
uses <a href="https://www.json.org/json-en.html"><abbr
|
uses <a href="https://www.json.org/json-en.html"><abbr
|
||||||
title="JavaScript Object Notation">JSON</abbr></a> format.</li>
|
title="JavaScript Object Notation">JSON</abbr></a> format.</li>
|
||||||
@@ -935,7 +935,13 @@ with perhaps the best-documented history of clock adjustments.</dd>
|
|||||||
<dt>United States</dt>
|
<dt>United States</dt>
|
||||||
<dd>The Department of Transportation's <a
|
<dd>The Department of Transportation's <a
|
||||||
href="https://www.transportation.gov/regulations/recent-time-zone-proceedings">Recent
|
href="https://www.transportation.gov/regulations/recent-time-zone-proceedings">Recent
|
||||||
Time Zone Proceedings</a> lists changes to time zone boundaries.</dd>
|
Time Zone Proceedings</a> lists changes to
|
||||||
|
official written time zone boundaries, and its <a
|
||||||
|
href="https://geodata.bts.gov/datasets/usdot::time-zones/about">Time
|
||||||
|
Zones dataset</a> maps current boundaries.
|
||||||
|
These boundaries are only for standard time, so the current map puts
|
||||||
|
all of Arizona in one time zone even though part of Arizona
|
||||||
|
observes <abbr>DST</abbr> and part does not.</dd>
|
||||||
<dt>Uruguay</dt>
|
<dt>Uruguay</dt>
|
||||||
<dd>The Oceanography, Hydrography, and Meteorology Service of the Uruguayan
|
<dd>The Oceanography, Hydrography, and Meteorology Service of the Uruguayan
|
||||||
Navy (SOHMA) publishes an annual <a
|
Navy (SOHMA) publishes an annual <a
|
||||||
@@ -979,6 +985,14 @@ a Sleep Research Society position statement</a>.
|
|||||||
doi:<a href="https://doi.org/10.1093/sleep/zsac236">10.1093/sleep/zsac236</a>.
|
doi:<a href="https://doi.org/10.1093/sleep/zsac236">10.1093/sleep/zsac236</a>.
|
||||||
After reviewing the scientific literature, the Sleep Research Society
|
After reviewing the scientific literature, the Sleep Research Society
|
||||||
advocates permanent standard time due to its health benefits.
|
advocates permanent standard time due to its health benefits.
|
||||||
|
<li>Neumann P, von Blanckenburg K. <a
|
||||||
|
href="https://journals.sagepub.com/doi/full/10.1177/0961463X241310562">What
|
||||||
|
time will it be? A comprehensive literature review on daylight saving time</a>.
|
||||||
|
<em>Time Soc</em>. 2025-01-21.
|
||||||
|
doi:<a href="https://doi.org/10.1177/0961463X241310562">10.1177/0961463X241310562</a>.
|
||||||
|
This reviews DST's effects on electricity, health, crime, road safety,
|
||||||
|
and the economy, focusing on research since 2010, and concludes that
|
||||||
|
year-round standard time is preferable overall.
|
||||||
<li>Rishi MA, Cheng JY, Strang AR <em>et al</em>.
|
<li>Rishi MA, Cheng JY, Strang AR <em>et al</em>.
|
||||||
<a href="https://jcsm.aasm.org/doi/10.5664/jcsm.10898">Permanent standard time
|
<a href="https://jcsm.aasm.org/doi/10.5664/jcsm.10898">Permanent standard time
|
||||||
is the optimal choice for health and safety:
|
is the optimal choice for health and safety:
|
||||||
@@ -994,7 +1008,8 @@ should we abolish Daylight Saving Time?</a>
|
|||||||
<em>J Biol Rhythms.</em> 2019;34(3):227–230.
|
<em>J Biol Rhythms.</em> 2019;34(3):227–230.
|
||||||
doi:<a href="https://doi.org/10.1177/0748730419854197">10.1177/0748730419854197</a>.
|
doi:<a href="https://doi.org/10.1177/0748730419854197">10.1177/0748730419854197</a>.
|
||||||
The Society for Research on Biological Rhythms
|
The Society for Research on Biological Rhythms
|
||||||
opposes DST changes and permanent DST, and advocates that governments adopt
|
opposes <abbr>DST</abbr> changes and permanent <abbr>DST</abbr>,
|
||||||
|
and advocates that governments adopt
|
||||||
"permanent Standard Time for the health and safety of their citizens".</li>
|
"permanent Standard Time for the health and safety of their citizens".</li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
@@ -1023,7 +1038,7 @@ title="Institute of Electrical and Electronics Engineers">IEEE</abbr> 1588)
|
|||||||
can achieve submicrosecond clock accuracy on a local area network
|
can achieve submicrosecond clock accuracy on a local area network
|
||||||
with special-purpose hardware.</li>
|
with special-purpose hardware.</li>
|
||||||
<li><a
|
<li><a
|
||||||
href="https://datatracker.ietf.org/doc/html/rfc4833">Timezone
|
href="https://www.rfc-editor.org/rfc/rfc4833">Timezone
|
||||||
Options for <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr></a>
|
Options for <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr></a>
|
||||||
(Internet <abbr>RFC</abbr> 4833)
|
(Internet <abbr>RFC</abbr> 4833)
|
||||||
specifies a <a
|
specifies a <a
|
||||||
@@ -1105,7 +1120,7 @@ the abovementioned <abbr>NTP</abbr> implementations, <a
|
|||||||
href="https://github.com/google/unsmear">supports</a> conversion between
|
href="https://github.com/google/unsmear">supports</a> conversion between
|
||||||
<abbr>UTC</abbr> and smeared <abbr>POSIX</abbr> timestamps, and is used by major
|
<abbr>UTC</abbr> and smeared <abbr>POSIX</abbr> timestamps, and is used by major
|
||||||
cloud service providers. However, according to
|
cloud service providers. However, according to
|
||||||
<a href="https://datatracker.ietf.org/doc/html/rfc8633#section-3.7.1">§3.7.1 of
|
<a href="https://www.rfc-editor.org/rfc/rfc8633#section-3.7.1">§3.7.1 of
|
||||||
Network Time Protocol Best Current Practices</a>
|
Network Time Protocol Best Current Practices</a>
|
||||||
(Internet <abbr>RFC</abbr> 8633), leap smearing is not suitable for
|
(Internet <abbr>RFC</abbr> 8633), leap smearing is not suitable for
|
||||||
applications requiring accurate <abbr>UTC</abbr> or civil time,
|
applications requiring accurate <abbr>UTC</abbr> or civil time,
|
||||||
@@ -1165,16 +1180,16 @@ interchange – Part 1: Basic rules</em></a>.</li>
|
|||||||
<a href="https://www.w3.org/TR/xmlschema/#dateTime"><abbr>XML</abbr>
|
<a href="https://www.w3.org/TR/xmlschema/#dateTime"><abbr>XML</abbr>
|
||||||
Schema: Datatypes – dateTime</a> specifies a format inspired by
|
Schema: Datatypes – dateTime</a> specifies a format inspired by
|
||||||
<abbr>ISO</abbr> 8601 that is in common use in <abbr>XML</abbr> data.</li>
|
<abbr>ISO</abbr> 8601 that is in common use in <abbr>XML</abbr> data.</li>
|
||||||
<li><a href="https://datatracker.ietf.org/doc/html/rfc5322#section-3.3">§3.3 of
|
<li><a href="https://www.rfc-editor.org/rfc/rfc5322#section-3.3">§3.3 of
|
||||||
Internet Message Format</a> (Internet <abbr>RFC</abbr> 5322)
|
Internet Message Format</a> (Internet <abbr>RFC</abbr> 5322)
|
||||||
specifies the time notation used in email and <a
|
specifies the time notation used in email and <a
|
||||||
href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol"><abbr>HTTP</abbr></a>
|
href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol"><abbr>HTTP</abbr></a>
|
||||||
headers.</li>
|
headers.</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="https://datatracker.ietf.org/doc/html/rfc3339">Date and Time
|
<a href="https://www.rfc-editor.org/rfc/rfc3339">Date and Time
|
||||||
on the Internet: Timestamps</a> (Internet <abbr>RFC</abbr> 3339)
|
on the Internet: Timestamps</a> (Internet <abbr>RFC</abbr> 3339)
|
||||||
specifies an <abbr>ISO</abbr> 8601 profile for use in new Internet protocols.
|
specifies an <abbr>ISO</abbr> 8601 profile for use in new Internet protocols.
|
||||||
An extension, <a href="https://datatracker.ietf.org/doc/html/rfc9557">Date
|
An extension, <a href="https://www.rfc-editor.org/rfc/rfc9557">Date
|
||||||
and Time on the Internet: Timestamps with Additional Information</a>
|
and Time on the Internet: Timestamps with Additional Information</a>
|
||||||
(Internet <abbr>RFC</abbr> 9557) extends this profile
|
(Internet <abbr>RFC</abbr> 9557) extends this profile
|
||||||
to let you specify the <code><abbr>tzdb</abbr></code> timezone of a timestamp
|
to let you specify the <code><abbr>tzdb</abbr></code> timezone of a timestamp
|
||||||
|
|||||||
+35
-35
@@ -11,7 +11,7 @@ The timezone information files used by
|
|||||||
.Xr tzset 3
|
.Xr tzset 3
|
||||||
are found under
|
are found under
|
||||||
.Pa /usr/share/zoneinfo .
|
.Pa /usr/share/zoneinfo .
|
||||||
These files use the format described in Internet RFC 8536.
|
These files use the format described in Internet RFC 9636.
|
||||||
Each file is a sequence of 8-bit bytes.
|
Each file is a sequence of 8-bit bytes.
|
||||||
In a file, a binary integer is represented by a sequence of one or
|
In a file, a binary integer is represented by a sequence of one or
|
||||||
more bytes in network order (bigendian, or high-order byte first),
|
more bytes in network order (bigendian, or high-order byte first),
|
||||||
@@ -107,7 +107,7 @@ and
|
|||||||
serves as an index into the array of time zone abbreviation bytes
|
serves as an index into the array of time zone abbreviation bytes
|
||||||
that follow the
|
that follow the
|
||||||
.Vt ttinfo
|
.Vt ttinfo
|
||||||
entries in the file; if the designated string is "\*-00", the
|
entries in the file; if the designated string is "\-00", the
|
||||||
.Vt ttinfo
|
.Vt ttinfo
|
||||||
entry is a placeholder indicating that local time is unspecified.
|
entry is a placeholder indicating that local time is unspecified.
|
||||||
The
|
The
|
||||||
@@ -128,7 +128,7 @@ The byte strings can overlap if one is a suffix of the other.
|
|||||||
The encoding of these strings is not specified.
|
The encoding of these strings is not specified.
|
||||||
.It Va tzh_leapcnt
|
.It Va tzh_leapcnt
|
||||||
pairs of four-byte values, written in network byte order;
|
pairs of four-byte values, written in network byte order;
|
||||||
the first value of each pair gives the nonnegative time
|
the first value of each pair gives the non-negative time
|
||||||
(as returned by
|
(as returned by
|
||||||
.Xr time 3 )
|
.Xr time 3 )
|
||||||
at which a leap second occurs or at which the leap second table expires;
|
at which a leap second occurs or at which the leap second table expires;
|
||||||
@@ -141,7 +141,7 @@ Each pair denotes one leap second, either positive or negative,
|
|||||||
except that if the last pair has the same correction as the previous one,
|
except that if the last pair has the same correction as the previous one,
|
||||||
the last pair denotes the leap second table's expiration time.
|
the last pair denotes the leap second table's expiration time.
|
||||||
Each leap second is at the end of a UTC calendar month.
|
Each leap second is at the end of a UTC calendar month.
|
||||||
The first leap second has a nonnegative occurrence time,
|
The first leap second has a non-negative occurrence time,
|
||||||
and is a positive leap second if and only if its correction is positive;
|
and is a positive leap second if and only if its correction is positive;
|
||||||
the correction for each leap second after the first differs
|
the correction for each leap second after the first differs
|
||||||
from the previous leap second by either 1 for a positive leap second,
|
from the previous leap second by either 1 for a positive leap second,
|
||||||
@@ -168,7 +168,7 @@ The standard/wall and UT/local indicators were designed for
|
|||||||
transforming a TZif file's transition times into transitions appropriate
|
transforming a TZif file's transition times into transitions appropriate
|
||||||
for another time zone specified via
|
for another time zone specified via
|
||||||
a proleptic TZ string that lacks rules.
|
a proleptic TZ string that lacks rules.
|
||||||
For example, when TZ="EET\*-2EEST" and there is no TZif file "EET\*-2EEST",
|
For example, when TZ="EET\-2EEST" and there is no TZif file "EET\-2EEST",
|
||||||
the idea was to adapt the transition times from a TZif file with the
|
the idea was to adapt the transition times from a TZif file with the
|
||||||
well-known name "posixrules" that is present only for this purpose and
|
well-known name "posixrules" that is present only for this purpose and
|
||||||
is a copy of the file "Europe/Brussels", a file with a different UT offset.
|
is a copy of the file "Europe/Brussels", a file with a different UT offset.
|
||||||
@@ -177,7 +177,7 @@ the default rules are installation-dependent, and no implementation
|
|||||||
is known to support this feature for timestamps past 2037,
|
is known to support this feature for timestamps past 2037,
|
||||||
so users desiring (say) Greek time should instead specify
|
so users desiring (say) Greek time should instead specify
|
||||||
TZ="Europe/Athens" for better historical coverage, falling back on
|
TZ="Europe/Athens" for better historical coverage, falling back on
|
||||||
TZ="EET\*-2EEST,M3.5.0/3,M10.5.0/4" if POSIX conformance is required
|
TZ="EET\-2EEST,M3.5.0/3,M10.5.0/4" if POSIX conformance is required
|
||||||
and older timestamps need not be handled accurately.
|
and older timestamps need not be handled accurately.
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
@@ -203,7 +203,7 @@ after the last transition time stored in the file
|
|||||||
or for all instants if the file has no transitions.
|
or for all instants if the file has no transitions.
|
||||||
The TZ string is empty (i.e., nothing between the newlines)
|
The TZ string is empty (i.e., nothing between the newlines)
|
||||||
if there is no proleptic representation for such instants.
|
if there is no proleptic representation for such instants.
|
||||||
If nonempty, the TZ string must agree with the local time
|
If non-empty, the TZ string must agree with the local time
|
||||||
type after the last transition time if present in the eight-byte data;
|
type after the last transition time if present in the eight-byte data;
|
||||||
for example, given the string
|
for example, given the string
|
||||||
.Dq "WET0WEST,M3.5.0/1,M10.5.0"
|
.Dq "WET0WEST,M3.5.0/1,M10.5.0"
|
||||||
@@ -218,7 +218,7 @@ the earliest transition time.
|
|||||||
For version-3-format timezone files, a TZ string (see
|
For version-3-format timezone files, a TZ string (see
|
||||||
.Xr newtzset 3 )
|
.Xr newtzset 3 )
|
||||||
may use the following POSIX.1-2024 extensions to POSIX.1-2017:
|
may use the following POSIX.1-2024 extensions to POSIX.1-2017:
|
||||||
First, as in TZ="<\*-02>2<\*-01>,M3.5.0/\*-1,M10.5.0/0",
|
First, as in TZ="<\-02>2<\-01>,M3.5.0/\-1,M10.5.0/0",
|
||||||
the hours part of its transition times may be signed and range from
|
the hours part of its transition times may be signed and range from
|
||||||
\-167 through 167 instead of being limited to unsigned values
|
\-167 through 167 instead of being limited to unsigned values
|
||||||
from 0 through 24.
|
from 0 through 24.
|
||||||
@@ -275,7 +275,7 @@ time did not exist (possibly with an error indication).
|
|||||||
Time zone designations should consist of at least three (3)
|
Time zone designations should consist of at least three (3)
|
||||||
and no more than six (6) ASCII characters from the set of
|
and no more than six (6) ASCII characters from the set of
|
||||||
alphanumerics,
|
alphanumerics,
|
||||||
.Dq "\*-" ,
|
.Dq "\-" ,
|
||||||
and
|
and
|
||||||
.Dq "+" .
|
.Dq "+" .
|
||||||
This is for compatibility with POSIX requirements for
|
This is for compatibility with POSIX requirements for
|
||||||
@@ -300,16 +300,16 @@ through 60 instead of the usual 59; the UTC offset is unaffected.
|
|||||||
This section documents common problems in reading or writing TZif files.
|
This section documents common problems in reading or writing TZif files.
|
||||||
Most of these are problems in generating TZif files for use by
|
Most of these are problems in generating TZif files for use by
|
||||||
older readers.
|
older readers.
|
||||||
The goals of this section are:
|
The goals of this section are to help:
|
||||||
.Bl -bullet
|
.Bl -bullet
|
||||||
.It
|
.It
|
||||||
to help TZif writers output files that avoid common
|
TZif writers output files that avoid common
|
||||||
pitfalls in older or buggy TZif readers,
|
pitfalls in older or buggy TZif readers,
|
||||||
.It
|
.It
|
||||||
to help TZif readers avoid common pitfalls when reading
|
TZif readers avoid common pitfalls when reading
|
||||||
files generated by future TZif writers, and
|
files generated by future TZif writers, and
|
||||||
.It
|
.It
|
||||||
to help any future specification authors see what sort of
|
any future specification authors see what sort of
|
||||||
problems arise when the TZif format is changed.
|
problems arise when the TZif format is changed.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
@@ -320,9 +320,9 @@ reader was designed for.
|
|||||||
When complete compatibility was not achieved, an attempt was
|
When complete compatibility was not achieved, an attempt was
|
||||||
made to limit glitches to rarely used timestamps and allow
|
made to limit glitches to rarely used timestamps and allow
|
||||||
simple partial workarounds in writers designed to generate
|
simple partial workarounds in writers designed to generate
|
||||||
new-version data useful even for older-version readers.
|
newer-version data useful even for older-version readers.
|
||||||
This section attempts to document these compatibility issues and
|
This section attempts to document these compatibility issues and
|
||||||
workarounds, as well as to document other common bugs in
|
workarounds as well as documenting other common bugs in
|
||||||
readers.
|
readers.
|
||||||
.Pp
|
.Pp
|
||||||
Interoperability problems with TZif include the following:
|
Interoperability problems with TZif include the following:
|
||||||
@@ -355,15 +355,15 @@ for two time zones east, e.g.,
|
|||||||
for a time zone with a never-used standard time (XXX, \-03)
|
for a time zone with a never-used standard time (XXX, \-03)
|
||||||
and negative daylight saving time (EDT, \-04) all year.
|
and negative daylight saving time (EDT, \-04) all year.
|
||||||
Alternatively,
|
Alternatively,
|
||||||
as a partial workaround a writer can substitute standard time
|
as a partial workaround, a writer can substitute standard time
|
||||||
for the next time zone east \(en e.g.,
|
for the next time zone east \(en e.g.,
|
||||||
.Dq "AST4"
|
.Dq "AST4"
|
||||||
for permanent
|
for permanent
|
||||||
Atlantic Standard Time (\-04).
|
Atlantic Standard Time (\-04).
|
||||||
.It
|
.It
|
||||||
Some readers designed for version 2 or 3, and that require strict
|
Some readers designed for version 2 or 3 and that require strict
|
||||||
conformance to RFC 8536, reject version 4 files whose leap second
|
conformance to RFC 9636 reject version 4 files whose leap second
|
||||||
tables are truncated at the start or that end in expiration times.
|
tables are truncated at the start or end in expiration times.
|
||||||
.It
|
.It
|
||||||
Some readers ignore the footer, and instead predict future
|
Some readers ignore the footer, and instead predict future
|
||||||
timestamps from the time type of the last transition.
|
timestamps from the time type of the last transition.
|
||||||
@@ -378,7 +378,7 @@ and even for current timestamps it can fail for settings like
|
|||||||
TZ="Africa/Casablanca". This corresponds to a TZif file
|
TZ="Africa/Casablanca". This corresponds to a TZif file
|
||||||
containing explicit transitions through the year 2087,
|
containing explicit transitions through the year 2087,
|
||||||
followed by a footer containing the TZ string
|
followed by a footer containing the TZ string
|
||||||
.Dq <+01>\*-1 ,
|
.Dq <+01>\-1 ,
|
||||||
which should be used only for timestamps after the last
|
which should be used only for timestamps after the last
|
||||||
explicit transition.
|
explicit transition.
|
||||||
.It
|
.It
|
||||||
@@ -389,7 +389,7 @@ As a partial workaround, a writer can output a dummy (no-op)
|
|||||||
first transition at an early time.
|
first transition at an early time.
|
||||||
.It
|
.It
|
||||||
Some readers mishandle timestamps before the first
|
Some readers mishandle timestamps before the first
|
||||||
transition that has a timestamp not less than \-2**31.
|
transition that has a timestamp that is not less than \-2**31.
|
||||||
Readers that support only 32-bit timestamps are likely to be
|
Readers that support only 32-bit timestamps are likely to be
|
||||||
more prone to this problem, for example, when they process
|
more prone to this problem, for example, when they process
|
||||||
64-bit transitions only some of which are representable in 32
|
64-bit transitions only some of which are representable in 32
|
||||||
@@ -401,7 +401,7 @@ Some readers mishandle a transition if its timestamp has
|
|||||||
the minimum possible signed 64-bit value.
|
the minimum possible signed 64-bit value.
|
||||||
Timestamps less than \-2**59 are not recommended.
|
Timestamps less than \-2**59 are not recommended.
|
||||||
.It
|
.It
|
||||||
Some readers mishandle TZ strings that
|
Some readers mishandle proleptic TZ strings that
|
||||||
contain
|
contain
|
||||||
.Dq "<"
|
.Dq "<"
|
||||||
or
|
or
|
||||||
@@ -418,9 +418,9 @@ non-ASCII characters.
|
|||||||
These characters are not recommended.
|
These characters are not recommended.
|
||||||
.It
|
.It
|
||||||
Some readers may mishandle time zone abbreviations that
|
Some readers may mishandle time zone abbreviations that
|
||||||
contain fewer than 3 or more than 6 characters, or that
|
contain fewer than 3 or more than 6 characters or that
|
||||||
contain ASCII characters other than alphanumerics,
|
contain ASCII characters other than alphanumerics,
|
||||||
.Dq "\*-",
|
.Dq "\-",
|
||||||
and
|
and
|
||||||
.Dq "+".
|
.Dq "+".
|
||||||
These abbreviations are not recommended.
|
These abbreviations are not recommended.
|
||||||
@@ -430,7 +430,7 @@ daylight-saving time UT offsets that are less than the UT
|
|||||||
offsets for the corresponding standard time.
|
offsets for the corresponding standard time.
|
||||||
These readers do not support locations like Ireland, which
|
These readers do not support locations like Ireland, which
|
||||||
uses the equivalent of the TZ string
|
uses the equivalent of the TZ string
|
||||||
.Dq "IST\*-1GMT0,M10.5.0,M3.5.0/1",
|
.Dq "IST\-1GMT0,M10.5.0,M3.5.0/1",
|
||||||
observing standard time
|
observing standard time
|
||||||
(IST, +01) in summer and daylight saving time (GMT, +00) in winter.
|
(IST, +01) in summer and daylight saving time (GMT, +00) in winter.
|
||||||
As a partial workaround, a writer can output data for the
|
As a partial workaround, a writer can output data for the
|
||||||
@@ -443,7 +443,7 @@ abbreviations correctly.
|
|||||||
.It
|
.It
|
||||||
Some readers generate ambiguous timestamps for positive leap seconds
|
Some readers generate ambiguous timestamps for positive leap seconds
|
||||||
that occur when the UTC offset is not a multiple of 60 seconds.
|
that occur when the UTC offset is not a multiple of 60 seconds.
|
||||||
For example, in a timezone with UTC offset +01:23:45 and with
|
For example, with UTC offset +01:23:45 and
|
||||||
a positive leap second 78796801 (1972-06-30 23:59:60 UTC), some readers will
|
a positive leap second 78796801 (1972-06-30 23:59:60 UTC), some readers will
|
||||||
map both 78796800 and 78796801 to 01:23:45 local time the next day
|
map both 78796800 and 78796801 to 01:23:45 local time the next day
|
||||||
instead of mapping the latter to 01:23:46, and they will map 78796815 to
|
instead of mapping the latter to 01:23:46, and they will map 78796815 to
|
||||||
@@ -462,15 +462,15 @@ Developers of distributed applications should keep this
|
|||||||
in mind if they need to deal with pre-1970 data.
|
in mind if they need to deal with pre-1970 data.
|
||||||
.It
|
.It
|
||||||
Some readers mishandle timestamps before the first
|
Some readers mishandle timestamps before the first
|
||||||
transition that has a nonnegative timestamp.
|
transition that has a non-negative timestamp.
|
||||||
Readers that do not support negative timestamps are likely to
|
Readers that do not support negative timestamps are likely to
|
||||||
be more prone to this problem.
|
be more prone to this problem.
|
||||||
.It
|
.It
|
||||||
Some readers mishandle time zone abbreviations like
|
Some readers mishandle time zone abbreviations like
|
||||||
.Dq "\*-08"
|
.Dq "\-08"
|
||||||
that contain
|
that contain
|
||||||
.Dq "+" ,
|
.Dq "+",
|
||||||
.Dq "\*-" ,
|
.Dq "\-",
|
||||||
or digits.
|
or digits.
|
||||||
.It
|
.It
|
||||||
Some readers mishandle UT offsets that are out of the
|
Some readers mishandle UT offsets that are out of the
|
||||||
@@ -479,7 +479,7 @@ support locations like Kiritimati that are outside this
|
|||||||
range.
|
range.
|
||||||
.It
|
.It
|
||||||
Some readers mishandle UT offsets in the range [\-3599, \-1]
|
Some readers mishandle UT offsets in the range [\-3599, \-1]
|
||||||
seconds from UT, because they integer-divide the offset by
|
seconds from UT because they integer-divide the offset by
|
||||||
3600 to get 0 and then display the hour part as
|
3600 to get 0 and then display the hour part as
|
||||||
.Dq "+00" .
|
.Dq "+00" .
|
||||||
.It
|
.It
|
||||||
@@ -498,8 +498,8 @@ of one hour, or of 15 minutes, or of 1 minute.
|
|||||||
.%A P. Eggert
|
.%A P. Eggert
|
||||||
.%A K. Murchison
|
.%A K. Murchison
|
||||||
.%T "The Time Zone Information Format (TZif)"
|
.%T "The Time Zone Information Format (TZif)"
|
||||||
.%R RFC 8536
|
.%R RFC 9636
|
||||||
.%D February 2019
|
.%D October 2024
|
||||||
.%U https://datatracker.ietf.org/doc/html/rfc8536
|
.%U https://datatracker.ietf.org/doc/html/rfc9636
|
||||||
.%U https://doi.org/10.17487/RFC8536
|
.%U https://doi.org/10.17487/RFC9636
|
||||||
.Re
|
.Re
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#endif /* !defined TZDEFRULES */
|
#endif /* !defined TZDEFRULES */
|
||||||
|
|
||||||
|
|
||||||
/* See Internet RFC 8536 for more details about the following format. */
|
/* See Internet RFC 9636 for more details about the following format. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Each file begins with. . .
|
** Each file begins with. . .
|
||||||
|
|||||||
+12
-14
@@ -4,8 +4,6 @@
|
|||||||
.SH NAME
|
.SH NAME
|
||||||
tzselect \- select a timezone
|
tzselect \- select a timezone
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.ie \n(.g .ds - \f(CR-\fP
|
|
||||||
.el .ds - \-
|
|
||||||
.ds d " degrees
|
.ds d " degrees
|
||||||
.ds m " minutes
|
.ds m " minutes
|
||||||
.ds s " seconds
|
.ds s " seconds
|
||||||
@@ -20,15 +18,15 @@ tzselect \- select a timezone
|
|||||||
.\}
|
.\}
|
||||||
.B tzselect
|
.B tzselect
|
||||||
[
|
[
|
||||||
.B \*-c
|
.B \-c
|
||||||
.I coord
|
.I coord
|
||||||
] [
|
] [
|
||||||
.B \*-n
|
.B \-n
|
||||||
.I limit
|
.I limit
|
||||||
] [
|
] [
|
||||||
.B \*-\*-help
|
.B \-\-help
|
||||||
] [
|
] [
|
||||||
.B \*-\*-version
|
.B \-\-version
|
||||||
]
|
]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
@@ -40,7 +38,7 @@ The output is suitable as a value for the TZ environment variable.
|
|||||||
All interaction with the user is done via standard input and standard error.
|
All interaction with the user is done via standard input and standard error.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.BI "\*-c " coord
|
.BI "\-c " coord
|
||||||
Instead of asking for continent and then country and then city,
|
Instead of asking for continent and then country and then city,
|
||||||
ask for selection from time zones whose largest cities
|
ask for selection from time zones whose largest cities
|
||||||
are closest to the location with geographical coordinates
|
are closest to the location with geographical coordinates
|
||||||
@@ -70,27 +68,27 @@ seconds, with any trailing fractions represent fractional minutes or
|
|||||||
.I SS
|
.I SS
|
||||||
is present) seconds. The decimal point is that of the current locale.
|
is present) seconds. The decimal point is that of the current locale.
|
||||||
For example, in the (default) C locale,
|
For example, in the (default) C locale,
|
||||||
.B "\*-c\ +40.689\*-074.045"
|
.B "\-c\ +40.689\-074.045"
|
||||||
specifies 40.689\*d\*_N, 74.045\*d\*_W,
|
specifies 40.689\*d\*_N, 74.045\*d\*_W,
|
||||||
.B "\*-c\ +4041.4\*-07402.7"
|
.B "\-c\ +4041.4\-07402.7"
|
||||||
specifies 40\*d\*_41.4\*m\*_N, 74\*d\*_2.7\*m\*_W, and
|
specifies 40\*d\*_41.4\*m\*_N, 74\*d\*_2.7\*m\*_W, and
|
||||||
.B "\*-c\ +404121\*-0740240"
|
.B "\-c\ +404121\-0740240"
|
||||||
specifies 40\*d\*_41\*m\*_21\*s\*_N, 74\*d\*_2\*m\*_40\*s\*_W.
|
specifies 40\*d\*_41\*m\*_21\*s\*_N, 74\*d\*_2\*m\*_40\*s\*_W.
|
||||||
If
|
If
|
||||||
.I coord
|
.I coord
|
||||||
is not one of the documented forms, the resulting behavior is unspecified.
|
is not one of the documented forms, the resulting behavior is unspecified.
|
||||||
.TP
|
.TP
|
||||||
.BI "\*-n " limit
|
.BI "\-n " limit
|
||||||
When
|
When
|
||||||
.B \*-c
|
.B \-c
|
||||||
is used, display the closest
|
is used, display the closest
|
||||||
.I limit
|
.I limit
|
||||||
locations (default 10).
|
locations (default 10).
|
||||||
.TP
|
.TP
|
||||||
.B "\*-\*-help"
|
.B "\-\-help"
|
||||||
Output help information and exit.
|
Output help information and exit.
|
||||||
.TP
|
.TP
|
||||||
.B "\*-\*-version"
|
.B "\-\-version"
|
||||||
Output version information and exit.
|
Output version information and exit.
|
||||||
.SH "ENVIRONMENT VARIABLES"
|
.SH "ENVIRONMENT VARIABLES"
|
||||||
.TP
|
.TP
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2024b
|
2025b
|
||||||
|
|||||||
+11
-3
@@ -28,6 +28,14 @@ The
|
|||||||
program prints the current time in each
|
program prints the current time in each
|
||||||
.Ar timezone
|
.Ar timezone
|
||||||
named on the command line.
|
named on the command line.
|
||||||
|
A
|
||||||
|
.Ar timezone
|
||||||
|
of
|
||||||
|
.Li -
|
||||||
|
is treated as if it were
|
||||||
|
.Pa /dev/stdin ;
|
||||||
|
this can be used to pipe TZif data into
|
||||||
|
.Nm .
|
||||||
.Pp
|
.Pp
|
||||||
The following options are available:
|
The following options are available:
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
@@ -106,7 +114,7 @@ then a line
|
|||||||
where
|
where
|
||||||
.Ar string
|
.Ar string
|
||||||
is a double-quoted string giving the timezone, a second line
|
is a double-quoted string giving the timezone, a second line
|
||||||
.Dq "\*- \*- \fIinterval\fP"
|
.Dq "\- \- \fIinterval\fP"
|
||||||
describing the time interval before the first transition if any, and
|
describing the time interval before the first transition if any, and
|
||||||
zero or more following lines
|
zero or more following lines
|
||||||
.Dq "\fIdate time interval\fP",
|
.Dq "\fIdate time interval\fP",
|
||||||
@@ -138,11 +146,11 @@ the seconds are omitted if they are zero, and
|
|||||||
the minutes are also omitted if they are also zero.
|
the minutes are also omitted if they are also zero.
|
||||||
Positive UT
|
Positive UT
|
||||||
offsets are east of Greenwich.
|
offsets are east of Greenwich.
|
||||||
The UT offset \*-00 denotes a UT
|
The UT offset \-00 denotes a UT
|
||||||
placeholder in areas where the actual offset is unspecified; by
|
placeholder in areas where the actual offset is unspecified; by
|
||||||
convention, this occurs when the UT offset is zero and the time zone
|
convention, this occurs when the UT offset is zero and the time zone
|
||||||
abbreviation begins with
|
abbreviation begins with
|
||||||
.Dq "-"
|
.Dq "\-"
|
||||||
or is
|
or is
|
||||||
.Dq "zzz".
|
.Dq "zzz".
|
||||||
.Pp
|
.Pp
|
||||||
|
|||||||
+26
-36
@@ -14,10 +14,6 @@
|
|||||||
#include "private.h"
|
#include "private.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifndef HAVE_SNPRINTF
|
|
||||||
# define HAVE_SNPRINTF (!PORT_TO_C89 || 199901 <= __STDC_VERSION__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_LOCALTIME_R
|
#ifndef HAVE_LOCALTIME_R
|
||||||
# define HAVE_LOCALTIME_R 1
|
# define HAVE_LOCALTIME_R 1
|
||||||
#endif
|
#endif
|
||||||
@@ -148,17 +144,6 @@ sumsize(ptrdiff_t a, ptrdiff_t b)
|
|||||||
size_overflow();
|
size_overflow();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the size of of the string STR, including its trailing NUL.
|
|
||||||
Report an error and exit if this would exceed INDEX_MAX which means
|
|
||||||
pointer subtraction wouldn't work. */
|
|
||||||
static ptrdiff_t
|
|
||||||
xstrsize(char const *str)
|
|
||||||
{
|
|
||||||
size_t len = strlen(str);
|
|
||||||
if (len < INDEX_MAX)
|
|
||||||
return len + 1;
|
|
||||||
size_overflow();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return a pointer to a newly allocated buffer of size SIZE, exiting
|
/* Return a pointer to a newly allocated buffer of size SIZE, exiting
|
||||||
on failure. SIZE should be positive. */
|
on failure. SIZE should be positive. */
|
||||||
@@ -266,7 +251,7 @@ tzalloc(char const *val)
|
|||||||
static ptrdiff_t fakeenv0size;
|
static ptrdiff_t fakeenv0size;
|
||||||
void *freeable = NULL;
|
void *freeable = NULL;
|
||||||
char **env = fakeenv, **initial_environ;
|
char **env = fakeenv, **initial_environ;
|
||||||
ptrdiff_t valsize = xstrsize(val);
|
ptrdiff_t valsize = strlen(val) + 1;
|
||||||
if (fakeenv0size < valsize) {
|
if (fakeenv0size < valsize) {
|
||||||
char **e = environ, **to;
|
char **e = environ, **to;
|
||||||
ptrdiff_t initial_nenvptrs = 1; /* Counting the trailing NULL pointer. */
|
ptrdiff_t initial_nenvptrs = 1; /* Counting the trailing NULL pointer. */
|
||||||
@@ -427,7 +412,7 @@ saveabbr(char **buf, ptrdiff_t *bufalloc, struct tm const *tmp)
|
|||||||
if (HAVE_LOCALTIME_RZ)
|
if (HAVE_LOCALTIME_RZ)
|
||||||
return ab;
|
return ab;
|
||||||
else {
|
else {
|
||||||
ptrdiff_t absize = xstrsize(ab);
|
ptrdiff_t absize = strlen(ab) + 1;
|
||||||
if (*bufalloc < absize) {
|
if (*bufalloc < absize) {
|
||||||
free(*buf);
|
free(*buf);
|
||||||
|
|
||||||
@@ -489,6 +474,7 @@ main(int argc, char *argv[])
|
|||||||
register time_t cuthitime;
|
register time_t cuthitime;
|
||||||
time_t now;
|
time_t now;
|
||||||
bool iflag = false;
|
bool iflag = false;
|
||||||
|
size_t arglenmax = 0;
|
||||||
|
|
||||||
cutlotime = absolute_min_time;
|
cutlotime = absolute_min_time;
|
||||||
cuthitime = absolute_max_time;
|
cuthitime = absolute_max_time;
|
||||||
@@ -588,15 +574,21 @@ main(int argc, char *argv[])
|
|||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
now |= !now;
|
now |= !now;
|
||||||
}
|
}
|
||||||
longest = 0;
|
|
||||||
for (i = optind; i < argc; i++) {
|
for (i = optind; i < argc; i++) {
|
||||||
size_t arglen = strlen(argv[i]);
|
size_t arglen = strlen(argv[i]);
|
||||||
if (longest < arglen)
|
if (arglenmax < arglen)
|
||||||
longest = min(arglen, INT_MAX);
|
arglenmax = arglen;
|
||||||
}
|
}
|
||||||
|
if (!HAVE_SETENV && INDEX_MAX <= arglenmax)
|
||||||
|
size_overflow();
|
||||||
|
longest = min(arglenmax, INT_MAX - 2);
|
||||||
|
|
||||||
for (i = optind; i < argc; ++i) {
|
for (i = optind; i < argc; ++i) {
|
||||||
timezone_t tz = tzalloc(argv[i]);
|
/* Treat "-" as standard input on platforms with /dev/stdin.
|
||||||
|
It's not worth the bother of supporting "-" on other
|
||||||
|
platforms, as that would need temp files. */
|
||||||
|
timezone_t tz = tzalloc(strcmp(argv[i], "-") == 0
|
||||||
|
? "/dev/stdin" : argv[i]);
|
||||||
char const *ab;
|
char const *ab;
|
||||||
time_t t;
|
time_t t;
|
||||||
struct tm tm, newtm;
|
struct tm tm, newtm;
|
||||||
@@ -697,7 +689,7 @@ yeartot(intmax_t y)
|
|||||||
return absolute_max_time;
|
return absolute_max_time;
|
||||||
seconds = diff400 * SECSPER400YEARS;
|
seconds = diff400 * SECSPER400YEARS;
|
||||||
years = diff400 * 400;
|
years = diff400 * 400;
|
||||||
} else {
|
} else {
|
||||||
seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
|
seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
|
||||||
years = 1;
|
years = 1;
|
||||||
}
|
}
|
||||||
@@ -928,13 +920,10 @@ showextrema(timezone_t tz, char *zone, time_t lo, struct tm *lotmp, time_t hi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_SNPRINTF
|
/* On pre-C99 platforms, a snprintf substitute good enough for us. */
|
||||||
# define my_snprintf snprintf
|
#if !HAVE_SNPRINTF
|
||||||
#else
|
|
||||||
# include <stdarg.h>
|
# include <stdarg.h>
|
||||||
|
ATTRIBUTE_FORMAT((printf, 3, 4)) static int
|
||||||
/* A substitute for snprintf that is good enough for zdump. */
|
|
||||||
static int
|
|
||||||
my_snprintf(char *s, size_t size, char const *format, ...)
|
my_snprintf(char *s, size_t size, char const *format, ...)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
@@ -962,6 +951,7 @@ my_snprintf(char *s, size_t size, char const *format, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
# define snprintf my_snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Store into BUF, of size SIZE, a formatted local time taken from *TM.
|
/* Store into BUF, of size SIZE, a formatted local time taken from *TM.
|
||||||
@@ -976,10 +966,10 @@ format_local_time(char *buf, ptrdiff_t size, struct tm const *tm)
|
|||||||
{
|
{
|
||||||
int ss = tm->tm_sec, mm = tm->tm_min, hh = tm->tm_hour;
|
int ss = tm->tm_sec, mm = tm->tm_min, hh = tm->tm_hour;
|
||||||
return (ss
|
return (ss
|
||||||
? my_snprintf(buf, size, "%02d:%02d:%02d", hh, mm, ss)
|
? snprintf(buf, size, "%02d:%02d:%02d", hh, mm, ss)
|
||||||
: mm
|
: mm
|
||||||
? my_snprintf(buf, size, "%02d:%02d", hh, mm)
|
? snprintf(buf, size, "%02d:%02d", hh, mm)
|
||||||
: my_snprintf(buf, size, "%02d", hh));
|
: snprintf(buf, size, "%02d", hh));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store into BUF, of size SIZE, a formatted UT offset for the
|
/* Store into BUF, of size SIZE, a formatted UT offset for the
|
||||||
@@ -1014,10 +1004,10 @@ format_utc_offset(char *buf, ptrdiff_t size, struct tm const *tm, time_t t)
|
|||||||
mm = off / 60 % 60;
|
mm = off / 60 % 60;
|
||||||
hh = off / 60 / 60;
|
hh = off / 60 / 60;
|
||||||
return (ss || 100 <= hh
|
return (ss || 100 <= hh
|
||||||
? my_snprintf(buf, size, "%c%02ld%02d%02d", sign, hh, mm, ss)
|
? snprintf(buf, size, "%c%02ld%02d%02d", sign, hh, mm, ss)
|
||||||
: mm
|
: mm
|
||||||
? my_snprintf(buf, size, "%c%02ld%02d", sign, hh, mm)
|
? snprintf(buf, size, "%c%02ld%02d", sign, hh, mm)
|
||||||
: my_snprintf(buf, size, "%c%02ld", sign, hh));
|
: snprintf(buf, size, "%c%02ld", sign, hh));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store into BUF (of size SIZE) a quoted string representation of P.
|
/* Store into BUF (of size SIZE) a quoted string representation of P.
|
||||||
@@ -1120,7 +1110,7 @@ istrftime(char *buf, ptrdiff_t size, char const *time_fmt,
|
|||||||
for (abp = ab; is_alpha(*abp); abp++)
|
for (abp = ab; is_alpha(*abp); abp++)
|
||||||
continue;
|
continue;
|
||||||
len = (!*abp && *ab
|
len = (!*abp && *ab
|
||||||
? my_snprintf(b, s, "%s", ab)
|
? snprintf(b, s, "%s", ab)
|
||||||
: format_quoted_string(b, s, ab));
|
: format_quoted_string(b, s, ab));
|
||||||
if (s <= len)
|
if (s <= len)
|
||||||
return false;
|
return false;
|
||||||
@@ -1128,7 +1118,7 @@ istrftime(char *buf, ptrdiff_t size, char const *time_fmt,
|
|||||||
}
|
}
|
||||||
formatted_len
|
formatted_len
|
||||||
= (tm->tm_isdst
|
= (tm->tm_isdst
|
||||||
? my_snprintf(b, s, &"\t\t%d"[show_abbr], tm->tm_isdst)
|
? snprintf(b, s, &"\t\t%d"[show_abbr], tm->tm_isdst)
|
||||||
: 0);
|
: 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
+22
-5
@@ -112,13 +112,13 @@ Link \fItimezone\fP posixrules
|
|||||||
If
|
If
|
||||||
.Ar timezone
|
.Ar timezone
|
||||||
is
|
is
|
||||||
.Dq "\*-"
|
.Dq "\-"
|
||||||
(the default), any already-existing link is removed.
|
(the default), any already-existing link is removed.
|
||||||
.Pp
|
.Pp
|
||||||
Unless
|
Unless
|
||||||
.Ar timezone
|
.Ar timezone
|
||||||
is
|
is
|
||||||
.Dq "\*-" ,
|
.Dq "\-" ,
|
||||||
this option is obsolete and poorly supported.
|
this option is obsolete and poorly supported.
|
||||||
Among other things it should not be used for timestamps after the year 2037,
|
Among other things it should not be used for timestamps after the year 2037,
|
||||||
and it should not be combined with
|
and it should not be combined with
|
||||||
@@ -148,6 +148,10 @@ omits data intended for negative timestamps (i.e., before the Epoch), and
|
|||||||
.Fl r @0/@2147483648
|
.Fl r @0/@2147483648
|
||||||
outputs data intended only for nonnegative timestamps that fit into
|
outputs data intended only for nonnegative timestamps that fit into
|
||||||
31-bit signed integers.
|
31-bit signed integers.
|
||||||
|
On platforms with GNU
|
||||||
|
.Nm date ,
|
||||||
|
.Dq "zic \-r @$(date +%s)"
|
||||||
|
omits data intended for past timestamps.
|
||||||
Although this option typically reduces the output file's size,
|
Although this option typically reduces the output file's size,
|
||||||
the size can increase due to the need to represent the timestamp range
|
the size can increase due to the need to represent the timestamp range
|
||||||
boundaries, particularly if
|
boundaries, particularly if
|
||||||
@@ -366,7 +370,15 @@ separate script to further restrict in which
|
|||||||
of years the rule would apply.
|
of years the rule would apply.
|
||||||
.It IN
|
.It IN
|
||||||
Names the month in which the rule takes effect.
|
Names the month in which the rule takes effect.
|
||||||
Month names may be abbreviated.
|
Month names may be abbreviated as mentioned previously;
|
||||||
|
for example, January can appear as
|
||||||
|
.Dq January ,
|
||||||
|
.Dq JANU
|
||||||
|
or
|
||||||
|
.Dq Ja ,
|
||||||
|
but not as
|
||||||
|
.Dq j
|
||||||
|
which would be ambiguous with both June and July.
|
||||||
.It ON
|
.It ON
|
||||||
Gives the day on which the rule takes effect.
|
Gives the day on which the rule takes effect.
|
||||||
Recognized forms include:
|
Recognized forms include:
|
||||||
@@ -389,7 +401,12 @@ or a weekday name preceded by
|
|||||||
.Dq "last"
|
.Dq "last"
|
||||||
(e.g.,
|
(e.g.,
|
||||||
.Ql "lastSunday" )
|
.Ql "lastSunday" )
|
||||||
may be abbreviated or spelled out in full.
|
may be abbreviated as mentioned previously,
|
||||||
|
e.g.,
|
||||||
|
.Dq Su
|
||||||
|
for Sunday and
|
||||||
|
.Dq lastsa
|
||||||
|
for the last Saturday.
|
||||||
There must be no white space characters within the
|
There must be no white space characters within the
|
||||||
.Ar ON
|
.Ar ON
|
||||||
field.
|
field.
|
||||||
@@ -540,7 +557,7 @@ field,
|
|||||||
giving the amount of time to be added to local standard time
|
giving the amount of time to be added to local standard time
|
||||||
and whether the resulting time is standard or daylight saving.
|
and whether the resulting time is standard or daylight saving.
|
||||||
Standard time applies if this field is
|
Standard time applies if this field is
|
||||||
.Ql \*-
|
.Ql \-
|
||||||
or for timestamps occurring before any rule takes effect.
|
or for timestamps occurring before any rule takes effect.
|
||||||
When an amount of time is given, only the sum of standard time and
|
When an amount of time is given, only the sum of standard time and
|
||||||
this amount matters.
|
this amount matters.
|
||||||
|
|||||||
+89
-53
@@ -526,19 +526,19 @@ memcheck(void *ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
emalloc(size_t size)
|
xmalloc(size_t size)
|
||||||
{
|
{
|
||||||
return memcheck(malloc(size));
|
return memcheck(malloc(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
erealloc(void *ptr, size_t size)
|
xrealloc(void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
return memcheck(realloc(ptr, size));
|
return memcheck(realloc(ptr, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
estrdup(char const *str)
|
xstrdup(char const *str)
|
||||||
{
|
{
|
||||||
return memcheck(strdup(str));
|
return memcheck(strdup(str));
|
||||||
}
|
}
|
||||||
@@ -567,7 +567,7 @@ growalloc(void *ptr, ptrdiff_t itemsize, ptrdiff_t nitems,
|
|||||||
{
|
{
|
||||||
return (nitems < *nitems_alloc
|
return (nitems < *nitems_alloc
|
||||||
? ptr
|
? ptr
|
||||||
: erealloc(ptr, grow_nitems_alloc(nitems_alloc, itemsize)));
|
: xrealloc(ptr, grow_nitems_alloc(nitems_alloc, itemsize)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -654,6 +654,8 @@ close_file(FILE *stream, char const *dir, char const *name,
|
|||||||
char const *e = (ferror(stream) ? _("I/O error")
|
char const *e = (ferror(stream) ? _("I/O error")
|
||||||
: fclose(stream) != 0 ? strerror(errno) : NULL);
|
: fclose(stream) != 0 ? strerror(errno) : NULL);
|
||||||
if (e) {
|
if (e) {
|
||||||
|
if (name && *name == '/')
|
||||||
|
dir = NULL;
|
||||||
fprintf(stderr, "%s: %s%s%s%s%s\n", progname,
|
fprintf(stderr, "%s: %s%s%s%s%s\n", progname,
|
||||||
dir ? dir : "", dir ? "/" : "",
|
dir ? dir : "", dir ? "/" : "",
|
||||||
name ? name : "", name ? ": " : "",
|
name ? name : "", name ? ": " : "",
|
||||||
@@ -961,6 +963,9 @@ static mode_t mflag = (S_IRUSR | S_IRGRP | S_IROTH
|
|||||||
| S_IWUSR);
|
| S_IWUSR);
|
||||||
static const char * tzdefault;
|
static const char * tzdefault;
|
||||||
|
|
||||||
|
/* True if DIRECTORY ends in '/'. */
|
||||||
|
static bool directory_ends_in_slash;
|
||||||
|
|
||||||
/* -1 if the TZif output file should be slim, 0 if default, 1 if the
|
/* -1 if the TZif output file should be slim, 0 if default, 1 if the
|
||||||
output should be fat for backward compatibility. ZIC_BLOAT_DEFAULT
|
output should be fat for backward compatibility. ZIC_BLOAT_DEFAULT
|
||||||
determines the default. */
|
determines the default. */
|
||||||
@@ -1166,6 +1171,7 @@ _("invalid file mode"));
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
associate();
|
associate();
|
||||||
change_directory(directory);
|
change_directory(directory);
|
||||||
|
directory_ends_in_slash = directory[strlen(directory) - 1] == '/';
|
||||||
catch_signals();
|
catch_signals();
|
||||||
for (i = 0; i < nzones; i = j) {
|
for (i = 0; i < nzones; i = j) {
|
||||||
/*
|
/*
|
||||||
@@ -1353,7 +1359,7 @@ random_dirent(char const **name, char **namealloc)
|
|||||||
uint_fast64_t unfair_min = - ((UINTMAX_MAX % base__6 + 1) % base__6);
|
uint_fast64_t unfair_min = - ((UINTMAX_MAX % base__6 + 1) % base__6);
|
||||||
|
|
||||||
if (!dst) {
|
if (!dst) {
|
||||||
dst = emalloc(size_sum(dirlen, prefixlen + suffixlen + 1));
|
dst = xmalloc(size_sum(dirlen, prefixlen + suffixlen + 1));
|
||||||
memcpy(dst, src, dirlen);
|
memcpy(dst, src, dirlen);
|
||||||
memcpy(dst + dirlen, prefix, prefixlen);
|
memcpy(dst + dirlen, prefix, prefixlen);
|
||||||
dst[dirlen + prefixlen + suffixlen] = '\0';
|
dst[dirlen + prefixlen + suffixlen] = '\0';
|
||||||
@@ -1370,6 +1376,20 @@ random_dirent(char const **name, char **namealloc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For diagnostics the directory, and file name relative to that
|
||||||
|
directory, respectively. A diagnostic routine can name FILENAME by
|
||||||
|
outputting diagdir(FILENAME), then diagslash(FILENAME), then FILENAME. */
|
||||||
|
static char const *
|
||||||
|
diagdir(char const *filename)
|
||||||
|
{
|
||||||
|
return *filename == '/' ? "" : directory;
|
||||||
|
}
|
||||||
|
static char const *
|
||||||
|
diagslash(char const *filename)
|
||||||
|
{
|
||||||
|
return &"/"[*filename == '/' || directory_ends_in_slash];
|
||||||
|
}
|
||||||
|
|
||||||
/* Prepare to write to the file *OUTNAME, using *TEMPNAME to store the
|
/* Prepare to write to the file *OUTNAME, using *TEMPNAME to store the
|
||||||
name of the temporary file that will eventually be renamed to
|
name of the temporary file that will eventually be renamed to
|
||||||
*OUTNAME. Assign the temporary file's name to both *OUTNAME and
|
*OUTNAME. Assign the temporary file's name to both *OUTNAME and
|
||||||
@@ -1406,8 +1426,9 @@ open_outfile(char const **outname, char **tempname)
|
|||||||
} else if (fopen_errno == EEXIST)
|
} else if (fopen_errno == EEXIST)
|
||||||
random_dirent(outname, tempname);
|
random_dirent(outname, tempname);
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, _("%s: Can't create %s/%s: %s\n"),
|
fprintf(stderr, _("%s: Can't create %s%s%s: %s\n"),
|
||||||
progname, directory, *outname, strerror(fopen_errno));
|
progname, diagdir(*outname), diagslash(*outname), *outname,
|
||||||
|
strerror(fopen_errno));
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1424,9 +1445,10 @@ rename_dest(char *tempname, char const *name)
|
|||||||
if (tempname) {
|
if (tempname) {
|
||||||
if (rename(tempname, name) != 0) {
|
if (rename(tempname, name) != 0) {
|
||||||
int rename_errno = errno;
|
int rename_errno = errno;
|
||||||
(void)remove(tempname);
|
remove(tempname);
|
||||||
fprintf(stderr, _("%s: rename to %s/%s: %s\n"),
|
fprintf(stderr, _("%s: rename to %s%s%s: %s\n"),
|
||||||
progname, directory, name, strerror(rename_errno));
|
progname, diagdir(name), diagslash(name), name,
|
||||||
|
strerror(rename_errno));
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
free(tempname);
|
free(tempname);
|
||||||
@@ -1436,7 +1458,8 @@ rename_dest(char *tempname, char const *name)
|
|||||||
/* Create symlink contents suitable for symlinking TARGET to LINKNAME, as a
|
/* Create symlink contents suitable for symlinking TARGET to LINKNAME, as a
|
||||||
freshly allocated string. TARGET should be a relative file name, and
|
freshly allocated string. TARGET should be a relative file name, and
|
||||||
is relative to the global variable DIRECTORY. LINKNAME can be either
|
is relative to the global variable DIRECTORY. LINKNAME can be either
|
||||||
relative or absolute. */
|
relative or absolute. Return a null pointer if the symlink contents
|
||||||
|
was not computed because LINKNAME is absolute but DIRECTORY is not. */
|
||||||
static char *
|
static char *
|
||||||
relname(char const *target, char const *linkname)
|
relname(char const *target, char const *linkname)
|
||||||
{
|
{
|
||||||
@@ -1449,8 +1472,10 @@ relname(char const *target, char const *linkname)
|
|||||||
size_t len = strlen(directory);
|
size_t len = strlen(directory);
|
||||||
size_t lenslash = len + (len && directory[len - 1] != '/');
|
size_t lenslash = len + (len && directory[len - 1] != '/');
|
||||||
size_t targetsize = strlen(target) + 1;
|
size_t targetsize = strlen(target) + 1;
|
||||||
|
if (*directory != '/')
|
||||||
|
return NULL;
|
||||||
linksize = size_sum(lenslash, targetsize);
|
linksize = size_sum(lenslash, targetsize);
|
||||||
f = result = emalloc(linksize);
|
f = result = xmalloc(linksize);
|
||||||
memcpy(result, directory, len);
|
memcpy(result, directory, len);
|
||||||
result[len] = '/';
|
result[len] = '/';
|
||||||
memcpy(result + lenslash, target, targetsize);
|
memcpy(result + lenslash, target, targetsize);
|
||||||
@@ -1464,7 +1489,7 @@ relname(char const *target, char const *linkname)
|
|||||||
dotdotetcsize = size_sum(size_product(dotdots, 3), taillen + 1);
|
dotdotetcsize = size_sum(size_product(dotdots, 3), taillen + 1);
|
||||||
if (dotdotetcsize <= linksize) {
|
if (dotdotetcsize <= linksize) {
|
||||||
if (!result)
|
if (!result)
|
||||||
result = emalloc(dotdotetcsize);
|
result = xmalloc(dotdotetcsize);
|
||||||
for (i = 0; i < dotdots; i++)
|
for (i = 0; i < dotdots; i++)
|
||||||
memcpy(result + 3 * i, "../", 3);
|
memcpy(result + 3 * i, "../", 3);
|
||||||
memmove(result + 3 * dotdots, f + dir_len, taillen + 1);
|
memmove(result + 3 * dotdots, f + dir_len, taillen + 1);
|
||||||
@@ -1500,8 +1525,9 @@ dolink(char const *target, char const *linkname, bool staysymlink)
|
|||||||
return;
|
return;
|
||||||
else {
|
else {
|
||||||
char const *e = strerror(errno);
|
char const *e = strerror(errno);
|
||||||
fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"),
|
fprintf(stderr, _("%s: Can't remove %s%s%s: %s\n"),
|
||||||
progname, directory, linkname, e);
|
progname, diagdir(linkname), diagslash(linkname), linkname,
|
||||||
|
e);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1544,8 +1570,9 @@ dolink(char const *target, char const *linkname, bool staysymlink)
|
|||||||
mkdirs(linkname, true);
|
mkdirs(linkname, true);
|
||||||
linkdirs_made = true;
|
linkdirs_made = true;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, _("%s: Can't link %s/%s to %s/%s: %s\n"),
|
fprintf(stderr, _("%s: Can't link %s%s%s to %s%s%s: %s\n"),
|
||||||
progname, directory, target, directory, outname,
|
progname, diagdir(target), diagslash(target), target,
|
||||||
|
diagdir(outname), diagslash(outname), outname,
|
||||||
strerror(link_errno));
|
strerror(link_errno));
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@@ -1554,21 +1581,23 @@ dolink(char const *target, char const *linkname, bool staysymlink)
|
|||||||
bool absolute = *target == '/';
|
bool absolute = *target == '/';
|
||||||
char *linkalloc = absolute ? NULL : relname(target, linkname);
|
char *linkalloc = absolute ? NULL : relname(target, linkname);
|
||||||
char const *contents = absolute ? target : linkalloc;
|
char const *contents = absolute ? target : linkalloc;
|
||||||
int symlink_errno;
|
int symlink_errno = -1;
|
||||||
|
|
||||||
while (true) {
|
if (contents) {
|
||||||
if (symlink(contents, outname) == 0) {
|
while (true) {
|
||||||
symlink_errno = 0;
|
if (symlink(contents, outname) == 0) {
|
||||||
break;
|
symlink_errno = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
symlink_errno = errno;
|
||||||
|
if (symlink_errno == EEXIST)
|
||||||
|
random_dirent(&outname, &tempname);
|
||||||
|
else if (symlink_errno == ENOENT && !linkdirs_made) {
|
||||||
|
mkdirs(linkname, true);
|
||||||
|
linkdirs_made = true;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
symlink_errno = errno;
|
|
||||||
if (symlink_errno == EEXIST)
|
|
||||||
random_dirent(&outname, &tempname);
|
|
||||||
else if (symlink_errno == ENOENT && !linkdirs_made) {
|
|
||||||
mkdirs(linkname, true);
|
|
||||||
linkdirs_made = true;
|
|
||||||
} else
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
free(linkalloc);
|
free(linkalloc);
|
||||||
if (symlink_errno == 0) {
|
if (symlink_errno == 0) {
|
||||||
@@ -1581,8 +1610,8 @@ dolink(char const *target, char const *linkname, bool staysymlink)
|
|||||||
fp = fopen(target, "rb");
|
fp = fopen(target, "rb");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
char const *e = strerror(errno);
|
char const *e = strerror(errno);
|
||||||
fprintf(stderr, _("%s: Can't read %s/%s: %s\n"),
|
fprintf(stderr, _("%s: Can't read %s%s%s: %s\n"),
|
||||||
progname, directory, target, e);
|
progname, diagdir(target), diagslash(target), target, e);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
tp = open_outfile(&outname, &tempname);
|
tp = open_outfile(&outname, &tempname);
|
||||||
@@ -1593,6 +1622,8 @@ dolink(char const *target, char const *linkname, bool staysymlink)
|
|||||||
if (link_errno != ENOTSUP)
|
if (link_errno != ENOTSUP)
|
||||||
warning(_("copy used because hard link failed: %s"),
|
warning(_("copy used because hard link failed: %s"),
|
||||||
strerror(link_errno));
|
strerror(link_errno));
|
||||||
|
else if (symlink_errno < 0)
|
||||||
|
warning(_("copy used because symbolic link not obvious"));
|
||||||
else if (symlink_errno != ENOTSUP)
|
else if (symlink_errno != ENOTSUP)
|
||||||
warning(_("copy used because symbolic link failed: %s"),
|
warning(_("copy used because symbolic link failed: %s"),
|
||||||
strerror(symlink_errno));
|
strerror(symlink_errno));
|
||||||
@@ -1906,8 +1937,8 @@ inrule(char **fields, int nfields)
|
|||||||
fields[RF_COMMAND], fields[RF_MONTH], fields[RF_DAY],
|
fields[RF_COMMAND], fields[RF_MONTH], fields[RF_DAY],
|
||||||
fields[RF_TOD]))
|
fields[RF_TOD]))
|
||||||
return;
|
return;
|
||||||
r.r_name = estrdup(fields[RF_NAME]);
|
r.r_name = xstrdup(fields[RF_NAME]);
|
||||||
r.r_abbrvar = estrdup(fields[RF_ABBRVAR]);
|
r.r_abbrvar = xstrdup(fields[RF_ABBRVAR]);
|
||||||
if (max_abbrvar_len < strlen(r.r_abbrvar))
|
if (max_abbrvar_len < strlen(r.r_abbrvar))
|
||||||
max_abbrvar_len = strlen(r.r_abbrvar);
|
max_abbrvar_len = strlen(r.r_abbrvar);
|
||||||
rules = growalloc(rules, sizeof *rules, nrules, &nrules_alloc);
|
rules = growalloc(rules, sizeof *rules, nrules, &nrules_alloc);
|
||||||
@@ -1990,7 +2021,8 @@ inzsub(char **fields, int nfields, bool iscont)
|
|||||||
z.z_filenum = filenum;
|
z.z_filenum = filenum;
|
||||||
z.z_linenum = linenum;
|
z.z_linenum = linenum;
|
||||||
z.z_stdoff = gethms(fields[i_stdoff], _("invalid UT offset"));
|
z.z_stdoff = gethms(fields[i_stdoff], _("invalid UT offset"));
|
||||||
if ((cp = strchr(fields[i_format], '%')) != 0) {
|
cp = strchr(fields[i_format], '%');
|
||||||
|
if (cp) {
|
||||||
if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%')
|
if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%')
|
||||||
|| strchr(fields[i_format], '/')) {
|
|| strchr(fields[i_format], '/')) {
|
||||||
error(_("invalid abbreviation format"));
|
error(_("invalid abbreviation format"));
|
||||||
@@ -2028,9 +2060,9 @@ inzsub(char **fields, int nfields, bool iscont)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
z.z_name = iscont ? NULL : estrdup(fields[ZF_NAME]);
|
z.z_name = iscont ? NULL : xstrdup(fields[ZF_NAME]);
|
||||||
z.z_rule = estrdup(fields[i_rule]);
|
z.z_rule = xstrdup(fields[i_rule]);
|
||||||
z.z_format = cp1 = estrdup(fields[i_format]);
|
z.z_format = cp1 = xstrdup(fields[i_format]);
|
||||||
if (z.z_format_specifier == 'z') {
|
if (z.z_format_specifier == 'z') {
|
||||||
cp1[cp - fields[i_format]] = 's';
|
cp1[cp - fields[i_format]] = 's';
|
||||||
if (noise)
|
if (noise)
|
||||||
@@ -2173,8 +2205,8 @@ inlink(char **fields, int nfields)
|
|||||||
return;
|
return;
|
||||||
l.l_filenum = filenum;
|
l.l_filenum = filenum;
|
||||||
l.l_linenum = linenum;
|
l.l_linenum = linenum;
|
||||||
l.l_target = estrdup(fields[LF_TARGET]);
|
l.l_target = xstrdup(fields[LF_TARGET]);
|
||||||
l.l_linkname = estrdup(fields[LF_LINKNAME]);
|
l.l_linkname = xstrdup(fields[LF_LINKNAME]);
|
||||||
links = growalloc(links, sizeof *links, nlinks, &nlinks_alloc);
|
links = growalloc(links, sizeof *links, nlinks, &nlinks_alloc);
|
||||||
links[nlinks++] = l;
|
links[nlinks++] = l;
|
||||||
}
|
}
|
||||||
@@ -2197,7 +2229,7 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
|
|||||||
rp->r_month = lp->l_value;
|
rp->r_month = lp->l_value;
|
||||||
rp->r_todisstd = false;
|
rp->r_todisstd = false;
|
||||||
rp->r_todisut = false;
|
rp->r_todisut = false;
|
||||||
dp = estrdup(timep);
|
dp = xstrdup(timep);
|
||||||
if (*dp != '\0') {
|
if (*dp != '\0') {
|
||||||
ep = dp + strlen(dp) - 1;
|
ep = dp + strlen(dp) - 1;
|
||||||
switch (lowerit(*ep)) {
|
switch (lowerit(*ep)) {
|
||||||
@@ -2272,19 +2304,23 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
|
|||||||
** Sun<=20
|
** Sun<=20
|
||||||
** Sun>=7
|
** Sun>=7
|
||||||
*/
|
*/
|
||||||
dp = estrdup(dayp);
|
dp = xstrdup(dayp);
|
||||||
if ((lp = byword(dp, lasts)) != NULL) {
|
if ((lp = byword(dp, lasts)) != NULL) {
|
||||||
rp->r_dycode = DC_DOWLEQ;
|
rp->r_dycode = DC_DOWLEQ;
|
||||||
rp->r_wday = lp->l_value;
|
rp->r_wday = lp->l_value;
|
||||||
rp->r_dayofmonth = len_months[1][rp->r_month];
|
rp->r_dayofmonth = len_months[1][rp->r_month];
|
||||||
} else {
|
} else {
|
||||||
if ((ep = strchr(dp, '<')) != 0)
|
ep = strchr(dp, '<');
|
||||||
rp->r_dycode = DC_DOWLEQ;
|
if (ep)
|
||||||
else if ((ep = strchr(dp, '>')) != 0)
|
rp->r_dycode = DC_DOWLEQ;
|
||||||
rp->r_dycode = DC_DOWGEQ;
|
|
||||||
else {
|
else {
|
||||||
|
ep = strchr(dp, '>');
|
||||||
|
if (ep)
|
||||||
|
rp->r_dycode = DC_DOWGEQ;
|
||||||
|
else {
|
||||||
ep = dp;
|
ep = dp;
|
||||||
rp->r_dycode = DC_DOM;
|
rp->r_dycode = DC_DOM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (rp->r_dycode != DC_DOM) {
|
if (rp->r_dycode != DC_DOM) {
|
||||||
*ep++ = 0;
|
*ep++ = 0;
|
||||||
@@ -2427,7 +2463,7 @@ writezone(const char *const name, const char *const string, char version,
|
|||||||
/* Allocate the ATS and TYPES arrays via a single malloc,
|
/* Allocate the ATS and TYPES arrays via a single malloc,
|
||||||
as this is a bit faster. Do not malloc(0) if !timecnt,
|
as this is a bit faster. Do not malloc(0) if !timecnt,
|
||||||
as that might return NULL even on success. */
|
as that might return NULL even on success. */
|
||||||
zic_t *ats = emalloc(align_to(size_product(timecnt + !timecnt,
|
zic_t *ats = xmalloc(align_to(size_product(timecnt + !timecnt,
|
||||||
sizeof *ats + 1),
|
sizeof *ats + 1),
|
||||||
alignof(zic_t)));
|
alignof(zic_t)));
|
||||||
void *typesptr = ats + timecnt;
|
void *typesptr = ats + timecnt;
|
||||||
@@ -2802,7 +2838,7 @@ writezone(const char *const name, const char *const string, char version,
|
|||||||
if (thisleapexpiry) {
|
if (thisleapexpiry) {
|
||||||
/* Append a no-op leap correction indicating when the leap
|
/* Append a no-op leap correction indicating when the leap
|
||||||
second table expires. Although this does not conform to
|
second table expires. Although this does not conform to
|
||||||
Internet RFC 8536, most clients seem to accept this and
|
Internet RFC 9636, most clients seem to accept this and
|
||||||
the plan is to amend the RFC to allow this in version 4
|
the plan is to amend the RFC to allow this in version 4
|
||||||
TZif files. */
|
TZif files. */
|
||||||
puttzcodepass(leapexpires, fp, pass);
|
puttzcodepass(leapexpires, fp, pass);
|
||||||
@@ -3059,7 +3095,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
|
|||||||
|
|
||||||
result[0] = '\0';
|
result[0] = '\0';
|
||||||
|
|
||||||
/* Internet RFC 8536 section 5.1 says to use an empty TZ string if
|
/* Internet RFC 9636 section 6.1 says to use an empty TZ string if
|
||||||
future timestamps are truncated. */
|
future timestamps are truncated. */
|
||||||
if (hi_time < max_time)
|
if (hi_time < max_time)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -3187,9 +3223,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
|
|||||||
max_abbr_len = 2 + max_format_len + max_abbrvar_len;
|
max_abbr_len = 2 + max_format_len + max_abbrvar_len;
|
||||||
max_envvar_len = 2 * max_abbr_len + 5 * 9;
|
max_envvar_len = 2 * max_abbr_len + 5 * 9;
|
||||||
|
|
||||||
startbuf = emalloc(max_abbr_len + 1);
|
startbuf = xmalloc(max_abbr_len + 1);
|
||||||
ab = emalloc(max_abbr_len + 1);
|
ab = xmalloc(max_abbr_len + 1);
|
||||||
envvar = emalloc(max_envvar_len + 1);
|
envvar = xmalloc(max_envvar_len + 1);
|
||||||
INITIALIZE(untiltime);
|
INITIALIZE(untiltime);
|
||||||
INITIALIZE(starttime);
|
INITIALIZE(starttime);
|
||||||
/*
|
/*
|
||||||
@@ -3972,7 +4008,7 @@ mkdirs(char const *argname, bool ancestors)
|
|||||||
if (Dflag)
|
if (Dflag)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char *name = estrdup(argname);
|
char *name = xstrdup(argname);
|
||||||
char *cp = name;
|
char *cp = name;
|
||||||
|
|
||||||
/* On MS-Windows systems, do not worry about drive letters or
|
/* On MS-Windows systems, do not worry about drive letters or
|
||||||
|
|||||||
Reference in New Issue
Block a user