Record the zone designation on DateTime, so callers can read "CDT" #5

Closed
opened 2026-08-31 10:07:34 -05:00 by jeff · 0 comments
Owner

DateTime carries an offset and no zone designation, so there is no way
to get "CDT" out of a formatted date.

The z and zz sequences are not the answer to this and were settled
separately in 4a1476d. moment has no zone names at all -- its whole
implementation is

function getZoneAbbr() { return this._isUTC ? 'UTC' : ''; }
function getZoneName() { return this._isUTC ? 'Coordinated Universal Time' : ''; }

and _isUTC is a construction mode rather than an offset of zero, so
moment.parseZone("2024-03-15T09:30:00-05:00").format("z") is "UTC" too.
Real abbreviations come from moment-timezone, a separate package. Those
two sequences match moment and should stay as they are; making them mean
something better would shadow a moment sequence, which is the thing that
got the superscript ordinals removed in 2720786.

What is worth having is the field itself, which callers can read directly:

const local = zone.atInstant(instant);
// local.designation == "CDT"

It should be a fixed-size array and a length rather than a slice. As a
slice it would borrow the TZif bytes, so a DateTime could outlive its
zone and dangle, and it would stop being a self-contained value: the
tests compare DateTime with expectEqual throughout, and a slice
compares as pointer-plus-length, so two values with identical content from
different storage would compare unequal.

Six bytes is enough. Across the 1241 TZif files in tzdata 2026c there are
177 distinct designations and the longest is 5 characters (+0430,
+1345, and the rest of the numeric ones). Worth asserting on rather than
truncating silently.

TimeZone.atInstant and atTimestamp would fill it in from
TimeZone.typeAt, which already has it. Nothing else needs to change, and
the format oracle stays green because no sequence writes it.

`DateTime` carries an offset and no zone designation, so there is no way to get "CDT" out of a formatted date. The `z` and `zz` sequences are not the answer to this and were settled separately in 4a1476d. moment has no zone names at all -- its whole implementation is function getZoneAbbr() { return this._isUTC ? 'UTC' : ''; } function getZoneName() { return this._isUTC ? 'Coordinated Universal Time' : ''; } and `_isUTC` is a construction mode rather than an offset of zero, so `moment.parseZone("2024-03-15T09:30:00-05:00").format("z")` is "UTC" too. Real abbreviations come from moment-timezone, a separate package. Those two sequences match moment and should stay as they are; making them mean something better would shadow a moment sequence, which is the thing that got the superscript ordinals removed in 2720786. What is worth having is the field itself, which callers can read directly: const local = zone.atInstant(instant); // local.designation == "CDT" It should be a fixed-size array and a length rather than a slice. As a slice it would borrow the TZif bytes, so a `DateTime` could outlive its zone and dangle, and it would stop being a self-contained value: the tests compare `DateTime` with `expectEqual` throughout, and a slice compares as pointer-plus-length, so two values with identical content from different storage would compare unequal. Six bytes is enough. Across the 1241 TZif files in tzdata 2026c there are 177 distinct designations and the longest is 5 characters (`+0430`, `+1345`, and the rest of the numeric ones). Worth asserting on rather than truncating silently. `TimeZone.atInstant` and `atTimestamp` would fill it in from `TimeZone.typeAt`, which already has it. Nothing else needs to change, and the format oracle stays green because no sequence writes it.
jeff closed this issue 2026-08-31 11:57:47 -05:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jeff/zig-datetime#5
No description provided.