mirror of
https://git.freebsd.org/src.git
synced 2026-01-16 23:02:24 +00:00
Update tzcode to 2025b
MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D52103
This commit is contained in:
parent
2326db40a1
commit
967a49a21a
20 changed files with 1121 additions and 751 deletions
|
|
@ -137,7 +137,7 @@ TIME_T_ALTERNATIVES_TAIL = int_least32_t.ck uint_least32_t.ck \
|
|||
uint_least64_t.ck
|
||||
|
||||
# What kind of TZif data files to generate. (TZif is the binary time
|
||||
# zone data format that zic generates; see Internet RFC 8536.)
|
||||
# zone data format that zic generates; see Internet RFC 9636.)
|
||||
# If you want only POSIX time, with time values interpreted as
|
||||
# seconds since the epoch (not counting leap seconds), use
|
||||
# REDO= posix_only
|
||||
|
|
@ -255,6 +255,7 @@ LDLIBS=
|
|||
# -DHAVE_UNISTD_H=0 if <unistd.h> does not work*
|
||||
# -DHAVE_UTMPX_H=0 if <utmpx.h> does not work*
|
||||
# -Dlocale_t=XXX if your system uses XXX instead of locale_t
|
||||
# -DMKTIME_MIGHT_OVERFLOW if mktime might fail due to time_t overflow
|
||||
# -DPORT_TO_C89 if tzcode should also run on mostly-C89 platforms+
|
||||
# Typically it is better to use a later standard. For example,
|
||||
# with GCC 4.9.4 (2016), prefer '-std=gnu11' to '-DPORT_TO_C89'.
|
||||
|
|
@ -262,7 +263,7 @@ LDLIBS=
|
|||
# feature (integers at least 64 bits wide) and maybe more.
|
||||
# -DRESERVE_STD_EXT_IDS if your platform reserves standard identifiers
|
||||
# with external linkage, e.g., applications cannot define 'localtime'.
|
||||
# -Dssize_t=long on hosts like MS-Windows that lack ssize_t
|
||||
# -Dssize_t=int on hosts like MS-Windows that lack ssize_t
|
||||
# -DSUPPORT_C89=0 if the tzcode library should not support C89 callers
|
||||
# Although -DSUPPORT_C89=0 might work around latent bugs in callers,
|
||||
# it does not conform to POSIX.
|
||||
|
|
@ -285,7 +286,7 @@ LDLIBS=
|
|||
# This mishandles some past timestamps, as US DST rules have changed.
|
||||
# It also mishandles settings like TZ='EET-2EEST' for eastern Europe,
|
||||
# as Europe and US DST rules differ.
|
||||
# -DTZNAME_MAXIMUM=N to limit time zone abbreviations to N bytes (default 255)
|
||||
# -DTZNAME_MAXIMUM=N to limit time zone abbreviations to N bytes (default 254)
|
||||
# -DUNINIT_TRAP if reading uninitialized storage can cause problems
|
||||
# other than simply getting garbage data
|
||||
# -DUSE_LTZ=0 to build zdump with the system time zone library
|
||||
|
|
@ -319,7 +320,8 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 \
|
|||
$(GCC_INSTRUMENT) \
|
||||
-Wall -Wextra \
|
||||
-Walloc-size-larger-than=100000 -Warray-bounds=2 \
|
||||
-Wbad-function-cast -Wbidi-chars=any,ucn -Wcast-align=strict -Wdate-time \
|
||||
-Wbad-function-cast -Wbidi-chars=any,ucn -Wcast-align=strict -Wcast-qual \
|
||||
-Wdate-time \
|
||||
-Wdeclaration-after-statement -Wdouble-promotion \
|
||||
-Wduplicated-branches -Wduplicated-cond -Wflex-array-member-not-at-end \
|
||||
-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 \
|
||||
-Wtrampolines -Wundef -Wunused-macros -Wuse-after-free=3 \
|
||||
-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
|
||||
# (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= to$(TZS_YEAR).tzs
|
||||
TZS_NEW= to$(TZS_YEAR)new.tzs
|
||||
TZS_DEPS= $(YDATA) asctime.c localtime.c \
|
||||
private.h tzfile.h zdump.c zic.c
|
||||
TZS_DEPS= $(YDATA) localtime.c private.h \
|
||||
strftime.c tzfile.h zdump.c zic.c
|
||||
TZDATA_DIST = $(COMMON) $(DATA) $(MISC)
|
||||
# EIGHT_YARDS is just a yard short of the whole ENCHILADA.
|
||||
EIGHT_YARDS = $(TZDATA_DIST) $(DOCS) $(SOURCES) tzdata.zi
|
||||
|
|
@ -855,10 +857,10 @@ tzselect: tzselect.ksh version
|
|||
chmod +x $@.out
|
||||
mv $@.out $@
|
||||
|
||||
check: check_mild back.ck
|
||||
check: check_mild back.ck now.ck
|
||||
check_mild: check_web check_zishrink \
|
||||
character-set.ck white-space.ck links.ck mainguard.ck \
|
||||
name-lengths.ck now.ck slashed-abbrs.ck sorted.ck \
|
||||
name-lengths.ck slashed-abbrs.ck sorted.ck \
|
||||
tables.ck ziguard.ck tzs.ck
|
||||
|
||||
# True if UTF8_LOCALE does not work;
|
||||
|
|
@ -1103,7 +1105,7 @@ set-timestamps.out: $(EIGHT_YARDS)
|
|||
touch -md @1 test.out; then \
|
||||
rm -f test.out && \
|
||||
for file in $$files; do \
|
||||
if git diff --quiet $$file; then \
|
||||
if git diff --quiet HEAD $$file; then \
|
||||
time=$$(TZ=UTC0 git log -1 \
|
||||
--format='tformat:%cd' \
|
||||
--date='format:%Y-%m-%dT%H:%M:%SZ' \
|
||||
|
|
@ -1354,13 +1356,13 @@ long-long.ck unsigned.ck: $(VERSION_DEPS)
|
|||
zonenames: 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
|
||||
difftime.o: private.h
|
||||
localtime.o: private.h tzfile.h tzdir.h
|
||||
strftime.o: private.h tzfile.h
|
||||
zdump.o: version.h
|
||||
zic.o: private.h tzfile.h tzdir.h version.h
|
||||
localtime.o: private.h tzdir.h tzfile.h
|
||||
strftime.o: localtime.c private.h tzdir.h tzfile.h
|
||||
zdump.o: private.h version.h
|
||||
zic.o: private.h tzdir.h tzfile.h version.h
|
||||
|
||||
.PHONY: ALL INSTALL all
|
||||
.PHONY: check check_mild check_time_t_alternatives
|
||||
|
|
|
|||
|
|
@ -1,5 +1,108 @@
|
|||
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
|
||||
|
||||
Briefly:
|
||||
|
|
@ -116,7 +219,7 @@ Release 2024b - 2024-09-04 12:27:47 -0700
|
|||
Changes to commentary
|
||||
|
||||
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.)
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
as the spring-forward transition. Its clocks will therefore not
|
||||
spring forward as previously scheduled. The time zone change
|
||||
reverts to its common practice before 1981.
|
||||
reverts to its common practice before 1981. (Thanks to Jule Dabars.)
|
||||
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
/*
|
||||
** 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
|
||||
** whereas the output of asctime is supposed to be constant.
|
||||
*/
|
||||
|
|
@ -18,27 +19,6 @@
|
|||
#include "un-namespace.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 };
|
||||
/*
|
||||
** 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];
|
||||
|
||||
/* A similar buffer for ctime.
|
||||
C89 requires that they be the same buffer.
|
||||
This requirement was removed in C99, so support it only if requested,
|
||||
as support is more likely to lead to bugs in badly written programs. */
|
||||
#if SUPPORT_C89
|
||||
# define buf_ctime buf_asctime
|
||||
#else
|
||||
static char buf_ctime[sizeof buf_asctime];
|
||||
/* On pre-C99 platforms, a snprintf substitute good enough for us. */
|
||||
#if !HAVE_SNPRINTF
|
||||
# include <stdarg.h>
|
||||
ATTRIBUTE_FORMAT((printf, 3, 4)) static int
|
||||
my_snprintf(char *s, size_t size, char const *format, ...)
|
||||
{
|
||||
int n;
|
||||
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
|
||||
|
||||
/* 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",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
const char * wn;
|
||||
const char * mn;
|
||||
char year[INT_STRLEN_MAXIMUM(int) + 2];
|
||||
char result[sizeof buf_asctime];
|
||||
register const char * wn;
|
||||
register const char * mn;
|
||||
int year, mday, hour, min, sec;
|
||||
long long_TM_YEAR_BASE = TM_YEAR_BASE;
|
||||
size_t bufsize = (buf == buf_asctime
|
||||
? sizeof buf_asctime : STD_ASCTIME_BUF_SIZE);
|
||||
|
||||
if (timeptr == NULL) {
|
||||
strcpy(buf, "??? ??? ?? ??:??:?? ????\n");
|
||||
/* Set errno now, since strcpy might change it in
|
||||
POSIX.1-2017 and earlier. */
|
||||
errno = EINVAL;
|
||||
return strcpy(buf, "??? ??? ?? ??:??:?? ????\n");
|
||||
return buf;
|
||||
}
|
||||
if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
|
||||
wn = "???";
|
||||
|
|
@ -99,25 +94,41 @@ asctime_r(struct tm const *restrict timeptr, char *restrict buf)
|
|||
if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
|
||||
mn = "???";
|
||||
else mn = mon_name[timeptr->tm_mon];
|
||||
/*
|
||||
** Use strftime's %Y to generate the year, to avoid overflow problems
|
||||
** when computing timeptr->tm_year + TM_YEAR_BASE.
|
||||
** Assume that strftime is unaffected by other out-of-range members
|
||||
** (e.g., timeptr->tm_mday) when processing "%Y".
|
||||
*/
|
||||
strftime(year, sizeof year, "%Y", timeptr);
|
||||
/*
|
||||
** We avoid using snprintf since it's not available on all systems.
|
||||
*/
|
||||
sprintf(result,
|
||||
((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B),
|
||||
wn, mn,
|
||||
timeptr->tm_mday, timeptr->tm_hour,
|
||||
timeptr->tm_min, timeptr->tm_sec,
|
||||
year);
|
||||
if (strlen(result) < STD_ASCTIME_BUF_SIZE
|
||||
|| buf == buf_ctime || buf == buf_asctime)
|
||||
return strcpy(buf, result);
|
||||
|
||||
year = timeptr->tm_year;
|
||||
mday = timeptr->tm_mday;
|
||||
hour = timeptr->tm_hour;
|
||||
min = timeptr->tm_min;
|
||||
sec = timeptr->tm_sec;
|
||||
|
||||
/* Vintage programs are coded for years that are always four bytes long
|
||||
and may assume that the newline always lands in the same place.
|
||||
For years that are less than four bytes, pad the output with
|
||||
leading zeroes to get the newline in the traditional place.
|
||||
For years longer than four bytes, put extra spaces before the year
|
||||
so that vintage code trying to overwrite the newline
|
||||
won't overwrite a digit within a year and truncate the year,
|
||||
using the principle that no output is better than wrong output.
|
||||
This conforms to ISO C and POSIX standards, which say behavior
|
||||
is undefined when the year is less than 1000 or greater than 9999.
|
||||
|
||||
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 {
|
||||
errno = EOVERFLOW;
|
||||
return NULL;
|
||||
|
|
@ -142,5 +153,8 @@ ctime_r(const time_t *timep, char *buf)
|
|||
char *
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,15 +6,13 @@ date \- show and set date and time
|
|||
.SH SYNOPSIS
|
||||
.if n .nh
|
||||
.if n .na
|
||||
.ie \n(.g .ds - \f(CR-\fP
|
||||
.el .ds - \-
|
||||
.B date
|
||||
[
|
||||
.B \*-u
|
||||
.B \-u
|
||||
] [
|
||||
.B \*-c
|
||||
.B \-c
|
||||
] [
|
||||
.B \*-r
|
||||
.B \-r
|
||||
.I seconds
|
||||
] [
|
||||
.BI + format
|
||||
|
|
@ -35,7 +33,7 @@ command
|
|||
without arguments writes the date and time to the standard output in
|
||||
the form
|
||||
.ce 1
|
||||
Wed Mar 8 14:54:40 EST 1989
|
||||
Sat Mar 8 14:54:40 EST 2025
|
||||
.br
|
||||
with
|
||||
.B EST
|
||||
|
|
@ -49,99 +47,24 @@ If a command-line argument starts with a plus sign (\c
|
|||
.q "\fB+\fP" ),
|
||||
the rest of the argument is used as a
|
||||
.I format
|
||||
that controls what appears in the output.
|
||||
In the format, when a percent sign (\c
|
||||
.q "\fB%\fP"
|
||||
appears,
|
||||
it and the character after it are not output,
|
||||
but rather identify part of the date or time
|
||||
to be output in a particular way
|
||||
(or identify a special character to output):
|
||||
.nf
|
||||
.sp
|
||||
.if t .in +.5i
|
||||
.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.
|
||||
that is processed by
|
||||
.BR strftime (3)
|
||||
to determine what to output;
|
||||
a newline character is appended.
|
||||
For example, the shell command:
|
||||
.ce 1
|
||||
date +"%Y\-%m\-%d %H:%M:%S %z"
|
||||
.br
|
||||
outputs a line like
|
||||
.q "2025\-03\-08 14:54:40 \-0500"
|
||||
instead.
|
||||
.PP
|
||||
These options are available:
|
||||
.TP
|
||||
.BR \*-u " or " \*-c
|
||||
.BR \-u " or " \-c
|
||||
Use Universal Time when setting and showing the date and time.
|
||||
.TP
|
||||
.BI "\*-r " seconds
|
||||
.BI "\-r " seconds
|
||||
Output the date that corresponds to
|
||||
.I seconds
|
||||
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
|
||||
hexadecimal (leading 0x), preceded by an optional sign.
|
||||
.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
|
||||
.br
|
||||
/usr/lib/locale/\f2L\fP/LC_TIME description of time locale \f2L\fP
|
||||
.br
|
||||
/usr/share/zoneinfo timezone directory
|
||||
.br
|
||||
/usr/share/zoneinfo/posixrules default DST rules (obsolete)
|
||||
.br
|
||||
/usr/share/zoneinfo/GMT for UTC leap seconds
|
||||
.PP
|
||||
If /usr/share/zoneinfo/GMT is absent,
|
||||
UTC leap seconds are loaded from /usr/share/zoneinfo/GMT0 if present.
|
||||
/usr/share/zoneinfo/Etc/UTC for UTC leap seconds
|
||||
.SH SEE ALSO
|
||||
.BR strftime (3).
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -5,43 +5,34 @@
|
|||
asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.ie \n(.g .ds - \f(CR-\fP
|
||||
.el .ds - \-
|
||||
.B #include <time.h>
|
||||
.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);
|
||||
.PP
|
||||
.B "struct tm *localtime_r(time_t const *restrict clock,"
|
||||
.B " struct tm *restrict result);"
|
||||
.PP
|
||||
.B "struct tm *localtime_rz(timezone_t restrict zone,"
|
||||
.B " time_t const *restrict clock,"
|
||||
.B " struct tm *restrict result);"
|
||||
.PP
|
||||
.B struct tm *gmtime(time_t const *clock);
|
||||
.PP
|
||||
.B "struct tm *gmtime_r(time_t const *restrict clock,"
|
||||
.B " struct tm *restrict result);"
|
||||
.PP
|
||||
.B time_t mktime(struct tm *tm);
|
||||
.PP
|
||||
.B "time_t mktime_z(timezone_t restrict zone,"
|
||||
.B " struct tm *restrict tm);"
|
||||
.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
|
||||
.SH DESCRIPTION
|
||||
.ie '\(en'' .ds en \-
|
||||
|
|
@ -54,30 +45,26 @@ asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
|
|||
\\$3\*(lq\\$1\*(rq\\$2
|
||||
..
|
||||
The
|
||||
.B ctime
|
||||
function
|
||||
converts a long integer, pointed to by
|
||||
.B localtime
|
||||
and
|
||||
.B gmtime
|
||||
functions
|
||||
convert an integer, pointed to by
|
||||
.IR clock ,
|
||||
and returns 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.
|
||||
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.
|
||||
and
|
||||
return pointers to
|
||||
.q "tm"
|
||||
structures, described below.
|
||||
If the integer is out of range for conversion,
|
||||
these functions return a null pointer.
|
||||
The
|
||||
.B localtime
|
||||
function
|
||||
corrects for the time zone and any time zone adjustments
|
||||
(such as Daylight Saving Time in the United States).
|
||||
The
|
||||
.B gmtime
|
||||
function converts to Coordinated Universal Time.
|
||||
.PP
|
||||
The
|
||||
.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.
|
||||
.PP
|
||||
The
|
||||
.B ctime
|
||||
function is deprecated starting in C23.
|
||||
Callers can use
|
||||
.B localtime_r
|
||||
and
|
||||
.B strftime
|
||||
instead.
|
||||
.PP
|
||||
The
|
||||
.B localtime
|
||||
and
|
||||
.B gmtime
|
||||
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
|
||||
function
|
||||
converts the broken-down time,
|
||||
|
|
@ -204,6 +150,52 @@ returns the difference between two calendar times,
|
|||
expressed in seconds.
|
||||
.PP
|
||||
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 localtime_r ,
|
||||
.BR gmtime_r ,
|
||||
|
|
|
|||
|
|
@ -40,8 +40,6 @@
|
|||
strftime \- format date and time
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.ie \n(.g .ds - \f(CR-\fP
|
||||
.el .ds - \-
|
||||
.B #include <time.h>
|
||||
.PP
|
||||
.B "size_t strftime(char *restrict buf, size_t maxsize,"
|
||||
|
|
@ -93,7 +91,7 @@ If a bracketed member name is followed by
|
|||
.B strftime
|
||||
can use the named member even though POSIX.1-2024 does not list it;
|
||||
if the name is followed by
|
||||
.q \*- ,
|
||||
.q \- ,
|
||||
.B strftime
|
||||
ignores the member even though POSIX.1-2024 lists 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_gmtoff ,
|
||||
.IR tm_zone ,
|
||||
.IR tm_isdst \*-].
|
||||
.IR tm_isdst \-].
|
||||
.TP
|
||||
%D
|
||||
is equivalent to
|
||||
.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 ,
|
||||
.IR tm_mon ,
|
||||
.IR tm_mday ]
|
||||
|
|
@ -167,6 +168,8 @@ is equivalent to
|
|||
.TP
|
||||
%G
|
||||
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
|
||||
.c %V
|
||||
conversion specification.
|
||||
|
|
@ -176,11 +179,7 @@ conversion specification.
|
|||
.TP
|
||||
%g
|
||||
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.
|
||||
(Monday as the first day of a week).
|
||||
See also the
|
||||
.c %V
|
||||
conversion specification.
|
||||
Since it omits the century, it is ambiguous for dates.
|
||||
.RI [ tm_year ,
|
||||
.IR tm_yday ,
|
||||
.IR tm_wday ]
|
||||
|
|
@ -249,9 +248,22 @@ of leap seconds.
|
|||
is replaced by the number of seconds since the Epoch (see
|
||||
.BR ctime (3)).
|
||||
Although %s is reliable in this implementation,
|
||||
it can have glitches on other platforms (notably platforms lacking
|
||||
.IR tm_gmtoff ),
|
||||
so portable code should format a
|
||||
it can have glitches on other platforms
|
||||
(notably obsolescent platforms lacking
|
||||
.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
|
||||
value directly via something like
|
||||
.B sprintf
|
||||
|
|
@ -267,7 +279,7 @@ with "%s".
|
|||
.IR tm_min ,
|
||||
.IR tm_sec ,
|
||||
.IR tm_gmtoff +,
|
||||
.IR tm_isdst \*-].
|
||||
.IR tm_isdst \-].
|
||||
.TP
|
||||
%T
|
||||
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].
|
||||
.RI [ tm_wday ,
|
||||
.IR tm_yday ,
|
||||
.IR tm_year \*-]
|
||||
.IR tm_year \-]
|
||||
.TP
|
||||
%u
|
||||
is replaced by the weekday (Monday as the first day of the week)
|
||||
|
|
@ -318,31 +330,33 @@ as a decimal number [0,6].
|
|||
.TP
|
||||
%X
|
||||
is replaced by the locale's appropriate time representation.
|
||||
.RI [ tm_year \*-,
|
||||
.IR tm_yday \*-,
|
||||
.IR tm_mon \*-,
|
||||
.IR tm_mday \*-,
|
||||
.IR tm_wday \*-,
|
||||
.RI [ tm_year \-,
|
||||
.IR tm_yday \-,
|
||||
.IR tm_mon \-,
|
||||
.IR tm_mday \-,
|
||||
.IR tm_wday \-,
|
||||
.IR tm_hour ,
|
||||
.IR tm_min ,
|
||||
.IR tm_sec ,
|
||||
.IR tm_gmtoff ,
|
||||
.IR tm_zone ,
|
||||
.IR tm_isdst \*-].
|
||||
.IR tm_isdst \-].
|
||||
.TP
|
||||
%x
|
||||
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 ,
|
||||
.IR tm_yday ,
|
||||
.IR tm_mon ,
|
||||
.IR tm_mday ,
|
||||
.IR tm_wday ,
|
||||
.IR tm_hour \*-,
|
||||
.IR tm_min \*-,
|
||||
.IR tm_sec \*-,
|
||||
.IR tm_gmtoff \*-,
|
||||
.IR tm_zone \*-,
|
||||
.IR tm_isdst \*-].
|
||||
.IR tm_hour \-,
|
||||
.IR tm_min \-,
|
||||
.IR tm_sec \-,
|
||||
.IR tm_gmtoff \-,
|
||||
.IR tm_zone \-,
|
||||
.IR tm_isdst \-].
|
||||
.TP
|
||||
%Y
|
||||
is replaced by the year with century as a decimal number.
|
||||
|
|
@ -350,28 +364,29 @@ is replaced by the year with century as a decimal number.
|
|||
.TP
|
||||
%y
|
||||
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 ]
|
||||
.TP
|
||||
%Z
|
||||
is replaced by the time zone abbreviation,
|
||||
or by the empty string if this is not determinable.
|
||||
.RI [ tm_zone ,
|
||||
.IR tm_isdst \*-]
|
||||
.IR tm_isdst \-]
|
||||
.TP
|
||||
%z
|
||||
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,
|
||||
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
|
||||
but local time is indeterminate; by convention this is used for
|
||||
locations while uninhabited, and corresponds to a zero offset when the
|
||||
time zone abbreviation begins with
|
||||
.q "\*-" .
|
||||
.q "\-" .
|
||||
.RI [ tm_gmtoff ,
|
||||
.IR tm_zone +,
|
||||
.IR tm_isdst \*-]
|
||||
.IR tm_isdst \-]
|
||||
.TP
|
||||
%%
|
||||
is replaced by a single %.
|
||||
|
|
@ -418,15 +433,6 @@ This function fails if:
|
|||
The total number of resulting bytes, including the terminating
|
||||
NUL character, is more than
|
||||
.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
|
||||
.BR date (1),
|
||||
.BR getenv (3),
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
tzset \- initialize time conversion information
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.ie \n(.g .ds - \f(CR-\fP
|
||||
.el .ds - \-
|
||||
.B #include <time.h>
|
||||
.PP
|
||||
.BI "timezone_t tzalloc(char const *" TZ );
|
||||
|
|
@ -23,7 +21,7 @@ tzset \- initialize time conversion information
|
|||
.br
|
||||
.B extern int daylight;
|
||||
.PP
|
||||
.B cc ... \*-ltz
|
||||
.B cc ... \-ltz
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
.ie '\(en'' .ds en \-
|
||||
|
|
@ -110,7 +108,7 @@ except a leading colon
|
|||
digits, comma
|
||||
.RB ( , ),
|
||||
ASCII minus
|
||||
.RB ( \*- ),
|
||||
.RB ( \- ),
|
||||
ASCII plus
|
||||
.RB ( + ),
|
||||
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
|
||||
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
|
||||
.q "\*-" ,
|
||||
.q "\-" ,
|
||||
the time zone shall be east of the Prime Meridian; otherwise it shall be
|
||||
west (which may be indicated by an optional preceding
|
||||
.q "+" .
|
||||
|
|
@ -239,7 +237,7 @@ values that directly specify the timezone.
|
|||
stands for US Eastern Standard
|
||||
Time (EST), 5 hours behind UT, without daylight saving.
|
||||
.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
|
||||
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
|
||||
|
|
@ -249,34 +247,34 @@ and daylight saving time are
|
|||
and
|
||||
.q "+13".
|
||||
.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),
|
||||
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
|
||||
23), and falling back on October's last Sunday at 02:00.
|
||||
.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
|
||||
abbreviation
|
||||
.q "\*-03".
|
||||
.q "\-03".
|
||||
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
|
||||
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
|
||||
all year and the initial
|
||||
.B <\*-04>
|
||||
.B <\-04>
|
||||
is a placeholder.
|
||||
.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
|
||||
follow the EU rules of
|
||||
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
|
||||
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
|
||||
.q "\*-03"
|
||||
.q "\-03"
|
||||
and
|
||||
.q "\*-02".
|
||||
.q "\-02".
|
||||
.PP
|
||||
If
|
||||
.I TZ
|
||||
|
|
|
|||
|
|
@ -37,6 +37,38 @@
|
|||
# define SUPPORT_C89 1
|
||||
#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__
|
||||
# define __STDC_VERSION__ 0
|
||||
#endif
|
||||
|
|
@ -51,6 +83,7 @@
|
|||
#endif
|
||||
|
||||
#if __STDC_VERSION__ < 202311
|
||||
# undef static_assert
|
||||
# define static_assert(cond) extern int static_assert_check[(cond) ? 1 : -1]
|
||||
#endif
|
||||
|
||||
|
|
@ -87,11 +120,11 @@
|
|||
|
||||
#if !defined HAVE_GETTEXT && defined __has_include
|
||||
# if __has_include(<libintl.h>)
|
||||
# define HAVE_GETTEXT true
|
||||
# define HAVE_GETTEXT 1
|
||||
# endif
|
||||
#endif
|
||||
#ifndef HAVE_GETTEXT
|
||||
# define HAVE_GETTEXT false
|
||||
# define HAVE_GETTEXT 0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INCOMPATIBLE_CTIME_R
|
||||
|
|
@ -124,20 +157,20 @@
|
|||
|
||||
#if !defined HAVE_SYS_STAT_H && defined __has_include
|
||||
# if !__has_include(<sys/stat.h>)
|
||||
# define HAVE_SYS_STAT_H false
|
||||
# define HAVE_SYS_STAT_H 0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef HAVE_SYS_STAT_H
|
||||
# define HAVE_SYS_STAT_H true
|
||||
# define HAVE_SYS_STAT_H 1
|
||||
#endif
|
||||
|
||||
#if !defined HAVE_UNISTD_H && defined __has_include
|
||||
# if !__has_include(<unistd.h>)
|
||||
# define HAVE_UNISTD_H false
|
||||
# define HAVE_UNISTD_H 0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef HAVE_UNISTD_H
|
||||
# define HAVE_UNISTD_H true
|
||||
# define HAVE_UNISTD_H 1
|
||||
#endif
|
||||
|
||||
#ifndef NETBSD_INSPIRED
|
||||
|
|
@ -149,25 +182,6 @@
|
|||
# define ctime_r _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
|
||||
*/
|
||||
|
|
@ -260,6 +274,10 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
# define HAVE_SNPRINTF (!PORT_TO_C89 || 199901 <= __STDC_VERSION__)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRFTIME_L
|
||||
# if _POSIX_VERSION < 200809
|
||||
# define HAVE_STRFTIME_L 0
|
||||
|
|
@ -305,7 +323,7 @@
|
|||
** stdint.h, even with pre-C99 compilers.
|
||||
*/
|
||||
#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
|
||||
#ifndef HAVE_STDINT_H
|
||||
# define HAVE_STDINT_H \
|
||||
|
|
@ -375,11 +393,15 @@ typedef int int_fast32_t;
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef INT_LEAST32_MAX
|
||||
typedef int_fast32_t int_least32_t;
|
||||
#endif
|
||||
|
||||
#ifndef INTMAX_MAX
|
||||
# ifdef LLONG_MAX
|
||||
typedef long long intmax_t;
|
||||
# ifndef HAVE_STRTOLL
|
||||
# define HAVE_STRTOLL true
|
||||
# define HAVE_STRTOLL 1
|
||||
# endif
|
||||
# if HAVE_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. */
|
||||
#if !defined HAVE_STDCKDINT_H && defined __has_include
|
||||
# if __has_include(<stdckdint.h>)
|
||||
# define HAVE_STDCKDINT_H true
|
||||
# define HAVE_STDCKDINT_H 1
|
||||
# endif
|
||||
#endif
|
||||
#ifdef HAVE_STDCKDINT_H
|
||||
|
|
@ -554,13 +576,26 @@ typedef unsigned long uintmax_t;
|
|||
# define ATTRIBUTE_REPRODUCIBLE /* empty */
|
||||
#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.
|
||||
__attribute__((const)) is stricter than [[unsequenced]],
|
||||
so the latter is an adequate substitute in non-GCC C23 platforms.
|
||||
__attribute__((pure)) is stricter than [[reproducible]],
|
||||
so the latter is an adequate substitute in non-GCC C23 platforms. */
|
||||
#if __GNUC__ < 3
|
||||
# define ATTRIBUTE_CONST ATTRIBUTE_UNSEQUENCED
|
||||
# define ATTRIBUTE_FORMAT(spec) /* empty */
|
||||
# define ATTRIBUTE_PURE ATTRIBUTE_REPRODUCIBLE
|
||||
#else
|
||||
# define ATTRIBUTE_CONST __attribute__((const))
|
||||
# define ATTRIBUTE_FORMAT(spec) __attribute__((format spec))
|
||||
# define ATTRIBUTE_PURE __attribute__((pure))
|
||||
#endif
|
||||
|
|
@ -593,6 +628,12 @@ typedef unsigned long uintmax_t;
|
|||
# define RESERVE_STD_EXT_IDS 0
|
||||
#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)
|
||||
are reserved and are not already being renamed anyway, rename them
|
||||
as if compiling with '-Dtime_tz=time_t'. */
|
||||
|
|
@ -608,9 +649,9 @@ typedef unsigned long uintmax_t;
|
|||
** typical platforms.
|
||||
*/
|
||||
#if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
|
||||
# define TZ_TIME_T 1
|
||||
# define TZ_TIME_T true
|
||||
#else
|
||||
# define TZ_TIME_T 0
|
||||
# define TZ_TIME_T false
|
||||
#endif
|
||||
|
||||
#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 *ctime_r(time_t const *, char *);
|
||||
#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,
|
||||
struct tm const *restrict);
|
||||
# if HAVE_STRFTIME_L
|
||||
|
|
@ -729,9 +770,9 @@ void tzset(void);
|
|||
|| defined __GLIBC__ || defined __tm_zone /* musl */ \
|
||||
|| defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
|
||||
|| (defined __APPLE__ && defined __MACH__))
|
||||
# define HAVE_DECL_TIMEGM true
|
||||
# define HAVE_DECL_TIMEGM 1
|
||||
# else
|
||||
# define HAVE_DECL_TIMEGM false
|
||||
# define HAVE_DECL_TIMEGM 0
|
||||
# endif
|
||||
#endif
|
||||
#if !HAVE_DECL_TIMEGM && !defined timegm
|
||||
|
|
@ -771,7 +812,11 @@ extern long altzone;
|
|||
*/
|
||||
|
||||
#ifndef STD_INSPIRED
|
||||
# define STD_INSPIRED 0
|
||||
# ifdef __NetBSD__
|
||||
# define STD_INSPIRED 1
|
||||
# else
|
||||
# define STD_INSPIRED 0
|
||||
# endif
|
||||
#endif
|
||||
#if STD_INSPIRED
|
||||
# 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) \
|
||||
: (time_t) -1)
|
||||
enum { SIGNED_PADDING_CHECK_NEEDED
|
||||
= _Generic((time_t) 0,
|
||||
= _Generic((time_t) 0,
|
||||
signed char: false, short: false,
|
||||
int: false, long: false, long long: false,
|
||||
default: true) };
|
||||
|
|
@ -927,8 +972,8 @@ static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED
|
|||
# define UNINIT_TRAP 0
|
||||
#endif
|
||||
|
||||
/* localtime.c sometimes needs access to timeoff if it is not already public.
|
||||
tz_private_timeoff should be used only by localtime.c. */
|
||||
/* strftime.c sometimes needs access to timeoff if it is not already public.
|
||||
tz_private_timeoff should be used only by localtime.c and strftime.c. */
|
||||
#if (!defined EXTERN_TIMEOFF \
|
||||
&& defined TM_GMTOFF && (200809 < _POSIX_VERSION || ! UNINIT_TRAP))
|
||||
# ifndef timeoff
|
||||
|
|
|
|||
|
|
@ -39,8 +39,63 @@
|
|||
#include <locale.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
|
||||
# define DEPRECATE_TWO_DIGIT_YEARS false
|
||||
# define DEPRECATE_TWO_DIGIT_YEARS 0
|
||||
#endif
|
||||
|
||||
struct lc_time_T {
|
||||
|
|
@ -135,10 +190,6 @@ strftime(char *restrict s, size_t maxsize, char const *restrict format,
|
|||
|
||||
tzset();
|
||||
p = _fmt(format, t, s, s + maxsize, &warn);
|
||||
if (!p) {
|
||||
errno = EOVERFLOW;
|
||||
return 0;
|
||||
}
|
||||
if (DEPRECATE_TWO_DIGIT_YEARS
|
||||
&& warn != IN_NONE && getenv(YEAR_2000_NAME)) {
|
||||
fprintf(stderr, "\n");
|
||||
|
|
@ -170,7 +221,12 @@ _fmt(const char *format, const struct tm *t, char *pt,
|
|||
if (*format == '%') {
|
||||
label:
|
||||
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;
|
||||
break;
|
||||
case 'A':
|
||||
|
|
@ -327,16 +383,17 @@ label:
|
|||
tm.tm_mday = t->tm_mday;
|
||||
tm.tm_mon = t->tm_mon;
|
||||
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
|
||||
mkt = timeoff(&tm, t->TM_GMTOFF);
|
||||
#else
|
||||
tm.tm_isdst = t->tm_isdst;
|
||||
mkt = mktime(&tm);
|
||||
#endif
|
||||
/* If mktime fails, %s expands to the
|
||||
value of (time_t) -1 as a failure
|
||||
marker; this is better in practice
|
||||
than strftime failing. */
|
||||
if (TYPE_SIGNED(time_t)) {
|
||||
intmax_t n = mkt;
|
||||
sprintf(buf, "%"PRIdMAX, n);
|
||||
|
|
@ -590,12 +647,6 @@ label:
|
|||
warnp);
|
||||
continue;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
geographically close. For an example selection interface, see the
|
||||
<code>tzselect</code> program in the <code><abbr>tz</abbr></code> code.
|
||||
The <a href="https://cldr.unicode.org">Unicode Common Locale Data
|
||||
Repository</a> contains data that may be useful for other selection
|
||||
Unicode's <a href="https://cldr.unicode.org">Common Locale Data
|
||||
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
|
||||
locale-dependent strings like "Prague", "Praha", "Прага", and "布拉格".
|
||||
</p>
|
||||
|
|
@ -200,6 +201,8 @@ in decreasing order of importance:
|
|||
<li>
|
||||
A name must not be empty, or contain '<code>//</code>', or
|
||||
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>
|
||||
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.
|
||||
</li>
|
||||
<li>
|
||||
If all the clocks in a timezone have agreed since 1970,
|
||||
do not bother to include more than one timezone
|
||||
even if some of the clocks disagreed before 1970.
|
||||
If all clocks in a region have agreed since 1970,
|
||||
give them just one name 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.
|
||||
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>
|
||||
If boundaries between regions are fluid, such as during a war or
|
||||
|
|
@ -579,10 +590,10 @@ in decreasing order of importance:
|
|||
locations while uninhabited.
|
||||
The leading '<code>-</code>' is a flag that the <abbr>UT</abbr> offset is in
|
||||
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>.
|
||||
(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
|
||||
would violate the POSIX requirement
|
||||
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 file's format is <dfn><abbr>TZif</abbr></dfn>,
|
||||
a timezone information format that contains binary data; see
|
||||
<a href="https://datatracker.ietf.org/doc/html/8536">Internet
|
||||
<abbr>RFC</abbr> 8536</a>.
|
||||
<a href="https://www.rfc-editor.org/rfc/9636">Internet
|
||||
<abbr>RFC</abbr> 9636</a>.
|
||||
The daylight saving time rules to be used for a
|
||||
particular timezone are encoded in the
|
||||
<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
|
||||
its uses should be discouraged in favor of the abovementioned
|
||||
<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
|
||||
<code>mktime</code> to disambiguate timestamps near
|
||||
a <abbr>DST</abbr> transition when the clock jumps back on
|
||||
platforms lacking <code>tm_gmtoff</code>, this
|
||||
disambiguation does not work when standard time itself jumps back,
|
||||
which can occur when a location changes to a time zone with a
|
||||
disambiguation works only for proleptic <code>TZ</code> strings;
|
||||
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.
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -1223,8 +1237,8 @@ The vestigial <abbr>API</abbr>s are:
|
|||
Programs that in the past used the <code>timezone</code> function
|
||||
may now examine <code>localtime(&clock)->tm_zone</code>
|
||||
(if <code>TM_ZONE</code> is defined) or
|
||||
<code>tzname[localtime(&clock)->tm_isdst]</code>
|
||||
(if <code>HAVE_TZNAME</code> is nonzero) to learn the correct time
|
||||
use <code>strftime</code> with a <code>%Z</code> conversion specification
|
||||
to learn the correct time
|
||||
zone abbreviation to use.
|
||||
</li>
|
||||
<li>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
machine-readable binary files, one for each location. The binary files
|
||||
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>
|
||||
(Internet <abbr title="Request For Comments">RFC</abbr> 8536).
|
||||
(Internet <abbr title="Request For Comments">RFC</abbr> 9636).
|
||||
The code also lets
|
||||
you read a <abbr>TZif</abbr> file and interpret timestamps for that
|
||||
location.</p>
|
||||
|
|
@ -260,7 +260,7 @@ Studio Code</a>.
|
|||
</p>
|
||||
<p>
|
||||
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).
|
||||
More detail can be
|
||||
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
|
||||
<a href="https://datatracker.ietf.org/wg/tzdist/charter/">Time Zone Data
|
||||
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,
|
||||
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
|
||||
transferring time zone data by reference.
|
||||
<a href="https://devguide.calconnect.org/Time-Zones/TZDS/">TZDIST
|
||||
implementations</a> are available.
|
||||
The <a href="https://www.ietf.org/mailman/listinfo/tzdist-bis">tzdist-bis
|
||||
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
|
||||
(iCalendar)</a> (Internet <abbr>RFC</abbr> 5445)
|
||||
covers time zone
|
||||
data; see its VTIMEZONE calendar component.
|
||||
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
|
||||
<a href="https://www.w3.org/XML/"><abbr
|
||||
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)
|
||||
uses <a href="https://www.json.org/json-en.html"><abbr
|
||||
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>
|
||||
<dd>The Department of Transportation's <a
|
||||
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>
|
||||
<dd>The Oceanography, Hydrography, and Meteorology Service of the Uruguayan
|
||||
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>.
|
||||
After reviewing the scientific literature, the Sleep Research Society
|
||||
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>.
|
||||
<a href="https://jcsm.aasm.org/doi/10.5664/jcsm.10898">Permanent standard time
|
||||
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.
|
||||
doi:<a href="https://doi.org/10.1177/0748730419854197">10.1177/0748730419854197</a>.
|
||||
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>
|
||||
</ul>
|
||||
</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
|
||||
with special-purpose hardware.</li>
|
||||
<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>
|
||||
(Internet <abbr>RFC</abbr> 4833)
|
||||
specifies a <a
|
||||
|
|
@ -1105,7 +1120,7 @@ the abovementioned <abbr>NTP</abbr> implementations, <a
|
|||
href="https://github.com/google/unsmear">supports</a> conversion between
|
||||
<abbr>UTC</abbr> and smeared <abbr>POSIX</abbr> timestamps, and is used by major
|
||||
cloud service providers. However, according to
|
||||
<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>
|
||||
(Internet <abbr>RFC</abbr> 8633), leap smearing is not suitable for
|
||||
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>
|
||||
Schema: Datatypes – dateTime</a> specifies a format inspired by
|
||||
<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)
|
||||
specifies the time notation used in email and <a
|
||||
href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol"><abbr>HTTP</abbr></a>
|
||||
headers.</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)
|
||||
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>
|
||||
(Internet <abbr>RFC</abbr> 9557) extends this profile
|
||||
to let you specify the <code><abbr>tzdb</abbr></code> timezone of a timestamp
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ The timezone information files used by
|
|||
.Xr tzset 3
|
||||
are found under
|
||||
.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.
|
||||
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),
|
||||
|
|
@ -107,7 +107,7 @@ and
|
|||
serves as an index into the array of time zone abbreviation bytes
|
||||
that follow the
|
||||
.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
|
||||
entry is a placeholder indicating that local time is unspecified.
|
||||
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.
|
||||
.It Va tzh_leapcnt
|
||||
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
|
||||
.Xr time 3 )
|
||||
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,
|
||||
the last pair denotes the leap second table's expiration time.
|
||||
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;
|
||||
the correction for each leap second after the first differs
|
||||
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
|
||||
for another time zone specified via
|
||||
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
|
||||
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.
|
||||
|
|
@ -177,7 +177,7 @@ the default rules are installation-dependent, and no implementation
|
|||
is known to support this feature for timestamps past 2037,
|
||||
so users desiring (say) Greek time should instead specify
|
||||
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.
|
||||
.Pp
|
||||
The
|
||||
|
|
@ -203,7 +203,7 @@ after the last transition time stored in the file
|
|||
or for all instants if the file has no transitions.
|
||||
The TZ string is empty (i.e., nothing between the newlines)
|
||||
if there is no 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;
|
||||
for example, given the string
|
||||
.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
|
||||
.Xr newtzset 3 )
|
||||
may use the following POSIX.1-2024 extensions to POSIX.1-2017:
|
||||
First, as in TZ="<\*-02>2<\*-01>,M3.5.0/\*-1,M10.5.0/0",
|
||||
First, as in TZ="<\-02>2<\-01>,M3.5.0/\-1,M10.5.0/0",
|
||||
the hours part of its transition times may be signed and range from
|
||||
\-167 through 167 instead of being limited to unsigned values
|
||||
from 0 through 24.
|
||||
|
|
@ -275,7 +275,7 @@ time did not exist (possibly with an error indication).
|
|||
Time zone designations should consist of at least three (3)
|
||||
and no more than six (6) ASCII characters from the set of
|
||||
alphanumerics,
|
||||
.Dq "\*-" ,
|
||||
.Dq "\-" ,
|
||||
and
|
||||
.Dq "+" .
|
||||
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.
|
||||
Most of these are problems in generating TZif files for use by
|
||||
older readers.
|
||||
The goals of this section are:
|
||||
The goals of this section are to help:
|
||||
.Bl -bullet
|
||||
.It
|
||||
to help TZif writers output files that avoid common
|
||||
TZif writers output files that avoid common
|
||||
pitfalls in older or buggy TZif readers,
|
||||
.It
|
||||
to help TZif readers avoid common pitfalls when reading
|
||||
TZif readers avoid common pitfalls when reading
|
||||
files generated by future TZif writers, and
|
||||
.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.
|
||||
.El
|
||||
.Pp
|
||||
|
|
@ -320,9 +320,9 @@ reader was designed for.
|
|||
When complete compatibility was not achieved, an attempt was
|
||||
made to limit glitches to rarely used timestamps and allow
|
||||
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
|
||||
workarounds, as well as to document other common bugs in
|
||||
workarounds as well as documenting other common bugs in
|
||||
readers.
|
||||
.Pp
|
||||
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)
|
||||
and negative daylight saving time (EDT, \-04) all year.
|
||||
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.,
|
||||
.Dq "AST4"
|
||||
for permanent
|
||||
Atlantic Standard Time (\-04).
|
||||
.It
|
||||
Some readers designed for version 2 or 3, and that require strict
|
||||
conformance to RFC 8536, reject version 4 files whose leap second
|
||||
tables are truncated at the start or that end in expiration times.
|
||||
Some readers designed for version 2 or 3 and that require strict
|
||||
conformance to RFC 9636 reject version 4 files whose leap second
|
||||
tables are truncated at the start or end in expiration times.
|
||||
.It
|
||||
Some readers ignore the footer, and instead predict future
|
||||
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
|
||||
containing explicit transitions through the year 2087,
|
||||
followed by a footer containing the TZ string
|
||||
.Dq <+01>\*-1 ,
|
||||
.Dq <+01>\-1 ,
|
||||
which should be used only for timestamps after the last
|
||||
explicit transition.
|
||||
.It
|
||||
|
|
@ -389,7 +389,7 @@ As a partial workaround, a writer can output a dummy (no-op)
|
|||
first transition at an early time.
|
||||
.It
|
||||
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
|
||||
more prone to this problem, for example, when they process
|
||||
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.
|
||||
Timestamps less than \-2**59 are not recommended.
|
||||
.It
|
||||
Some readers mishandle TZ strings that
|
||||
Some readers mishandle proleptic TZ strings that
|
||||
contain
|
||||
.Dq "<"
|
||||
or
|
||||
|
|
@ -418,9 +418,9 @@ non-ASCII characters.
|
|||
These characters are not recommended.
|
||||
.It
|
||||
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,
|
||||
.Dq "\*-",
|
||||
.Dq "\-",
|
||||
and
|
||||
.Dq "+".
|
||||
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.
|
||||
These readers do not support locations like Ireland, which
|
||||
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
|
||||
(IST, +01) in summer and daylight saving time (GMT, +00) in winter.
|
||||
As a partial workaround, a writer can output data for the
|
||||
|
|
@ -443,7 +443,7 @@ abbreviations correctly.
|
|||
.It
|
||||
Some readers generate ambiguous timestamps for positive leap 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
|
||||
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
|
||||
|
|
@ -462,15 +462,15 @@ Developers of distributed applications should keep this
|
|||
in mind if they need to deal with pre-1970 data.
|
||||
.It
|
||||
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
|
||||
be more prone to this problem.
|
||||
.It
|
||||
Some readers mishandle time zone abbreviations like
|
||||
.Dq "\*-08"
|
||||
.Dq "\-08"
|
||||
that contain
|
||||
.Dq "+" ,
|
||||
.Dq "\*-" ,
|
||||
.Dq "+",
|
||||
.Dq "\-",
|
||||
or digits.
|
||||
.It
|
||||
Some readers mishandle UT offsets that are out of the
|
||||
|
|
@ -479,7 +479,7 @@ support locations like Kiritimati that are outside this
|
|||
range.
|
||||
.It
|
||||
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
|
||||
.Dq "+00" .
|
||||
.It
|
||||
|
|
@ -498,8 +498,8 @@ of one hour, or of 15 minutes, or of 1 minute.
|
|||
.%A P. Eggert
|
||||
.%A K. Murchison
|
||||
.%T "The Time Zone Information Format (TZif)"
|
||||
.%R RFC 8536
|
||||
.%D February 2019
|
||||
.%U https://datatracker.ietf.org/doc/html/rfc8536
|
||||
.%U https://doi.org/10.17487/RFC8536
|
||||
.%R RFC 9636
|
||||
.%D October 2024
|
||||
.%U https://datatracker.ietf.org/doc/html/rfc9636
|
||||
.%U https://doi.org/10.17487/RFC9636
|
||||
.Re
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#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. . .
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@
|
|||
.SH NAME
|
||||
tzselect \- select a timezone
|
||||
.SH SYNOPSIS
|
||||
.ie \n(.g .ds - \f(CR-\fP
|
||||
.el .ds - \-
|
||||
.ds d " degrees
|
||||
.ds m " minutes
|
||||
.ds s " seconds
|
||||
|
|
@ -20,15 +18,15 @@ tzselect \- select a timezone
|
|||
.\}
|
||||
.B tzselect
|
||||
[
|
||||
.B \*-c
|
||||
.B \-c
|
||||
.I coord
|
||||
] [
|
||||
.B \*-n
|
||||
.B \-n
|
||||
.I limit
|
||||
] [
|
||||
.B \*-\*-help
|
||||
.B \-\-help
|
||||
] [
|
||||
.B \*-\*-version
|
||||
.B \-\-version
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
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.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI "\*-c " coord
|
||||
.BI "\-c " coord
|
||||
Instead of asking for continent and then country and then city,
|
||||
ask for selection from time zones whose largest cities
|
||||
are closest to the location with geographical coordinates
|
||||
|
|
@ -70,27 +68,27 @@ seconds, with any trailing fractions represent fractional minutes or
|
|||
.I SS
|
||||
is present) seconds. The decimal point is that of the current 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,
|
||||
.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
|
||||
.B "\*-c\ +404121\*-0740240"
|
||||
.B "\-c\ +404121\-0740240"
|
||||
specifies 40\*d\*_41\*m\*_21\*s\*_N, 74\*d\*_2\*m\*_40\*s\*_W.
|
||||
If
|
||||
.I coord
|
||||
is not one of the documented forms, the resulting behavior is unspecified.
|
||||
.TP
|
||||
.BI "\*-n " limit
|
||||
.BI "\-n " limit
|
||||
When
|
||||
.B \*-c
|
||||
.B \-c
|
||||
is used, display the closest
|
||||
.I limit
|
||||
locations (default 10).
|
||||
.TP
|
||||
.B "\*-\*-help"
|
||||
.B "\-\-help"
|
||||
Output help information and exit.
|
||||
.TP
|
||||
.B "\*-\*-version"
|
||||
.B "\-\-version"
|
||||
Output version information and exit.
|
||||
.SH "ENVIRONMENT VARIABLES"
|
||||
.TP
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
2024b
|
||||
2025b
|
||||
|
|
|
|||
|
|
@ -28,6 +28,14 @@ The
|
|||
program prints the current time in each
|
||||
.Ar timezone
|
||||
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
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
|
|
@ -106,7 +114,7 @@ then a line
|
|||
where
|
||||
.Ar string
|
||||
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
|
||||
zero or more following lines
|
||||
.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.
|
||||
Positive UT
|
||||
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
|
||||
convention, this occurs when the UT offset is zero and the time zone
|
||||
abbreviation begins with
|
||||
.Dq "-"
|
||||
.Dq "\-"
|
||||
or is
|
||||
.Dq "zzz".
|
||||
.Pp
|
||||
|
|
|
|||
|
|
@ -14,10 +14,6 @@
|
|||
#include "private.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
# define HAVE_SNPRINTF (!PORT_TO_C89 || 199901 <= __STDC_VERSION__)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_LOCALTIME_R
|
||||
# define HAVE_LOCALTIME_R 1
|
||||
#endif
|
||||
|
|
@ -148,17 +144,6 @@ sumsize(ptrdiff_t a, ptrdiff_t b)
|
|||
size_overflow();
|
||||
}
|
||||
|
||||
/* Return the size of of the string STR, including its trailing NUL.
|
||||
Report an error and exit if this would exceed INDEX_MAX which means
|
||||
pointer subtraction wouldn't work. */
|
||||
static ptrdiff_t
|
||||
xstrsize(char const *str)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
if (len < INDEX_MAX)
|
||||
return len + 1;
|
||||
size_overflow();
|
||||
}
|
||||
|
||||
/* Return a pointer to a newly allocated buffer of size SIZE, exiting
|
||||
on failure. SIZE should be positive. */
|
||||
|
|
@ -266,7 +251,7 @@ tzalloc(char const *val)
|
|||
static ptrdiff_t fakeenv0size;
|
||||
void *freeable = NULL;
|
||||
char **env = fakeenv, **initial_environ;
|
||||
ptrdiff_t valsize = xstrsize(val);
|
||||
ptrdiff_t valsize = strlen(val) + 1;
|
||||
if (fakeenv0size < valsize) {
|
||||
char **e = environ, **to;
|
||||
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)
|
||||
return ab;
|
||||
else {
|
||||
ptrdiff_t absize = xstrsize(ab);
|
||||
ptrdiff_t absize = strlen(ab) + 1;
|
||||
if (*bufalloc < absize) {
|
||||
free(*buf);
|
||||
|
||||
|
|
@ -489,6 +474,7 @@ main(int argc, char *argv[])
|
|||
register time_t cuthitime;
|
||||
time_t now;
|
||||
bool iflag = false;
|
||||
size_t arglenmax = 0;
|
||||
|
||||
cutlotime = absolute_min_time;
|
||||
cuthitime = absolute_max_time;
|
||||
|
|
@ -588,15 +574,21 @@ main(int argc, char *argv[])
|
|||
now = time(NULL);
|
||||
now |= !now;
|
||||
}
|
||||
longest = 0;
|
||||
for (i = optind; i < argc; i++) {
|
||||
size_t arglen = strlen(argv[i]);
|
||||
if (longest < arglen)
|
||||
longest = min(arglen, INT_MAX);
|
||||
if (arglenmax < arglen)
|
||||
arglenmax = arglen;
|
||||
}
|
||||
if (!HAVE_SETENV && INDEX_MAX <= arglenmax)
|
||||
size_overflow();
|
||||
longest = min(arglenmax, INT_MAX - 2);
|
||||
|
||||
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;
|
||||
time_t t;
|
||||
struct tm tm, newtm;
|
||||
|
|
@ -697,7 +689,7 @@ yeartot(intmax_t y)
|
|||
return absolute_max_time;
|
||||
seconds = diff400 * SECSPER400YEARS;
|
||||
years = diff400 * 400;
|
||||
} else {
|
||||
} else {
|
||||
seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
|
||||
years = 1;
|
||||
}
|
||||
|
|
@ -928,13 +920,10 @@ showextrema(timezone_t tz, char *zone, time_t lo, struct tm *lotmp, time_t hi)
|
|||
}
|
||||
}
|
||||
|
||||
#if HAVE_SNPRINTF
|
||||
# define my_snprintf snprintf
|
||||
#else
|
||||
/* On pre-C99 platforms, a snprintf substitute good enough for us. */
|
||||
#if !HAVE_SNPRINTF
|
||||
# include <stdarg.h>
|
||||
|
||||
/* A substitute for snprintf that is good enough for zdump. */
|
||||
static int
|
||||
ATTRIBUTE_FORMAT((printf, 3, 4)) static int
|
||||
my_snprintf(char *s, size_t size, char const *format, ...)
|
||||
{
|
||||
int n;
|
||||
|
|
@ -962,6 +951,7 @@ my_snprintf(char *s, size_t size, char const *format, ...)
|
|||
va_end(args);
|
||||
return n;
|
||||
}
|
||||
# define snprintf my_snprintf
|
||||
#endif
|
||||
|
||||
/* 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;
|
||||
return (ss
|
||||
? my_snprintf(buf, size, "%02d:%02d:%02d", hh, mm, ss)
|
||||
? snprintf(buf, size, "%02d:%02d:%02d", hh, mm, ss)
|
||||
: mm
|
||||
? my_snprintf(buf, size, "%02d:%02d", hh, mm)
|
||||
: my_snprintf(buf, size, "%02d", hh));
|
||||
? snprintf(buf, size, "%02d:%02d", hh, mm)
|
||||
: snprintf(buf, size, "%02d", hh));
|
||||
}
|
||||
|
||||
/* 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;
|
||||
hh = off / 60 / 60;
|
||||
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
|
||||
? my_snprintf(buf, size, "%c%02ld%02d", sign, hh, mm)
|
||||
: my_snprintf(buf, size, "%c%02ld", sign, hh));
|
||||
? snprintf(buf, size, "%c%02ld%02d", sign, hh, mm)
|
||||
: snprintf(buf, size, "%c%02ld", sign, hh));
|
||||
}
|
||||
|
||||
/* 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++)
|
||||
continue;
|
||||
len = (!*abp && *ab
|
||||
? my_snprintf(b, s, "%s", ab)
|
||||
? snprintf(b, s, "%s", ab)
|
||||
: format_quoted_string(b, s, ab));
|
||||
if (s <= len)
|
||||
return false;
|
||||
|
|
@ -1128,7 +1118,7 @@ istrftime(char *buf, ptrdiff_t size, char const *time_fmt,
|
|||
}
|
||||
formatted_len
|
||||
= (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);
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -112,13 +112,13 @@ Link \fItimezone\fP posixrules
|
|||
If
|
||||
.Ar timezone
|
||||
is
|
||||
.Dq "\*-"
|
||||
.Dq "\-"
|
||||
(the default), any already-existing link is removed.
|
||||
.Pp
|
||||
Unless
|
||||
.Ar timezone
|
||||
is
|
||||
.Dq "\*-" ,
|
||||
.Dq "\-" ,
|
||||
this option is obsolete and poorly supported.
|
||||
Among other things it should not be used for timestamps after the year 2037,
|
||||
and it should not be combined with
|
||||
|
|
@ -148,6 +148,10 @@ omits data intended for negative timestamps (i.e., before the Epoch), and
|
|||
.Fl r @0/@2147483648
|
||||
outputs data intended only for nonnegative timestamps that fit into
|
||||
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,
|
||||
the size can increase due to the need to represent the timestamp range
|
||||
boundaries, particularly if
|
||||
|
|
@ -366,7 +370,15 @@ separate script to further restrict in which
|
|||
of years the rule would apply.
|
||||
.It IN
|
||||
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
|
||||
Gives the day on which the rule takes effect.
|
||||
Recognized forms include:
|
||||
|
|
@ -389,7 +401,12 @@ or a weekday name preceded by
|
|||
.Dq "last"
|
||||
(e.g.,
|
||||
.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
|
||||
.Ar ON
|
||||
field.
|
||||
|
|
@ -540,7 +557,7 @@ field,
|
|||
giving the amount of time to be added to local standard time
|
||||
and whether the resulting time is standard or daylight saving.
|
||||
Standard time applies if this field is
|
||||
.Ql \*-
|
||||
.Ql \-
|
||||
or for timestamps occurring before any rule takes effect.
|
||||
When an amount of time is given, only the sum of standard time and
|
||||
this amount matters.
|
||||
|
|
|
|||
|
|
@ -526,19 +526,19 @@ memcheck(void *ptr)
|
|||
}
|
||||
|
||||
static void *
|
||||
emalloc(size_t size)
|
||||
xmalloc(size_t size)
|
||||
{
|
||||
return memcheck(malloc(size));
|
||||
}
|
||||
|
||||
static void *
|
||||
erealloc(void *ptr, size_t size)
|
||||
xrealloc(void *ptr, size_t size)
|
||||
{
|
||||
return memcheck(realloc(ptr, size));
|
||||
}
|
||||
|
||||
static char *
|
||||
estrdup(char const *str)
|
||||
xstrdup(char const *str)
|
||||
{
|
||||
return memcheck(strdup(str));
|
||||
}
|
||||
|
|
@ -567,7 +567,7 @@ growalloc(void *ptr, ptrdiff_t itemsize, ptrdiff_t nitems,
|
|||
{
|
||||
return (nitems < *nitems_alloc
|
||||
? 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")
|
||||
: fclose(stream) != 0 ? strerror(errno) : NULL);
|
||||
if (e) {
|
||||
if (name && *name == '/')
|
||||
dir = NULL;
|
||||
fprintf(stderr, "%s: %s%s%s%s%s\n", progname,
|
||||
dir ? dir : "", dir ? "/" : "",
|
||||
name ? name : "", name ? ": " : "",
|
||||
|
|
@ -961,6 +963,9 @@ static mode_t mflag = (S_IRUSR | S_IRGRP | S_IROTH
|
|||
| S_IWUSR);
|
||||
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
|
||||
output should be fat for backward compatibility. ZIC_BLOAT_DEFAULT
|
||||
determines the default. */
|
||||
|
|
@ -1166,6 +1171,7 @@ _("invalid file mode"));
|
|||
return EXIT_FAILURE;
|
||||
associate();
|
||||
change_directory(directory);
|
||||
directory_ends_in_slash = directory[strlen(directory) - 1] == '/';
|
||||
catch_signals();
|
||||
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);
|
||||
|
||||
if (!dst) {
|
||||
dst = emalloc(size_sum(dirlen, prefixlen + suffixlen + 1));
|
||||
dst = xmalloc(size_sum(dirlen, prefixlen + suffixlen + 1));
|
||||
memcpy(dst, src, dirlen);
|
||||
memcpy(dst + dirlen, prefix, prefixlen);
|
||||
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
|
||||
name of the temporary file that will eventually be renamed to
|
||||
*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)
|
||||
random_dirent(outname, tempname);
|
||||
else {
|
||||
fprintf(stderr, _("%s: Can't create %s/%s: %s\n"),
|
||||
progname, directory, *outname, strerror(fopen_errno));
|
||||
fprintf(stderr, _("%s: Can't create %s%s%s: %s\n"),
|
||||
progname, diagdir(*outname), diagslash(*outname), *outname,
|
||||
strerror(fopen_errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
|
@ -1424,9 +1445,10 @@ rename_dest(char *tempname, char const *name)
|
|||
if (tempname) {
|
||||
if (rename(tempname, name) != 0) {
|
||||
int rename_errno = errno;
|
||||
(void)remove(tempname);
|
||||
fprintf(stderr, _("%s: rename to %s/%s: %s\n"),
|
||||
progname, directory, name, strerror(rename_errno));
|
||||
remove(tempname);
|
||||
fprintf(stderr, _("%s: rename to %s%s%s: %s\n"),
|
||||
progname, diagdir(name), diagslash(name), name,
|
||||
strerror(rename_errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
free(tempname);
|
||||
|
|
@ -1436,7 +1458,8 @@ rename_dest(char *tempname, char const *name)
|
|||
/* Create symlink contents suitable for symlinking TARGET to LINKNAME, as a
|
||||
freshly allocated string. TARGET should be a relative file name, and
|
||||
is relative to the global variable DIRECTORY. LINKNAME can be either
|
||||
relative or absolute. */
|
||||
relative or absolute. Return a null pointer if the symlink contents
|
||||
was not computed because LINKNAME is absolute but DIRECTORY is not. */
|
||||
static char *
|
||||
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 lenslash = len + (len && directory[len - 1] != '/');
|
||||
size_t targetsize = strlen(target) + 1;
|
||||
if (*directory != '/')
|
||||
return NULL;
|
||||
linksize = size_sum(lenslash, targetsize);
|
||||
f = result = emalloc(linksize);
|
||||
f = result = xmalloc(linksize);
|
||||
memcpy(result, directory, len);
|
||||
result[len] = '/';
|
||||
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);
|
||||
if (dotdotetcsize <= linksize) {
|
||||
if (!result)
|
||||
result = emalloc(dotdotetcsize);
|
||||
result = xmalloc(dotdotetcsize);
|
||||
for (i = 0; i < dotdots; i++)
|
||||
memcpy(result + 3 * i, "../", 3);
|
||||
memmove(result + 3 * dotdots, f + dir_len, taillen + 1);
|
||||
|
|
@ -1500,8 +1525,9 @@ dolink(char const *target, char const *linkname, bool staysymlink)
|
|||
return;
|
||||
else {
|
||||
char const *e = strerror(errno);
|
||||
fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"),
|
||||
progname, directory, linkname, e);
|
||||
fprintf(stderr, _("%s: Can't remove %s%s%s: %s\n"),
|
||||
progname, diagdir(linkname), diagslash(linkname), linkname,
|
||||
e);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
|
@ -1544,8 +1570,9 @@ dolink(char const *target, char const *linkname, bool staysymlink)
|
|||
mkdirs(linkname, true);
|
||||
linkdirs_made = true;
|
||||
} else {
|
||||
fprintf(stderr, _("%s: Can't link %s/%s to %s/%s: %s\n"),
|
||||
progname, directory, target, directory, outname,
|
||||
fprintf(stderr, _("%s: Can't link %s%s%s to %s%s%s: %s\n"),
|
||||
progname, diagdir(target), diagslash(target), target,
|
||||
diagdir(outname), diagslash(outname), outname,
|
||||
strerror(link_errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
|
@ -1554,21 +1581,23 @@ dolink(char const *target, char const *linkname, bool staysymlink)
|
|||
bool absolute = *target == '/';
|
||||
char *linkalloc = absolute ? NULL : relname(target, linkname);
|
||||
char const *contents = absolute ? target : linkalloc;
|
||||
int symlink_errno;
|
||||
int symlink_errno = -1;
|
||||
|
||||
while (true) {
|
||||
if (symlink(contents, outname) == 0) {
|
||||
symlink_errno = 0;
|
||||
break;
|
||||
if (contents) {
|
||||
while (true) {
|
||||
if (symlink(contents, outname) == 0) {
|
||||
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);
|
||||
if (symlink_errno == 0) {
|
||||
|
|
@ -1581,8 +1610,8 @@ dolink(char const *target, char const *linkname, bool staysymlink)
|
|||
fp = fopen(target, "rb");
|
||||
if (!fp) {
|
||||
char const *e = strerror(errno);
|
||||
fprintf(stderr, _("%s: Can't read %s/%s: %s\n"),
|
||||
progname, directory, target, e);
|
||||
fprintf(stderr, _("%s: Can't read %s%s%s: %s\n"),
|
||||
progname, diagdir(target), diagslash(target), target, e);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
tp = open_outfile(&outname, &tempname);
|
||||
|
|
@ -1593,6 +1622,8 @@ dolink(char const *target, char const *linkname, bool staysymlink)
|
|||
if (link_errno != ENOTSUP)
|
||||
warning(_("copy used because hard link failed: %s"),
|
||||
strerror(link_errno));
|
||||
else if (symlink_errno < 0)
|
||||
warning(_("copy used because symbolic link not obvious"));
|
||||
else if (symlink_errno != ENOTSUP)
|
||||
warning(_("copy used because symbolic link failed: %s"),
|
||||
strerror(symlink_errno));
|
||||
|
|
@ -1906,8 +1937,8 @@ inrule(char **fields, int nfields)
|
|||
fields[RF_COMMAND], fields[RF_MONTH], fields[RF_DAY],
|
||||
fields[RF_TOD]))
|
||||
return;
|
||||
r.r_name = estrdup(fields[RF_NAME]);
|
||||
r.r_abbrvar = estrdup(fields[RF_ABBRVAR]);
|
||||
r.r_name = xstrdup(fields[RF_NAME]);
|
||||
r.r_abbrvar = xstrdup(fields[RF_ABBRVAR]);
|
||||
if (max_abbrvar_len < strlen(r.r_abbrvar))
|
||||
max_abbrvar_len = strlen(r.r_abbrvar);
|
||||
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_linenum = linenum;
|
||||
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, '%')
|
||||
|| strchr(fields[i_format], '/')) {
|
||||
error(_("invalid abbreviation format"));
|
||||
|
|
@ -2028,9 +2060,9 @@ inzsub(char **fields, int nfields, bool iscont)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
z.z_name = iscont ? NULL : estrdup(fields[ZF_NAME]);
|
||||
z.z_rule = estrdup(fields[i_rule]);
|
||||
z.z_format = cp1 = estrdup(fields[i_format]);
|
||||
z.z_name = iscont ? NULL : xstrdup(fields[ZF_NAME]);
|
||||
z.z_rule = xstrdup(fields[i_rule]);
|
||||
z.z_format = cp1 = xstrdup(fields[i_format]);
|
||||
if (z.z_format_specifier == 'z') {
|
||||
cp1[cp - fields[i_format]] = 's';
|
||||
if (noise)
|
||||
|
|
@ -2173,8 +2205,8 @@ inlink(char **fields, int nfields)
|
|||
return;
|
||||
l.l_filenum = filenum;
|
||||
l.l_linenum = linenum;
|
||||
l.l_target = estrdup(fields[LF_TARGET]);
|
||||
l.l_linkname = estrdup(fields[LF_LINKNAME]);
|
||||
l.l_target = xstrdup(fields[LF_TARGET]);
|
||||
l.l_linkname = xstrdup(fields[LF_LINKNAME]);
|
||||
links = growalloc(links, sizeof *links, nlinks, &nlinks_alloc);
|
||||
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_todisstd = false;
|
||||
rp->r_todisut = false;
|
||||
dp = estrdup(timep);
|
||||
dp = xstrdup(timep);
|
||||
if (*dp != '\0') {
|
||||
ep = dp + strlen(dp) - 1;
|
||||
switch (lowerit(*ep)) {
|
||||
|
|
@ -2272,19 +2304,23 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
|
|||
** Sun<=20
|
||||
** Sun>=7
|
||||
*/
|
||||
dp = estrdup(dayp);
|
||||
dp = xstrdup(dayp);
|
||||
if ((lp = byword(dp, lasts)) != NULL) {
|
||||
rp->r_dycode = DC_DOWLEQ;
|
||||
rp->r_wday = lp->l_value;
|
||||
rp->r_dayofmonth = len_months[1][rp->r_month];
|
||||
} else {
|
||||
if ((ep = strchr(dp, '<')) != 0)
|
||||
rp->r_dycode = DC_DOWLEQ;
|
||||
else if ((ep = strchr(dp, '>')) != 0)
|
||||
rp->r_dycode = DC_DOWGEQ;
|
||||
ep = strchr(dp, '<');
|
||||
if (ep)
|
||||
rp->r_dycode = DC_DOWLEQ;
|
||||
else {
|
||||
ep = strchr(dp, '>');
|
||||
if (ep)
|
||||
rp->r_dycode = DC_DOWGEQ;
|
||||
else {
|
||||
ep = dp;
|
||||
rp->r_dycode = DC_DOM;
|
||||
}
|
||||
}
|
||||
if (rp->r_dycode != DC_DOM) {
|
||||
*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,
|
||||
as this is a bit faster. Do not malloc(0) if !timecnt,
|
||||
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),
|
||||
alignof(zic_t)));
|
||||
void *typesptr = ats + timecnt;
|
||||
|
|
@ -2802,7 +2838,7 @@ writezone(const char *const name, const char *const string, char version,
|
|||
if (thisleapexpiry) {
|
||||
/* Append a no-op leap correction indicating when the leap
|
||||
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
|
||||
TZif files. */
|
||||
puttzcodepass(leapexpires, fp, pass);
|
||||
|
|
@ -3059,7 +3095,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
|
|||
|
||||
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. */
|
||||
if (hi_time < max_time)
|
||||
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_envvar_len = 2 * max_abbr_len + 5 * 9;
|
||||
|
||||
startbuf = emalloc(max_abbr_len + 1);
|
||||
ab = emalloc(max_abbr_len + 1);
|
||||
envvar = emalloc(max_envvar_len + 1);
|
||||
startbuf = xmalloc(max_abbr_len + 1);
|
||||
ab = xmalloc(max_abbr_len + 1);
|
||||
envvar = xmalloc(max_envvar_len + 1);
|
||||
INITIALIZE(untiltime);
|
||||
INITIALIZE(starttime);
|
||||
/*
|
||||
|
|
@ -3972,7 +4008,7 @@ mkdirs(char const *argname, bool ancestors)
|
|||
if (Dflag)
|
||||
return;
|
||||
|
||||
char *name = estrdup(argname);
|
||||
char *name = xstrdup(argname);
|
||||
char *cp = name;
|
||||
|
||||
/* On MS-Windows systems, do not worry about drive letters or
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue