Skip to content

totalDuration

totalDuration(value: string, unit: keyof DurationLike | DateTimeUnit, options?: { relativeTo?: DurationRelativeTo; }): number | null

Express an ISO 8601 duration as a single fractional total in one unit.

  • Uses Temporal.Duration.from and .total — the whole duration is converted, so totalDuration(“P1DT2H30M”, “hours”) is 26.5, not the 2 that getDurationUnit reads.
  • Which function to use: totalDuration takes an ISO 8601 duration string. totalUnits takes a unit object of exact units, such as { minutes: 15 }. durationFromUnits turns a unit object into the duration string this function takes. To total a calendar amount written as a unit object, such as { months: 1 }, pass the result of durationFromUnits here with relativeTo.
  • The result is fractional, not rounded: totalDuration(“P1DT2H30M”, “days”) is 1.1041666666666667. Round it yourself, or reach for normalizeDuration instead. It is a JavaScript number, so a total past 2^53 is the nearest double.
  • The calendar-unit rule of relativeTo is the same one normalizeDuration (A3) carries; addDuration/subtractDuration (A2) have it worse still, since Temporal gives them no relativeTo option at all.
  • The requested-unit half of that rule bites even on day/time-only input: “P1DT2H30M” has no calendar component, yet totalDuration(“P1DT2H30M”, “weeks”) is still null — a week is a calendar quantity to Temporal regardless of what it is being measured from.
  • 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.
  • unit accepts the plural or singular name ("hours" or "hour"), as Temporal does.
  • Returns null on a non-duration value, an invalid unit, or an invalid relativeTo.
ParameterTypeDescription
valuestringISO 8601 duration string
unitkeyof DurationLike | DateTimeUnitDateTimeDurationUnit to total into (“years” | “months” | “weeks” | “days” | “hours” | “minutes” | “seconds” | “milliseconds” | “microseconds” | “nanoseconds”, or the singular name)

options

The anchor calendar units are measured from

OptionTypeDefaultDescription
relativeTo?DurationRelativeToNone. Days are 24 hours, and a duration or unit that involves a year, month or week returns null.The date or zoned date-time the duration is measured from. It is required whenever a year, month or week is involved, as the unit asked for or as a nonzero field of the duration. With a zoned value, days follow that zone’s clock changes, so a day spanning a spring-forward transition totals 23 hours.

the fractional total in unit, or null on invalid input

import { totalDuration } from "@northguild/gmt/duration/calculate";
totalDuration("P1DT2H30M", "hours") // 26.5
output 

duration/calculate/totalDuration.ts