mirror of
https://frontier.innolan.net/rainlance/amiga-tz.git
synced 2025-11-21 13:01:40 +00:00
Support time stamps past 2038 in zones like America/Santiago.
This implements a suggestion by Arthur David Olson. Without this change, zic -v diagnoses problems with several zones where it cannot compute a POSIX-equivalent TZ setting for time stamps past 2038, which means these time stamps may be mishandled. This entails a minor change to the binary tz file format, to allow a minor extension to the POSIX TZ setting in the binary file, instead of requiring a pure POSIX TZ setting. The zones fixed by this change are America/Godthab, America/Santiago, Antarctica/Palmer, Asia/Gaza, Asia/Hebron, Asia/Jerusalem, Pacific/Easter, and Pacific/Fiji. The only zone that remains unfixed is Asia/Tehran, which schedules clock transitions via the Iranian calendar, something that even the extended TZ setting cannot represent. * localtime.c (getrule): Allow transition times to be signed. * newtzset.3: Describe the extensions to POSIX TZ strings. Some of these extensions (e.g., hours == 26) were already implemented but were not documented. Give examples. * tzfile.5: Document the relaxed restriction on the stored TZ string; its hours component can be in the range -167..167 rather than the POSIX-required 0..24. Refer to newtzset(5). * zic.c (stringoffset): Allow hours to go up to 167. (stringrule): Be willing to generate hours in the range -167 through 167.
This commit is contained in:
@ -835,7 +835,7 @@ getrule(const char *strp, register struct rule *const rulep)
|
||||
** Time specified.
|
||||
*/
|
||||
++strp;
|
||||
strp = getsecs(strp, &rulep->r_time);
|
||||
strp = getoffset(strp, &rulep->r_time);
|
||||
} else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
|
||||
return strp;
|
||||
}
|
||||
|
||||
37
newtzset.3
37
newtzset.3
@ -177,16 +177,47 @@ The
|
||||
.I time
|
||||
has the same format as
|
||||
.I offset
|
||||
except that no leading sign
|
||||
except that POSIX does not allow a leading sign
|
||||
.RB (`` \(mi ''
|
||||
or
|
||||
.RB `` \(pl '')
|
||||
is allowed. The default, if
|
||||
.RB `` \(pl '').
|
||||
As an extension to POSIX, the hours part of
|
||||
.I time
|
||||
can range from \(mi167 to 167; this allows for unusual rules such
|
||||
as "the Saturday before the first Sunday of March". The default, if
|
||||
.I time
|
||||
is not given, is
|
||||
.BR 02:00:00 .
|
||||
.RE
|
||||
.LP
|
||||
Here are some examples of
|
||||
.B TZ
|
||||
values that directly specify the time zone rules; they use some of the
|
||||
extensions to POSIX.
|
||||
.TP
|
||||
.B EST5
|
||||
stands for US eastern
|
||||
time (EST), 5 hours behind UTC, without daylight saving.
|
||||
.TP
|
||||
.B FJT\(mi12FJST,M10.3.4/74,M1.3.4/75
|
||||
stands for Fiji Time (FJT) and Fiji Summer Time (FJST), 12 hours ahead
|
||||
of UTC, where clocks spring forward at 74:00 on the third Thursday in
|
||||
October (i.e., 02:00 on the first Sunday on or after October 18), and
|
||||
fall back at 75:00 on the third Thursday in January (i.e., 03:00 on
|
||||
the first Sunday on or after January 18).
|
||||
.TP
|
||||
.B IST\(mi2IDT,M3.4.4/26,M10.5.0
|
||||
stands for Israel standard time (IST) and Israel daylight time (IDT),
|
||||
2 hours ahead of UTC, where clocks spring forward at 26:00 on the
|
||||
fourth Thursday in March (i.e., 02:00 on the first Friday on or after
|
||||
March 23), and fall back at 02:00 on the last Sunday in October.
|
||||
.TP
|
||||
.B WGT3WGST,M3.5.0/\(mi2,M10.5.0/\(mi1
|
||||
stands for Western Greenland Time (WGT) and Western Greenland Summer
|
||||
Time (WGST), 3 hours behind UTC, where clocks follow the EU rules of
|
||||
springing forward the last Sunday in March at \(mi02:00 (i.e., 01:00 UTC)
|
||||
and falling back the last Sunday in October at \(mi01:00 (i.e., 01:00 UTC).
|
||||
.PP
|
||||
If no
|
||||
.I rule
|
||||
is present in
|
||||
|
||||
6
tzfile.5
6
tzfile.5
@ -145,7 +145,11 @@ POSIX-TZ-environment-variable-style string for use in handling instants
|
||||
after the last transition time stored in the file
|
||||
(with nothing between the newlines if there is no POSIX representation for
|
||||
such instants).
|
||||
This string may use a minor extension to the POSIX TZ format: the
|
||||
hours part of its transition times may be signed and range from
|
||||
\(mi167 through 167 instead of the POSIX-required unsigned values
|
||||
from 0 through 24.
|
||||
.SH SEE ALSO
|
||||
newctime(3)
|
||||
newctime(3), newtzset(3)
|
||||
.\" This file is in the public domain, so clarified as of
|
||||
.\" 1996-06-05 by Arthur David Olson.
|
||||
|
||||
27
zic.c
27
zic.c
@ -1776,7 +1776,7 @@ stringoffset(char *result, zic_t offset)
|
||||
minutes = offset % MINSPERHOUR;
|
||||
offset /= MINSPERHOUR;
|
||||
hours = offset;
|
||||
if (hours > HOURSPERDAY) {
|
||||
if (hours >= HOURSPERDAY * DAYSPERWEEK) {
|
||||
result[0] = '\0';
|
||||
return -1;
|
||||
}
|
||||
@ -1793,7 +1793,7 @@ static int
|
||||
stringrule(char *result, const struct rule *const rp, const zic_t dstoff,
|
||||
const zic_t gmtoff)
|
||||
{
|
||||
register zic_t tod;
|
||||
register zic_t tod = rp->r_tod;
|
||||
|
||||
result = end(result);
|
||||
if (rp->r_dycode == DC_DOM) {
|
||||
@ -1807,32 +1807,33 @@ stringrule(char *result, const struct rule *const rp, const zic_t dstoff,
|
||||
(void) sprintf(result, "J%d", total + rp->r_dayofmonth);
|
||||
} else {
|
||||
register int week;
|
||||
register int wday = rp->r_wday;
|
||||
register int wdayoff;
|
||||
|
||||
if (rp->r_dycode == DC_DOWGEQ) {
|
||||
if ((rp->r_dayofmonth % DAYSPERWEEK) != 1)
|
||||
return -1;
|
||||
week = 1 + rp->r_dayofmonth / DAYSPERWEEK;
|
||||
wdayoff = (rp->r_dayofmonth - 1) % DAYSPERWEEK;
|
||||
wday -= wdayoff;
|
||||
tod += wdayoff * SECSPERDAY;
|
||||
week = 1 + (rp->r_dayofmonth - 1) / DAYSPERWEEK;
|
||||
} else if (rp->r_dycode == DC_DOWLEQ) {
|
||||
if (rp->r_dayofmonth == len_months[1][rp->r_month])
|
||||
week = 5;
|
||||
else {
|
||||
if ((rp->r_dayofmonth % DAYSPERWEEK) != 0)
|
||||
return -1;
|
||||
wdayoff = rp->r_dayofmonth % DAYSPERWEEK;
|
||||
wday -= wdayoff;
|
||||
tod += wdayoff * SECSPERDAY;
|
||||
week = rp->r_dayofmonth / DAYSPERWEEK;
|
||||
}
|
||||
} else return -1; /* "cannot happen" */
|
||||
if (wday < 0)
|
||||
wday += DAYSPERWEEK;
|
||||
(void) sprintf(result, "M%d.%d.%d",
|
||||
rp->r_month + 1, week, rp->r_wday);
|
||||
rp->r_month + 1, week, wday);
|
||||
}
|
||||
tod = rp->r_tod;
|
||||
if (rp->r_todisgmt)
|
||||
tod += gmtoff;
|
||||
if (rp->r_todisstd && rp->r_stdoff == 0)
|
||||
tod += dstoff;
|
||||
if (tod < 0) {
|
||||
result[0] = '\0';
|
||||
return -1;
|
||||
}
|
||||
if (tod != 2 * SECSPERMIN * MINSPERHOUR) {
|
||||
(void) strcat(result, "/");
|
||||
if (stringoffset(end(result), tod) != 0)
|
||||
|
||||
Reference in New Issue
Block a user