[tz] [PROPOSED] More clarification/explanation from RFC 8536

Paul Eggert eggert at cs.ucla.edu
Tue Jun 18 00:58:28 UTC 2019


This just changes documentation: it does not change code or data.
Mostly, it just adopts more terminology from RFC 8536.
It also contains an example of what the std/wall and UT/local
indicators are for.
* newtzset.3, theory.html, tz-how-to.html, tzfile.5, tzfile.h, zic.8:
In documentation and comments, make it clearer that local time
equals wall clock time.
* tzfile.5, tzfile.h: In documentation and comments, say that when
isut is 1, isstd must also be 1.
* tzfile.5: Specify that bytes are 8 bits, that binary integers
use two's complement, and that booleans use 0 and 1.
Say that UT offsets are never equal to -2**31, and that they
realistically are in the range [-89999, 93599].  Say that
leap second counts are signed.  Say why std/wall and UT/local
indicators are present, and give AKST9AKDT as an example.
Do not say that the first standard-time ttinfo is used by
localtime, as the actual heuristic is far more complicated;
instead, document what RFC 8536 says as what's normally used.
* zic.c (struct rule): Adjust comments.
---
 newtzset.3     |  4 ++--
 theory.html    | 10 ++++----
 tz-how-to.html | 14 ++++++------
 tzfile.5       | 62 +++++++++++++++++++++++++++++++++-----------------
 tzfile.h       | 15 ++++++------
 zic.8          | 16 ++++++-------
 zic.c          |  6 ++---
 7 files changed, 73 insertions(+), 54 deletions(-)

diff --git a/newtzset.3 b/newtzset.3
index 29e8a21..4959851 100644
--- a/newtzset.3
+++ b/newtzset.3
@@ -65,8 +65,8 @@ falls back on Universal Time (UT).
 .PP
 If
 .B TZ
-is null, the best available approximation to local wall
-clock time, as specified by the
+is null, the best available approximation to local (wall
+clock) time, as specified by the
 .IR tzfile (5)-format
 file
 .B localtime
diff --git a/theory.html b/theory.html
index e580ccc..61d556b 100644
--- a/theory.html
+++ b/theory.html
@@ -955,7 +955,7 @@ an older <code>zic</code>.
   </li>
   <li>
     In POSIX, there is no tamper-proof way for a process to learn the
-    system's best idea of local wall clock.
+    system's best idea of local (wall clock) time.
     This is important for applications that an administrator wants
     used only at certain times – without regard to whether the
     user has fiddled the
@@ -1052,14 +1052,14 @@ an older <code>zic</code>.
   </li>
   <li>
     A function <code>tzsetwall</code> has been added to arrange for the
-    system's best approximation to local wall clock time to be delivered
+    system's best approximation to local (wall clock) time to be delivered
     by subsequent calls to <code>localtime</code>.
-    Source code for portable applications that "must" run on local wall
-    clock time should call <code>tzsetwall</code>;
+    Source code for portable applications that "must" run on local
+    time should call <code>tzsetwall</code>;
     if such code is moved to "old" systems that do not
     provide <code>tzsetwall</code>, you will not be able to generate an
     executable program.
-    (These functions also arrange for local wall clock time to
+    (These functions also arrange for local time to
     be used if <code>tzset</code> is called – directly or
     indirectly – and there is no <code>TZ</code> environment
     variable; portable applications should not, however, rely on this
diff --git a/tz-how-to.html b/tz-how-to.html
index 7274af4..2e4842d 100644
--- a/tz-how-to.html
+++ b/tz-how-to.html
@@ -102,7 +102,7 @@ in some localizable way. It’s used in the file, <code>pacificnew</code>,
 to determine whether a given year will have a US presidential election;
 but everything related to that use is commented out.)
 
-<p>The <code>SAVE</code> column contains the wall clock offset from
+<p>The <code>SAVE</code> column contains the local (wall clock) offset from
 local standard time.
 This is usually either zero for standard time or one hour for daylight
 saving time; but there’s no reason, in principle, why it can’t
@@ -250,10 +250,10 @@ Rule  US   2007 max   -   Nov Sun>=1   2:00  0    S
 <p>There are two interesting things to note here.</p>
 
 <p>First, the time that something happens (in the <code>AT</code>
-column) is not necessarily the local wall clock time. The time can be
+column) is not necessarily the local (wall clock) time. The time can be
 suffixed with ‘s’ (for “standard”) to mean
-local standard time (different from wall clock time when observing
-daylight saving time); or it can be suffixed with ‘g’,
+local standard time, different from local (wall clock) time when observing
+daylight saving time; or it can be suffixed with ‘g’,
 ‘u’, or ‘z’, all three of which mean the
 standard time at the
 <a href="https://en.wikipedia.org/wiki/Prime_Meridian">prime meridian</a>.
