jiff::tz

Module posix

Source
Expand description

Provides a parser for POSIX’s TZ environment variable.

NOTE: Sadly, at time of writing, the actual parser is in src/shared/posix.rs. This is so it can be shared (via simple code copying) with proc macros like the one found in jiff-tzdb-static. The parser populates a “lowest common denominator” data type. In normal use in Jiff, this type is converted into the types defined below. This module still does provide the various time zone operations. Only the parsing is written elsewhere.

The TZ environment variable is most commonly used to set a time zone. For example, TZ=America/New_York. But it can also be used to tersely define DST transitions. Moreover, the format is not just used as an environment variable, but is also included at the end of TZif files (version 2 or greater). The IANA Time Zone Database project also documents the TZ variable with a little more commentary.

Note that we (along with pretty much everyone else) don’t strictly follow POSIX here. Namely, TZ=America/New_York isn’t a POSIX compatible usage, and I believe it technically should be TZ=:America/New_York. Nevertheless, apparently some group of people (IANA folks?) decided TZ=America/New_York should be fine. From the IANA theory.html documentation:

It was recognized that allowing the TZ environment variable to take on values such as ‘America/New_York’ might cause “old” programs (that expect TZ to have a certain form) to operate incorrectly; consideration was given to using some other environment variable (for example, TIMEZONE) to hold the string used to generate the TZif file’s name. In the end, however, it was decided to continue using TZ: it is widely used for time zone purposes; separately maintaining both TZ and TIMEZONE seemed a nuisance; and systems where “new” forms of TZ might cause problems can simply use legacy TZ values such as “EST5EDT” which can be used by “new” programs as well as by “old” programs that assume pre-POSIX TZ values.

Indeed, even musl subscribes to this behavior. So that’s what we do here too.

Note that a POSIX time zone like EST5 corresponds to the UTC offset -05:00, and GMT-4 corresponds to the UTC offset +04:00. Yes, it’s backwards. How fun.

§IANA v3+ Support

While this module and many of its types are directly associated with POSIX, this module also plays a supporting role for TZ strings in the IANA TZif binary format for versions 2 and greater. Specifically, for versions 3 and greater, some minor extensions are supported here via IanaTz::parse. But using PosixTz::parse is limited to parsing what is specified by POSIX. Nevertheless, we generally use IanaTz::parse everywhere, even when parsing the TZ environment variable. The reason for this is that it seems to be what other programs do in practice (for example, GNU date).

§no-std and no-alloc support

A big part of this module works fine in core-only environments. But because core-only environments provide means of indirection, and embedding a PosixTimeZone into a TimeZone without indirection would use up a lot of space (and thereby make Zoned quite chunky), we provide core-only support principally through a proc macro. Namely, a PosixTimeZone can be parsed by the proc macro and then turned into static data.

POSIX time zone support isn’t explicitly provided directly as a public API for core-only environments, but is implicitly supported via TZif. (Since TZif data contains POSIX time zone strings.)

Type Aliases§