rfc-9636

The Time Zone Information Format (TZif)

A. Olson, P. Eggert, K. Murchison
date2024-10 streamIETF wgnon working group statusPROPOSED STANDARD pages45 canonicalhttps://www.rfc-editor.org/rfc/rfc9636 doi10.17487/RFC9636
This document specifies the Time Zone Information Format (TZif) for representing and exchanging time zone information, independent of any particular service or protocol. Two media types for this format are also defined. This document replaces and obsoletes RFC 8536.

obsoletes

Extracted elements (33)

design-rationale §3.3.2

The TZ string extension (version 3+) allowing hour values from -167 to 167 was added to support time zones like parts of Western Australia that observe DST with transitions occurring on the day before the official date — POSIX's unsigned 0-24 range cannot represent the required negative hour values.

design-rationale §3.2

The utoff field is forbidden from being -2^31 specifically to allow 32-bit clients to safely negate the value without integer overflow, a constraint that would otherwise be invisible from the protocol semantics alone.

design-rationale §3.2

Transition times SHOULD be at least -2^59 because this is the greatest negated power of 2 that predates the Big Bang, and avoiding earlier timestamps works around known TZif reader bugs relating to outlandishly negative timestamps.

design-rationale §3

Version 1 header and data block are retained in version 2+ files solely for backward compatibility with obsolescent readers. The version 1 block uses 32-bit timestamps limited to 1901-2038; the version 2+ block with 64-bit timestamps is what current readers should use, ignoring the version 1 block entirely.

design-rationale §3.2

Version 4's leap-second expiration time is encoded by repeating the final correction value in a terminal record whose occurrence field is the expiration timestamp, rather than adding a new field, to maintain the fixed-record-size structure and distinguish expiration from an actual leap second by the identical correction value.

interoperability-note §6

A TZDIST service MUST indicate TZif support by including 'application/tzif' in its capabilities response and MUST NOT advertise 'application/tzif-leap' without also advertising 'application/tzif'. TZDIST clients MUST use the HTTP Accept header to express their format preference.

http

interoperability-note §4

To save space, writers of version 2+ files MAY output a placeholder version 1 data block with all counts zero except typecnt=1 and charcnt=1; obsolescent version-1-only readers MUST interpret such files as lacking time changes and time zone abbreviations.

interoperability-note §4

Version 1 files are legacy and SHOULD NOT be generated because they do not support transition times after 2038. Version 2+ files use 64-bit timestamps capable of representing times approximately 292 billion years into the past or future.

interoperability-note §4

When a TZif file contains a leap-second table expiration time, readers SHOULD either refuse to process post-expiration timestamps or process them as if the expiration did not exist, possibly with an error indication, to reduce disagreement among implementations on far-future timestamps.

interoperability-note §4

Writers SHOULD generate the lowest version number sufficient for a file's data: generate version 4 only if the leap-second table expires or is truncated at the start; generate version 3 only if the TZ string extension is necessary; otherwise use version 2.

normative-requirement §3 MUST

All multi-octet integer values MUST be stored in network octet order (big-endian, high-order octet first) with all bits significant. Signed integer values MUST be represented using two's complement.

normative-requirement §3.2 MUST

Each correction after the first MUST differ from the previous by exactly +1 (positive leap second) or -1 (negative leap second), except in version 4 files where the last two records MAY share the same correction value, with the last record's occurrence denoting the leap-second table expiration time.

normative-requirement §3.3 MUST

If the TZ string in the footer is non-empty and one or more transitions appear in the v2+ data block, the TZ string MUST be consistent with the last v2+ transition — evaluating the TZ string at the last transition time must yield the same time type as specified in the last transition.

normative-requirement §3.1 MUST NOT

The typecnt field MUST NOT be zero, even in files with non-empty TZ strings but no transitions, because many TZif readers reject files with zero time types. The charcnt field also MUST NOT be zero.

normative-requirement §3.2 MUST NOT

The utoff field MUST NOT be -2^31 (to allow 32-bit clients to negate without overflow) and SHOULD be in the range [-89999, 93599] seconds (more than -25 hours and less than 26 hours).

normative-requirement §3.1 MUST