@@ -265,8 +265,8 @@ href="https://en.wikipedia.org/wiki/Coordinated_Universal_Time">UTC</a>”
 (whichever was official at the time); ‘z’ stands for the
 <a href="https://en.wikipedia.org/wiki/Nautical_time">nautical time zone</a>
 Z (a.k.a. “Zulu” which, in turn, stands for ‘Z’).
-The time can also be suffixed with ‘w’ meaning “wall
-clock time;” but it usually isn’t because that’s the
+The time can also be suffixed with ‘w’ meaning local (wall
+clock) time; but it usually isn’t because that’s the
 default.</p>
 
 <p>Second, the day in the <code>ON</code> column, in addition to
@@ -467,7 +467,7 @@ Zone Pacific/Honolulu ...                 1933 Apr 30  2:00
 <p>Hawaii tried daylight saving time for three weeks in 1933 and
 decided they didn’t like it. <code>8-) </code>Note that
 the <code>STDOFF</code> column always contains the standard time
-offset, so the wall clock time during this period was GMT −
+offset, so the local (wall clock) time during this period was GMT −
 10:30 + 1:00 = GMT − 9:30.</p>
 
 <p>The <code>FORMAT</code> column specifies the usual abbreviation of
diff --git a/tzfile.5 b/tzfile.5
index b591e56..d13029c 100644
--- a/tzfile.5
+++ b/tzfile.5
@@ -16,6 +16,13 @@ The timezone information files used by
 are typically found under a directory with a name like
 .IR /usr/share/zoneinfo .
 These files use the format described in Internet RFC 8536.
+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),
+with all bits significant,
+a signed binary integer is represented using two's complement,
+and a boolean is represented by a one-byte binary integer that is
+either 0 (false) or 1 (true).
 The format begins with a 44-byte header containing the following fields:
 .IP * 2
 The magic four-byte ASCII sequence
@@ -30,11 +37,7 @@ or
 .IP *
 Fifteen bytes containing zeros reserved for future use.
 .IP *
-Six four-byte integer values
-written in a standard byte order
-(the high-order byte of the value is written first).
-These values are,
-in order:
+Six four-byte integer values, in the following order:
 .RS
 .TP
 .I tzh_ttisutcnt
@@ -64,7 +67,7 @@ depend on the contents of the header:
 .IP * 2
 .I tzh_timecnt
 four-byte signed integer values sorted in ascending order.
-These values are written in standard byte order.
+These values are written in network byte order.
 Each is used as a transition time (as returned by
 .BR time (2))
 at which the rules for computing local time change.
