DXN's dates and times as text and as numbers (DXN.md §1.2, §1.5, §2.2;
Jan, 2026-10-20): one place that reads and writes the ISO 8601 strings
under @date, @time, @datetime, @local-datetime and @duration,
and turns a value into the nanoseconds .dxnb holds and back.
A time, datetime or local datetime that fits a microsecond is Elixir's
own Time, DateTime or NaiveDateTime; one finer is a
Dextrin.Nanos. A datetime keeps its offset: Z is UTC, -00:00
(an unknown offset) is refused.
Summary
Functions
The datetime epoch_nanos after the epoch, written at offset_minutes.
A datetime as nanoseconds since the epoch and its offset in minutes.
The text of a datetime: the wall clock at its offset, then Z or ±HH:MM.
P...: the fields in DXN.md §2.3's order, absent and zero ones left out, PT0S when none is left (§1.5).
The local date-time nanos after 1970-01-01T00:00:00.
A local date-time as nanoseconds since 1970-01-01T00:00:00 on the wall clock.
The text of a local date-time: YYYY-MM-DDTHH:MM:SS and the fraction.
An offset in minutes as a datetime writes it: Z, or ±HH:MM.
The date text writes, YYYY-MM-DD.
The datetime text writes: a date, T, a time, and an offset, Z or
±HH:MM.
The duration text writes, P... (ISO 8601, a field's sign its own,
seconds with up to nine fraction digits), as Dextrin.Duration's
fields.
The local date-time text writes: a date, T and a time, no offset.
The time text writes, HH:MM:SS and up to nine fraction digits.
A date, time, datetime, local date-time or duration as its tag and ISO
8601 text, {"date", "2026-10-20"}, or :error for any other value --
what the printer and the canonical form both write.
The time nanos after midnight.
A time's nanoseconds since midnight.
HH:MM:SS, then the fraction with trailing zeros removed (DXN.md §1.5).
Functions
@spec datetime_from(integer(), integer()) :: DateTime.t() | Dextrin.Nanos.t()
The datetime epoch_nanos after the epoch, written at offset_minutes.
@spec datetime_parts(DateTime.t() | Dextrin.Nanos.t()) :: {integer(), integer()}
A datetime as nanoseconds since the epoch and its offset in minutes.
The text of a datetime: the wall clock at its offset, then Z or ±HH:MM.
@spec duration_text(Dextrin.Duration.t()) :: String.t()
P...: the fields in DXN.md §2.3's order, absent and zero ones left out, PT0S when none is left (§1.5).
@spec local_from(integer()) :: NaiveDateTime.t() | Dextrin.Nanos.t()
The local date-time nanos after 1970-01-01T00:00:00.
@spec local_nanos(NaiveDateTime.t() | Dextrin.Nanos.t()) :: integer()
A local date-time as nanoseconds since 1970-01-01T00:00:00 on the wall clock.
The text of a local date-time: YYYY-MM-DDTHH:MM:SS and the fraction.
An offset in minutes as a datetime writes it: Z, or ±HH:MM.
The date text writes, YYYY-MM-DD.
@spec parse_datetime(String.t()) :: {:ok, DateTime.t() | Dextrin.Nanos.t()} | :error
The datetime text writes: a date, T, a time, and an offset, Z or
±HH:MM.
@spec parse_duration(String.t()) :: {:ok, Dextrin.Duration.t()} | :error
The duration text writes, P... (ISO 8601, a field's sign its own,
seconds with up to nine fraction digits), as Dextrin.Duration's
fields.
@spec parse_local(String.t()) :: {:ok, NaiveDateTime.t() | Dextrin.Nanos.t()} | :error
The local date-time text writes: a date, T and a time, no offset.
@spec parse_time(String.t()) :: {:ok, Time.t() | Dextrin.Nanos.t()} | :error
The time text writes, HH:MM:SS and up to nine fraction digits.
A date, time, datetime, local date-time or duration as its tag and ISO
8601 text, {"date", "2026-10-20"}, or :error for any other value --
what the printer and the canonical form both write.
@spec time_from_nanos(non_neg_integer()) :: Time.t() | Dextrin.Nanos.t()
The time nanos after midnight.
@spec time_nanos(Time.t() | Dextrin.Nanos.t()) :: non_neg_integer()
A time's nanoseconds since midnight.
@spec time_text(non_neg_integer()) :: String.t()
HH:MM:SS, then the fraction with trailing zeros removed (DXN.md §1.5).