The version field MUST be one of: NUL (0x00) for version 1; '2' (0x32) for version 2, which MUST contain both v1 and v2+ header/data blocks plus a footer; '3' (0x33) for version 3, which additionally MAY use TZ string extensions; or '4' (0x34) for version 4, which additionally allows truncated or expiring leap-second tables.

normative-requirement §4 MUST

Time zone designations MUST consist of at least 3 and no more than 6 ASCII characters from the set of alphanumerics, '-', and '+'. A reader encountering other bytes SHOULD act as if the designation were replaced by a signed numeric UT offset string (e.g., '-10', '+0530').

normative-requirement §4 SHOULD

When a TZif file is used in a MIME message entity, it SHOULD be indicated by 'application/tzif-leap' if leap-second records are included, or 'application/tzif' (with leapcnt=0 in all headers) if they are not.

registry

normative-requirement §6.1 MUST

When truncating the end of a TZif file, the service MUST supply a last version 2+ transition at the truncation end point with an empty TZ string, and the time type of that last transition MUST be a placeholder for unspecified local time.

normative-requirement §6.1 MUST

When truncating the start of a TZif file, the service MUST supply a first version 2+ transition at the truncation start point, and time type 0 MUST be a placeholder indicating unspecified local time to unambiguously signal truncation.

privacy-consideration §8 MUST

Transmission of time zone 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.

privacy, tls

protocol-element §3.3.1

DST is considered in effect all year if its UT offset is less than (west of) standard time's offset, and it starts January 1 at 00:00 and ends December 31 at 24:00 minus the DST-to-standard difference, leaving no room for standard time. Example: 'XXX3EDT4,0/0,J365/23' represents perpetual UTC-4.

protocol-element §3.3.2

Version 3 and higher TZif files MAY use a TZ string extension allowing the hours part of transition times to be signed and range from -167 through 167, instead of POSIX's required unsigned 0 through 24. A file using this extension MUST be designated as version 3 or higher.

registry §9.2

This document registers the 'application/tzif-leap' media type for binary TZif data that includes leap-second records as necessary. Uses the same magic number as 'application/tzif'. Change controller is IETF.

registry

registry §9.1

This document registers the 'application/tzif' media type for binary TZif data without leap-second records (leapcnt MUST be zero). The magic number is 0x54 0x5A 0x69 0x66. Change controller is IETF.

registry

security-consideration §7

All counts in TZif objects should be validated when processing to guard against references past the end of the object; the format uses counted arrays throughout.

security

security-consideration §7 MUST

TZif contains no executable code and no extensible areas for such code, but it provides no integrity protection. Since time zone data is used in critical applications, integrity protection MUST be provided externally, and TZif data transmitted over a public channel MUST be protected with a security layer such as TLS.

security, tls

state-machine §3.2

Local time is determined by transition time state: timestamps before the first transition use time type 0; timestamps from each transition up to (but not including) the next use the type indexed by the transition type array; timestamps after the last transition use the footer TZ string if present and non-empty, otherwise are unspecified. A designation of '-00' marks an unspecified local time.

wire-format §3.2

Each local time type record is 6 octets: 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.

wire-format §3.2

Leap-second records are 8 octets in v1 (4-octet occur + 4-octet corr) and 12 octets in v2+ (8-octet occur + 4-octet corr). The occur field is a UNIX leap time value for the correction event; the corr field is the signed LEAPCORR value on or after that occurrence.

wire-format §3.2

The TZif data block contains seven variable-length elements in order: transition times (timecnt × TIME_SIZE), transition types (timecnt × 1 octet), local time type records (typecnt × 6 octets), time zone designations (charcnt octets), leap-second records (leapcnt × (TIME_SIZE + 4)), standard/wall indicators (isstdcnt octets), and UT/local indicators (isutcnt octets). TIME_SIZE is 4 in v1 and 8 in v2+.

wire-format §3.3

The TZif footer (version 2+ only) is delimited by two ASCII newline characters (0x0A) surrounding a POSIX TZ environment variable string. The TZ string MUST NOT contain NUL octets, MUST NOT be NUL-terminated, and SHOULD NOT begin with ':'.

wire-format §3.1

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.

json