SpanA mixed-unit, calendar-aware duration: years, months, weeks, days, and time units held as SEPARATE fields — "1 month" stays 1 month until it meets a date, where Date/DateTime arithmetic applies it correctly (end-of-month clamping, DST). Contrast Duration, which is a fixed length of time.
Parse ISO 8601 ('P1Y2M3D') or the friendly form ('1y 2mo'); combine with +: / -: field-wise. Equality is FIELDWISE: 1h ≠ 60m — whether they're the same depends on a calendar, so Span refuses to guess (and has no <: for the same reason).
(Span.parse:'P1Y2M').s "* -> 1y 2mo ((Span.years:1) + (Span.months:2)).iso8601 "* -> 'P1Y2M'
The calendar span, as an ISO 8601 duration ('P1Y2M'; Span.parse: reads it back).
A Span of exactly n calendar days (may be negative). A calendar day is not always 24 hours — applying it across a DST change keeps the wall-clock time.
(Span.days:3).iso8601 "* -> 'P3D'
A Span of exactly n hours (may be negative).
A Span of exactly n minutes (may be negative).
A Span of exactly n calendar months (may be negative).
The Span an ISO 8601 duration ('P1Y2M3DT4H') or friendly form ('1y 2mo') denotes. Not parseable → ValueError.
(Span.parse:'P1Y2M3D').days "* -> 3 (Span.parse:'1h 30m').minutes "* -> 30
A Span of exactly n seconds (may be negative).
A Span of exactly n weeks (may be negative).
A Span of exactly n calendar years (may be negative).
The empty Span — every unit zero; the identity for +:.
The field-wise sum: each unit adds independently — 1y + 2mo is 1y 2mo, and 1h + 60m stays 1h 60m (units never convert; without a calendar there is no correct conversion). Per-unit overflow throws an ArithmeticError.
((Span.years:1) + (Span.months:2)).s "* -> 1y 2mo
The field-wise difference — +: with every unit of the argument negated.
FIELDWISE equality: every unit must match — 1h is not 60m (whether they name the same length depends on a calendar, so Span refuses to guess). A non-Span argument is simply unequal.
(Span.hours:1) == (Span.minutes:60) "* -> false (Span.hours:1) == (Span.hours:1) "* -> true
The equivalent fixed Duration — defined only for a span of pure time units. A span with calendar units (years/months/weeks/days) has no fixed length, so it throws a ValueError rather than guessing.
(Span.parse:'PT1H30M').asDuration.asSeconds "* -> 5400.0
The days field alone.
The hours field alone.
The canonical ISO 8601 duration string, for serialization.
((Span.years:1) + (Span.hours:2)).iso8601 "* -> 'P1YT2H'
The microseconds field alone.
The milliseconds field alone.
The minutes field alone.
The months field alone.
The nanoseconds field alone.
The same units with every sign flipped.
(Span.parse:'P1Y2M').negate.iso8601 "* -> '-P1Y2M'
A human-readable rendering (jiff's friendly form). For a machine-readable form use iso8601.
(Span.parse:'P1Y2M3D').s "* -> 1y 2mo 3d
The seconds field alone — fractional seconds parse into the millisecond/microsecond/nanosecond fields, not here.
The weeks field alone.
The years field alone (no conversion from other units).