The Time Zone Information Format (TZif)
obsoleted by
- rfc-9636 — The Time Zone Information Format (TZif)
Extracted elements (30)
The utoff field MUST NOT equal -2**31 so that 32-bit clients can negate the value without integer overflow. The SHOULD range of [-89999, 93599] is chosen to accommodate implementations already supporting the POSIX range of [-24:59:59, 25:59:59].
Transition times SHOULD be at least -2**59 because timestamps earlier than that, while valid, have triggered bugs in deployed TZif readers. -2**59 is described as 'the greatest negated power of 2 that predates the Big Bang.'
typecnt MUST NOT be zero even when the TZ string makes local time type records unnecessary, because many TZif readers reject files with zero time types. This is an explicit concession to deployed reader behavior rather than a principled constraint.
Version 1 data blocks are retained in version 2+ files solely for backward compatibility with obsolete readers; the 32-bit transition times limit coverage to 1901–2038. Implementations SHOULD ignore version 1 data when reading version 2+ files.
Implementations SHOULD generate a version 3 file if TZ string extensions are necessary to accurately model transitions; otherwise version 2 SHOULD be generated. The version 1 data SHOULD be a contiguous sub-sequence of version 2+ data to help old readers agree on timestamps within the overlap.
Some readers mishandle TZif files where the DST UT offset is less than the standard UT offset (e.g., Ireland's IST/GMT pattern). A workaround is to swap the standard and DST designations, which preserves UT offsets and abbreviations at the cost of mislabeling which period is DST.
Some version 2 readers cannot parse version 3 TZ string extensions (signed hours, year-round DST). A partial workaround is to output additional explicit transitions so that only far-future timestamps are mishandled.
Time zone designations SHOULD consist of 3–6 ASCII alphanumeric characters plus '-' and '+'. Non-ASCII characters and abbreviations outside this range are not recommended due to widespread reader incompatibilities documented in Appendix A.
Version 1 files are considered a legacy format and SHOULD NOT be generated, as they cannot represent transition times after 2038. When reading version 2 or 3 files, implementations SHOULD ignore the version 1 header and data block except to skip over them.
A standard/wall indicator MUST be set to 1 (standard) if the corresponding UT/local indicator is set to 1 (UT). If isstdcnt or isutcnt is zero, all transition times are assumed to be wall time or local time respectively.
All multi-octet integer values MUST be stored in network octet order (big-endian, high-order octet first), and signed integer values MUST be represented using two's complement.
The first leap-second correction value MUST be either 1 or -1, and correction values in adjacent leap-second records MUST differ by exactly 1. The first occurrence value, if present, MUST be nonnegative, and each subsequent occurrence MUST be at least 2419199 greater than the prior value.
The TZ string in the footer, if nonempty and one or more transitions appear in the version 2+ data, MUST be consistent with the last version 2+ transition — evaluating the TZ string at the last transition time must yield the same time type as specified in that transition.
The utoff field MUST NOT be -2**31 and SHOULD be in the range [-89999, 93599] seconds (more than -25 hours and less than 26 hours), to support both 32-bit negation without overflow and the POSIX-required range.
The version field MUST be one of 0x00 (version 1), '2' (0x32), or '3' (0x33). Version 1 files MUST NOT contain a version 2+ header, data block, or footer; versions 2 and 3 MUST contain the version 1 block, a version 2+ block, and a footer.
Transition times MUST appear in strictly ascending order. Each transition time SHOULD be at least -2**59 to avoid known reader bugs with outlandishly negative timestamps.
typecnt MUST NOT be zero, and charcnt MUST NOT be zero. The count includes the trailing NUL octet of the last time zone designation string.
Transmission of TZif data over an insecure channel could leak the past, current, or future location of a device or user. TZif data transmitted over a public communications channel MUST be protected with a confidentiality layer such as TLS.
Local time for timestamps before the first transition is specified by time type 0. Local time after the last transition is specified by the TZ string in the footer if present and nonempty; otherwise it is unspecified. If there are no transitions, time type 0 applies unless a TZ string is present.
Version 2 and 3 files contain a complete version 1 block (for backward compatibility) followed by a second 44-octet header and 64-bit data block followed by a footer. The 64-bit transition times can represent approximately 292 billion years into the past or future.
Version 3 TZif files MAY extend POSIX TZ strings in two ways: transition time hours may be signed and range from -167 to 167 (vs. POSIX's 0–24), and DST can be specified as in effect all year (start January 1 at 00:00, end December 31 at 24:00 plus the DST offset).
This document registers the 'application/tzif-leap' media type for TZif files that include leap-second records as necessary. A TZDIST service MUST NOT advertise 'application/tzif-leap' without also advertising 'application/tzif'.
This document registers the 'application/tzif' media type for TZif files that do not include leap-second records (leapcnt in all headers MUST be zero). The magic number is the first 4 octets 0x54 0x5A 0x69 0x66.
TZif contains counted arrays; all count fields MUST be validated when processing a file to guard against references past the end of the object. The format contains no executable code and defines no extensible areas that could carry such code.
TZif provides no confidentiality or integrity protection. While time zone data is normally public and does not require confidentiality, integrity protection may be required for critical applications and must be provided by an external mechanism.
Each local time type record is a 6-octet structure: a 4-octet signed integer utoff (seconds to add to UT for local time), a 1-octet isdst flag (0 or 1), and a 1-octet desigidx (zero-based index into the time zone designations array).
Leap-second records are 8 octets in version 1 (4-octet occur + 4-octet corr) and 12 octets in version 2+ (8-octet occur + 4-octet corr). The occur field is a UNIX leap time value; corr is the cumulative LEAPCORR value on or after the occurrence.
The TZif data block contains seven variable-length elements in order: transition times (timecnt × TIME_SIZE), transition types (timecnt × 1), local time type records (typecnt × 6), time zone designations (charcnt octets), leap-second records (leapcnt × (TIME_SIZE+4)), standard/wall indicators (isstdcnt), and UT/local indicators (isutcnt). TIME_SIZE is 4 in version 1 and 8 in version 2+.
The TZif footer, present only in version 2 and 3 files, consists of an ASCII newline (0x0A), a variable-length POSIX TZ string (possibly empty, no NUL octets, SHOULD NOT begin with ':'), and a closing newline.
The TZif header is a fixed 44-octet structure beginning with the 4-octet ASCII magic 'TZif' (0x54 0x5A 0x69 0x66), followed by a 1-octet version field, 15 reserved octets, and six 4-octet unsigned integer count fields: isutcnt, isstdcnt, leapcnt, timecnt, typecnt, and charcnt.