@@ -96,7 +99,7 @@ struct ttinfo {
 .sp
 Each structure is written as a four-byte signed integer value for
 .IR tt_utoff ,
-in a standard byte order, followed by a one-byte value for
+in network byte order, followed by a one-byte boolean for
 .I tt_isdst
 and a one-byte value for
 .IR tt_desigidx .
@@ -114,14 +117,23 @@ serves as an index into the array of time zone abbreviation bytes
 that follow the
 .I ttinfo
 structure(s) in the file.
+The
+.I tt_utoff
+value is never equal to -2**31, to let 32-bit clients negate it without
+overflow.
+Also, in realistic applications
+.I tt_utoff
+is in the range [-89999, 93599] (i.e., more than -25 hours and less
+than 26 hours); this allows easy support by implementations that
+already support the POSIX-required range [-24:59:59, 25:59:59].
 .IP *
 .I tzh_leapcnt
-pairs of four-byte values, written in standard byte order;
+pairs of four-byte values, written in network byte order;
 the first value of each pair gives the nonnegative time
 (as returned by
 .BR time (2))
 at which a leap second occurs;
-the second gives the
+the second is a signed integer specifying the
 .I total
 number of leap seconds to be applied during the time period
 starting at the given time.
@@ -130,28 +142,36 @@ Each transition is for one leap second, either positive or negative;
 transitions always separated by at least 28 days minus 1 second.
 .IP *
 .I tzh_ttisstdcnt
-standard/wall indicators, each stored as a one-byte value;
+standard/wall indicators, each stored as a one-byte boolean;
 they tell whether the transition times associated with local time types
-were specified as standard time or wall clock time,
-and are used when a timezone file is used in handling POSIX-style
-timezone environment variables.
+were specified as standard time or local (wall clock) time.
 .IP *
 .I tzh_ttisutcnt
-UT/local indicators, each stored as a one-byte value;
+UT/local indicators, each stored as a one-byte boolean;
 they tell whether the transition times associated with local time types
-were specified as UT or local time,
-and are used when a timezone file is used in handling POSIX-style
-timezone environment variables.
+were specified as UT or local time.
+If a UT/local indicator is set, the corresponding standard/wall indicator
+must also be set.
+.PP
+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 POSIX-style TZ string that lacks rules.
+For example, when TZ="AKST9AKDT" and there is no TZif file "AKST9AKDT",
+the transition times might be adapted from a TZif file with the
+well-known name "posixrules" that is present only for this purpose and
+is a copy of the file "America/New_York", a file with a different UT offset.
+POSIX does not specify this obsolescent transformational behavior and
+widely used platforms such as GNU/Linux do not support it correctly, so users
+desiring Alaska time should specify TZ="America/Anchorage" for better
+historical coverage, or TZ="AKST9AKDT,M3.2.0,M11.1.0" for POSIX
+conformance and coverage for recent timestamps only.
 .PP
 The
 .BR localtime (3)
 function
-uses the first standard-time
+normally uses the first
 .I ttinfo
 structure in the file
-(or simply the first
-.I ttinfo
-structure in the absence of a standard-time structure)
 if either
 .I tzh_timecnt
 is zero or the time argument is less than the first transition time recorded
diff --git a/tzfile.h b/tzfile.h
index 52673d6..ee91104 100644
--- a/tzfile.h
+++ b/tzfile.h
@@ -69,14 +69,15 @@ struct tzhead {
 **		one (char [4])		total correction after above
 **	tzh_ttisstdcnt (char)s		indexed by type; if 1, transition
 **					time is standard time, if 0,
-**					transition time is wall clock time
-**					if absent, transition times are
-**					assumed to be wall clock time
-**	tzh_ttisutcnt (char)s		indexed by type; if 1, transition
-**					time is UT, if 0,
-**					transition time is local time
-**					if absent, transition times are
+**					transition time is local (wall clock)
+**					time; if absent, transition times are
 **					assumed to be local time
+**	tzh_ttisutcnt (char)s		indexed by type; if 1, transition
+**					time is UT, if 0, transition time is
+**					local time; if absent, transition
+**					times are assumed to be local time.
+**					When this is 1, the corresponding
+**					std/wall indicator must also be 1.
 */
 
 /*
diff --git a/zic.8 b/zic.8
index 02b6048..3a4d96f 100644
--- a/zic.8
+++ b/zic.8
@@ -385,13 +385,12 @@ to other applications requiring greater precision.
 The source format does not specify any maximum precision.
 Any of these forms may be followed by the letter
 .B w
-if the given time is local
+if the given time is local or
 .q "wall clock"
 time,
 .B s
-if the given time is local
-.q "standard"
-time, or
+if the given time is standard time without any adjustment for daylight saving,
+or
 .B u
 (or
 .B g
@@ -399,7 +398,7 @@ or
 .BR z )
 if the given time is universal time;
 in the absence of an indicator,
-wall clock time is assumed.
+local (wall clock) time is assumed.
 These forms ignore leap seconds; for example,
 if a leap second occurs at 00:59:60 local time,
 .q "1:00"
@@ -478,7 +477,8 @@ a file name component is a maximal substring that does not contain
 .q "/" .
 .TP
 .B STDOFF
-The amount of time to add to UT to get standard time.
+The amount of time to add to UT to get standard time,
+without any adjustment for daylight saving.
 This field has the same format as the
 .B AT
 and
@@ -636,7 +636,7 @@ or
 (an abbreviation of)
 .q "Rolling"
 if the leap second time given by the other fields should be interpreted as
-local wall clock time.
+local (wall clock) time.
 .SH "EXTENDED EXAMPLE"
 Here is an extended example of
 .B zic
@@ -720,7 +720,7 @@ coincides with and is equal to
 a clock retreat caused by a change in UT offset,
 .B zic
 produces a single transition to daylight saving at the new UT offset
-(without any change in wall clock time).
+without any change in local (wall clock) time.
 To get separate transitions
 use multiple zone continuation lines
 specifying transition instants using universal time.
diff --git a/zic.c b/zic.c
index b3665bd..3fb32c7 100644
--- a/zic.c
+++ b/zic.c
@@ -92,10 +92,8 @@ struct rule {
 	int		r_wday;
 
 	zic_t		r_tod;		/* time from midnight */
-	bool		r_todisstd;	/* above is standard time if 1 */
-					/* or wall clock time if 0 */
-	bool		r_todisut;	/* above is GMT if 1 */
-					/* or local time if 0 */
+	bool		r_todisstd;	/* is r_tod standard time? */
+	bool		r_todisut;	/* is r_tod UT? */
 	bool		r_isdst;	/* is this daylight saving time? */
 	zic_t		r_save;		/* offset from standard time */
 	const char *	r_abbrvar;	/* variable part of abbreviation */
-- 
2.21.0



More information about the tz mailing list