xref: /freebsd/contrib/tzcode/tzfile.5 (revision 15f0b8c3)
1.\" This file is in the public domain, so clarified as of
2.\" 1996-06-05 by Arthur David Olson.
3.\"
4.\" $FreeBSD$
5.\"
6.Dd December 15, 2022
7.Dt TZFILE 5
8.Os
9.Sh NAME
10.Nm tzfile
11.Nd timezone information
12.Sh DESCRIPTION
13The timezone information files used by
14.Xr tzset 3
15are found under
16.Pa /usr/share/zoneinfo .
17These files use the format described in Internet RFC 8536.
18Each file is a sequence of 8-bit bytes.
19In a file, a binary integer is represented by a sequence of one or
20more bytes in network order (bigendian, or high-order byte first),
21with all bits significant,
22a signed binary integer is represented using two's complement,
23and a boolean is represented by a one-byte binary integer that is
24either 0 (false) or 1 (true).
25The format begins with a 44-byte header containing the following fields:
26.Pp
27.Bl -bullet
28.It
29The magic four-byte ASCII sequence
30.Dq "TZif"
31identifies the file as a timezone information file.
32.It
33A byte identifying the version of the file's format
34(as of 2021, either an ASCII NUL,
35.Dq "2" ,
36.Dq "3" ,
37or
38.Dq "4" ) .
39.It
40Fifteen bytes containing zeros reserved for future use.
41.It
42Six four-byte integer values, in the following order:
43.Pp
44.Bl -tag -compat -width tzh_ttisstdcnt
45.It Va tzh_ttisutcnt
46The number of UT/local indicators stored in the file.
47(UT is Universal Time.)
48.It Va tzh_ttisstdcnt
49The number of standard/wall indicators stored in the file.
50.It Va tzh_leapcnt
51The number of leap seconds for which data entries are stored in the file.
52.It Va tzh_timecnt
53The number of transition times for which data entries are stored
54in the file.
55.It Va tzh_typecnt
56The number of local time types for which data entries are stored
57in the file (must not be zero).
58.It Va tzh_charcnt
59The number of bytes of time zone abbreviation strings
60stored in the file.
61.El
62.El
63.Pp
64The above header is followed by the following fields, whose lengths
65depend on the contents of the header:
66.Bl -tag -compat -width tzh_timecnt
67.It Va tzh_timecnt
68four-byte signed integer values sorted in ascending order.
69These values are written in network byte order.
70Each is used as a transition time (as returned by
71.Xt time 2 )
72at which the rules for computing local time change.
73.It Va tzh_timecnt
74one-byte unsigned integer values;
75each one but the last tells which of the different types of local time types
76described in the file is associated with the time period
77starting with the same-indexed transition time
78and continuing up to but not including the next transition time.
79(The last time type is present only for consistency checking with the
80POSIX-style TZ string described below.)
81These values serve as indices into the next field.
82.It Va tzh_typecnt
83.Vt ttinfo
84entries, each defined as follows:
85.Pp
86.Bd -literal -offset indent
87struct ttinfo {
88	int32_t	tt_utoff;
89	unsigned char	tt_isdst;
90	unsigned char	tt_desigidx;
91};
92.Ed
93.Pp
94Each structure is written as a four-byte signed integer value for
95.Va tt_utoff ,
96in network byte order, followed by a one-byte boolean for
97.Va tt_isdst
98and a one-byte value for
99.Va tt_desigidx .
100In each structure,
101.Va tt_utoff
102gives the number of seconds to be added to UT,
103.Va tt_isdst
104tells whether
105.Va tm_isdst
106should be set by
107.Xr localtime 3
108and
109.Va tt_desigidx
110serves as an index into the array of time zone abbreviation bytes
111that follow the
112.Vt ttinfo
113entries in the file; if the designated string is "\*-00", the
114.Vt ttinfo
115entry is a placeholder indicating that local time is unspecified.
116The
117.Va tt_utoff
118value is never equal to \-2**31, to let 32-bit clients negate it without
119overflow.
120Also, in realistic applications
121.Va tt_utoff
122is in the range [\-89999, 93599] (i.e., more than \-25 hours and less
123than 26 hours); this allows easy support by implementations that
124already support the POSIX-required range [\-24:59:59, 25:59:59].
125.It Va tzh_charcnt
126bytes that represent time zone designations,
127which are null-terminated byte strings, each indexed by the
128.Va tt_desigidx
129values mentioned above.
130The byte strings can overlap if one is a suffix of the other.
131The encoding of these strings is not specified.
132.It Va tzh_leapcnt
133pairs of four-byte values, written in network byte order;
134the first value of each pair gives the nonnegative time
135(as returned by
136.Xr time 3 )
137at which a leap second occurs or at which the leap second table expires;
138the second is a signed integer specifying the correction, which is the
139.Em total
140number of leap seconds to be applied during the time period
141starting at the given time.
142The pairs of values are sorted in strictly ascending order by time.
143Each pair denotes one leap second, either positive or negative,
144except that if the last pair has the same correction as the previous one,
145the last pair denotes the leap second table's expiration time.
146Each leap second is at the end of a UTC calendar month.
147The first leap second has a nonnegative occurrence time,
148and is a positive leap second if and only if its correction is positive;
149the correction for each leap second after the first differs
150from the previous leap second by either 1 for a positive leap second,
151or \-1 for a negative leap second.
152If the leap second table is empty, the leap-second correction is zero
153for all timestamps;
154otherwise, for timestamps before the first occurrence time,
155the leap-second correction is zero if the first pair's correction is 1 or \-1,
156and is unspecified otherwise (which can happen only in files
157truncated at the start).
158.It Va tzh_ttisstdcnt
159standard/wall indicators, each stored as a one-byte boolean;
160they tell whether the transition times associated with local time types
161were specified as standard time or local (wall clock) time.
162.It Va tzh_ttisutcnt
163UT/local indicators, each stored as a one-byte boolean;
164they tell whether the transition times associated with local time types
165were specified as UT or local time.
166If a UT/local indicator is set, the corresponding standard/wall indicator
167must also be set.
168.El
169.Pp
170The standard/wall and UT/local indicators were designed for
171transforming a TZif file's transition times into transitions appropriate
172for another time zone specified via a POSIX-style TZ string that lacks rules.
173For example, when TZ="EET\*-2EEST" and there is no TZif file "EET\*-2EEST",
174the idea was to adapt the transition times from a TZif file with the
175well-known name "posixrules" that is present only for this purpose and
176is a copy of the file "Europe/Brussels", a file with a different UT offset.
177POSIX does not specify this obsolete transformational behavior,
178the default rules are installation-dependent, and no implementation
179is known to support this feature for timestamps past 2037,
180so users desiring (say) Greek time should instead specify
181TZ="Europe/Athens" for better historical coverage, falling back on
182TZ="EET\*-2EEST,M3.5.0/3,M10.5.0/4" if POSIX conformance is required
183and older timestamps need not be handled accurately.
184.Pp
185The
186.Xr localtime 3
187function
188normally uses the first
189.Vt ttinfo
190structure in the file
191if either
192.Va tzh_timecnt
193is zero or the time argument is less than the first transition time recorded
194in the file.
195.Ss Version 2 format
196For version-2-format timezone files,
197the above header and data are followed by a second header and data,
198identical in format except that
199eight bytes are used for each transition time or leap second time.
200(Leap second counts remain four bytes.)
201After the second header and data comes a newline-enclosed,
202POSIX-TZ-environment-variable-style string for use in handling instants
203after the last transition time stored in the file
204or for all instants if the file has no transitions.
205The POSIX-style TZ string is empty (i.e., nothing between the newlines)
206if there is no POSIX-style representation for such instants.
207If nonempty, the POSIX-style TZ string must agree with the local time
208type after the last transition time if present in the eight-byte data;
209for example, given the string
210.Dq "WET0WEST,M3.5.0,M10.5.0/3"
211then if a last transition time is in July, the transition's local time
212type must specify a daylight-saving time abbreviated
213.Dq "WEST"
214that is one hour east of UT.
215Also, if there is at least one transition, time type 0 is associated
216with the time period from the indefinite past up to but not including
217the earliest transition time.
218.Ss Version 3 format
219For version-3-format timezone files, the POSIX-TZ-style string may
220use two minor extensions to the POSIX TZ format, as described in
221.Xr newtzset 3 .
222First, the hours part of its transition times may be signed and range from
223\-167 through 167 instead of the POSIX-required unsigned values
224from 0 through 24.
225Second, DST is in effect all year if it starts
226January 1 at 00:00 and ends December 31 at 24:00 plus the difference
227between daylight saving and standard time.
228.Ss Version 4 format
229For version-4-format TZif files,
230the first leap second record can have a correction that is neither
231+1 nor \-1, to represent truncation of the TZif file at the start.
232Also, if two or more leap second transitions are present and the last
233entry's correction equals the previous one, the last entry
234denotes the expiration of the leap second table instead of a leap second;
235timestamps after this expiration are unreliable in that future
236releases will likely add leap second entries after the expiration, and
237the added leap seconds will change how post-expiration timestamps are treated.
238.Ss Interoperability considerations
239Future changes to the format may append more data.
240.Pp
241Version 1 files are considered a legacy format and
242should not be generated, as they do not support transition
243times after the year 2038.
244Readers that understand only Version 1 must ignore
245any data that extends beyond the calculated end of the version
2461 data block.
247.Pp
248Other than version 1, writers should generate
249the lowest version number needed by a file's data.
250For example, a writer should generate a version 4 file
251only if its leap second table either expires or is truncated at the start.
252Likewise, a writer not generating a version 4 file
253should generate a version 3 file only if
254TZ string extensions are necessary to accurately
255model transition times.
256.Pp
257The sequence of time changes defined by the version 1
258header and data block should be a contiguous sub-sequence
259of the time changes defined by the version 2+ header and data
260block, and by the footer.
261This guideline helps obsolescent version 1 readers
262agree with current readers about timestamps within the
263contiguous sub-sequence.
264It also lets writers not
265supporting obsolescent readers use a
266.Va tzh_timecnt
267of zero
268in the version 1 data block to save space.
269.Pp
270When a TZif file contains a leap second table expiration
271time, TZif readers should either refuse to process
272post-expiration timestamps, or process them as if the expiration
273time did not exist (possibly with an error indication).
274.Pp
275Time zone designations should consist of at least three (3)
276and no more than six (6) ASCII characters from the set of
277alphanumerics,
278.Dq "\*-" ,
279and
280.Dq "+" .
281This is for compatibility with POSIX requirements for
282time zone abbreviations.
283.Pp
284When reading a version 2 or higher file, readers
285should ignore the version 1 header and data block except for
286the purpose of skipping over them.
287.Pp
288Readers should calculate the total lengths of the
289headers and data blocks and check that they all fit within
290the actual file size, as part of a validity check for the file.
291.Pp
292When a positive leap second occurs, readers should append an extra
293second to the local minute containing the second just before the leap
294second.
295If this occurs when the UTC offset is not a multiple of 60
296seconds, the leap second occurs earlier than the last second of the
297local minute and the minute's remaining local seconds are numbered
298through 60 instead of the usual 59; the UTC offset is unaffected.
299.Ss Common interoperability issues
300This section documents common problems in reading or writing TZif files.
301Most of these are problems in generating TZif files for use by
302older readers.
303The goals of this section are:
304.Bl -bullet
305.It
306to help TZif writers output files that avoid common
307pitfalls in older or buggy TZif readers,
308.It
309to help TZif readers avoid common pitfalls when reading
310files generated by future TZif writers, and
311.It
312to help any future specification authors see what sort of
313problems arise when the TZif format is changed.
314.El
315.Pp
316When new versions of the TZif format have been defined, a
317design goal has been that a reader can successfully use a TZif
318file even if the file is of a later TZif version than what the
319reader was designed for.
320When complete compatibility was not achieved, an attempt was
321made to limit glitches to rarely used timestamps and allow
322simple partial workarounds in writers designed to generate
323new-version data useful even for older-version readers.
324This section attempts to document these compatibility issues and
325workarounds, as well as to document other common bugs in
326readers.
327.Pp
328Interoperability problems with TZif include the following:
329.Bl -bullet
330.It
331Some readers examine only version 1 data.
332As a partial workaround, a writer can output as much version 1
333data as possible.
334However, a reader should ignore version 1 data, and should use
335version 2+ data even if the reader's native timestamps have only
33632 bits.
337.It
338Some readers designed for version 2 might mishandle
339timestamps after a version 3 or higher file's last transition, because
340they cannot parse extensions to POSIX in the TZ-like string.
341As a partial workaround, a writer can output more transitions
342than necessary, so that only far-future timestamps are
343mishandled by version 2 readers.
344.It
345Some readers designed for version 2 do not support
346permanent daylight saving time with transitions after 24:00
347\(en e.g., a TZ string
348.Dq "EST5EDT,0/0,J365/25"
349denoting permanent Eastern Daylight Time
350(\-04).
351As a workaround, a writer can substitute standard time
352for two time zones east, e.g.,
353.Dq "XXX3EDT4,0/0,J365/23"
354for a time zone with a never-used standard time (XXX, \-03)
355and negative daylight saving time (EDT, \-04) all year.
356Alternatively,
357as a partial workaround a writer can substitute standard time
358for the next time zone east \(en e.g.,
359.Dq "AST4"
360for permanent
361Atlantic Standard Time (\-04).
362.It
363Some readers designed for version 2 or 3, and that require strict
364conformance to RFC 8536, reject version 4 files whose leap second
365tables are truncated at the start or that end in expiration times.
366.It
367Some readers ignore the footer, and instead predict future
368timestamps from the time type of the last transition.
369As a partial workaround, a writer can output more transitions
370than necessary.
371.It
372Some readers do not use time type 0 for timestamps before
373the first transition, in that they infer a time type using a
374heuristic that does not always select time type 0.
375As a partial workaround, a writer can output a dummy (no-op)
376first transition at an early time.
377.It
378Some readers mishandle timestamps before the first
379transition that has a timestamp not less than \-2**31.
380Readers that support only 32-bit timestamps are likely to be
381more prone to this problem, for example, when they process
38264-bit transitions only some of which are representable in 32
383bits.
384As a partial workaround, a writer can output a dummy
385transition at timestamp \-2**31.
386.It
387Some readers mishandle a transition if its timestamp has
388the minimum possible signed 64-bit value.
389Timestamps less than \-2**59 are not recommended.
390.It
391Some readers mishandle POSIX-style TZ strings that
392contain
393.Dq "<"
394or
395.Dq ">".
396As a partial workaround, a writer can avoid using
397.Dq "<"
398or
399.Dq ">"
400for time zone abbreviations containing only alphabetic
401characters.
402.It
403Many readers mishandle time zone abbreviations that contain
404non-ASCII characters.
405These characters are not recommended.
406.It
407Some readers may mishandle time zone abbreviations that
408contain fewer than 3 or more than 6 characters, or that
409contain ASCII characters other than alphanumerics,
410.Dq "\*-",
411and
412.Dq "+".
413These abbreviations are not recommended.
414.It
415Some readers mishandle TZif files that specify
416daylight-saving time UT offsets that are less than the UT
417offsets for the corresponding standard time.
418These readers do not support locations like Ireland, which
419uses the equivalent of the POSIX TZ string
420.Dq "IST\*-1GMT0,M10.5.0,M3.5.0/1" ,
421observing standard time
422(IST, +01) in summer and daylight saving time (GMT, +00) in winter.
423As a partial workaround, a writer can output data for the
424equivalent of the POSIX TZ string
425.Dq "GMT0IST,M3.5.0/1,M10.5.0" ,
426thus swapping standard and daylight saving time.
427Although this workaround misidentifies which part of the year
428uses daylight saving time, it records UT offsets and time zone
429abbreviations correctly.
430.It
431Some readers generate ambiguous timestamps for positive leap seconds
432that occur when the UTC offset is not a multiple of 60 seconds.
433For example, in a timezone with UTC offset +01:23:45 and with
434a positive leap second 78796801 (1972-06-30 23:59:60 UTC), some readers will
435map both 78796800 and 78796801 to 01:23:45 local time the next day
436instead of mapping the latter to 01:23:46, and they will map 78796815 to
43701:23:59 instead of to 01:23:60.
438This has not yet been a practical problem, since no civil authority
439has observed such UTC offsets since leap seconds were
440introduced in 1972.
441.El
442.Pp
443Some interoperability problems are reader bugs that
444are listed here mostly as warnings to developers of readers.
445.Bl -bullet
446.It
447Some readers do not support negative timestamps.
448Developers of distributed applications should keep this
449in mind if they need to deal with pre-1970 data.
450.It
451Some readers mishandle timestamps before the first
452transition that has a nonnegative timestamp.
453Readers that do not support negative timestamps are likely to
454be more prone to this problem.
455.It
456Some readers mishandle time zone abbreviations like
457.Dq "\*-08"
458that contain
459.Dq "+" ,
460.Dq "\*-" ,
461or digits.
462.It
463Some readers mishandle UT offsets that are out of the
464traditional range of \-12 through +12 hours, and so do not
465support locations like Kiritimati that are outside this
466range.
467.It
468Some readers mishandle UT offsets in the range [\-3599, \-1]
469seconds from UT, because they integer-divide the offset by
4703600 to get 0 and then display the hour part as
471.Dq "+00" .
472.It
473Some readers mishandle UT offsets that are not a multiple
474of one hour, or of 15 minutes, or of 1 minute.
475.El
476.Sh SEE ALSO
477.Xr time 3 ,
478.Xr localtime 3 ,
479.Xr tzset 3 ,
480.Xr tzsetup 8 ,
481.Xr zic 8 ,
482.Xr zdump 8
483.Rs
484.%A A. Olson
485.%A P. Eggert
486.%A K. Murchison
487.%T "The Time Zone Information Format (TZif)"
488.%R RFC 8536
489.%D February 2019
490.%U https://datatracker.ietf.org/doc/html/rfc8536
491.%U https://doi.org/10.17487/RFC8536
492.Re
493