Skip to content

compareDurations

compareDurations(a: string, b: string, options?: { relativeTo?: DurationRelativeTo; }): number | null

Compare two ISO 8601 duration strings by length.

  • Uses Temporal.Duration.compare: -1 when a is shorter, 0 when equal, 1 when a is longer.
  • Equality is by length, not by spelling — “PT60M” and “PT1H” compare 0, as do “P1D” and “PT24H” absent a relativeTo.
  • Field-identical durations compare 0 without a relativeTo (“P1Y” vs “P1Y”), since Temporal checks identity first. Note the asymmetry with addDuration/subtractDuration (A2): Temporal.Duration.compare does accept relativeTo, while .add/.subtract do not, so calendar-unit durations are comparable here even though they cannot be combined there. totalDuration and normalizeDuration (A3) carry the same relativeTo rule as this function.
  • The anchor genuinely decides the answer rather than merely unblocking it: “P1M” is longer than “P30D” relative to January (31 days) and shorter relative to February 2024 (29).
  • A zoned relativeTo string resolves its wall time with disambiguation “compatible” and offset “reject”, as Temporal does: an ambiguous wall time takes the earlier instant, a nonexistent one the later instant, and an offset that does not match the zone returns null. Pass an explicit offset to pick the other reading of an ambiguous wall time.
  • A relativeTo string is ISO 8601 extended format before its first [: a date, a date-time, or with a time zone annotation a zoned date-time (<date>T<time>, then nothing, Z or ±HH:MM). Basic format ("20240101"), a space or lower-case t separator, a lower-case z, a UTC offset without a zone and a zoned date without a time are invalid.
  • A relativeTo string takes a calendar in RFC 9557 form, as convertDateToCalendar and convertZonedToCalendar write it: ISO digits and a [u-ca=<id>] annotation, after the zone for a zoned string ("2024-02-24[u-ca=hebrew]", "2024-02-24T00:00:00-05:00[America/New_York][u-ca=hebrew]"). The annotations are read as Temporal reads them: the critical flag and the id’s letter case are accepted, elective unknown annotations are ignored, the first u-ca names the calendar, and a string with a time zone annotation is zoned. An unknown critical annotation, a critical duplicate calendar, a calendar before the zone, an unsupported calendar and a leap second in any spelling return null. Compatibility: before 1.16.0 the digits were read as the calendar’s own year, month and day.
  • Returns null if either operand is not a valid ISO 8601 duration string, or relativeTo is invalid.
ParameterTypeDescription
astringISO 8601 duration string
bstringISO 8601 duration string

options

The anchor calendar units are measured from

OptionTypeDefaultDescription
relativeTo?DurationRelativeToNone. Days are 24 hours, and two different durations of which one has a year, month or week return null.The date or zoned date-time both durations are measured from. It is required when either side has a year, month or week and the two differ. With a zoned value, days follow that zone’s clock changes, so across a spring-forward transition "P1D" is 23 hours and compares shorter than "PT24H".

-1, 0, or 1, or null on invalid input

import { compareDurations } from "@northguild/gmt/duration/compare";
compareDurations("PT1H", "PT30M") // 1
output 

duration/compare/compareDurations.ts