GNU `date` accepts every letter `a`-`y` as a military time zone, and all
of them are already in our table except `j`. It is missing because it is
the one letter that does not denote a fixed offset: `j` means *local
time*, so it cannot be expressed as an `Offset` at all.
$ TZ=America/New_York date -d '8j' # 08:00 -0400
$ TZ=America/New_York date -d '2026-01-01 j' # 00:00 -0500
$ TZ=America/New_York date -d '8z' # 04:00 -0400
Because it follows the base zone's DST rules rather than pinning an
offset, it is represented as its own item and recorded on the builder as
a flag rather than as an offset.
- `j` parses as its own item, so `8j`, `8 j`, `j 8` and `8J` all work.
- It is still a time zone item, so `8j utc`, `8 utc j` and `8 j j` are
rejected as a repeated zone, matching GNU.
- The whole alphabetic word is consumed before comparing, so `8jan` still
parses as a date and `jj` is rejected rather than matching a `j` prefix.
- Unknown words remain errors: `8foo` still fails, as it does in GNU.
Verified against GNU coreutils 9.4: all 26 letters `a`-`z` now resolve to
the same instant as GNU, in both a DST and a non-DST base zone.
A fixed offset (e.g. the "UTC" keyword) was applied after relative
items, so "1970/01/01 UTC N seconds" added N seconds to a local
wall-clock that could drift across a DST boundary before being
re-anchored at the offset, yielding an instant off by the DST gap.
Anchor the offset first, then apply relative items.
Fixesuutils/coreutils#12555.
Replace hand-rolled format_offset_colon / format_for_assert helpers
with the new Display impls. Replace local expect_in_range_datetime
test helpers with ParsedDateTime::expect_in_range().
NOTE: This commit only adds tests as the implementation was already
working correctly. These tests document and verify the expected
behavior for the embedded timezone edge case referenced in Debian
bug #851934.
In GNU if using date with relative Months with the -d flag and the target Month does not have the source day (for example 31) GNU overflows the diff in days.