Skip to content

formatDuration

formatDuration(value: string, locale?: string | string[], options?: FormatDurationOptions): string

Render an ISO 8601 duration string as a locale-aware, human-readable string.

  • Uses Temporal.Duration.from to parse, then Intl.NumberFormat({ style: “unit” }) to render each nonzero year/month/week/day/hour/minute/second component with correct per-locale unit labels and pluralization, joined via Intl.ListFormat.
  • Sub-second components (milliseconds/microseconds/nanoseconds) are folded into the seconds component as an exact fractional value (e.g. “PT1.5S” -> one “1.5 seconds” component). Every digit the duration holds is rendered, up to 9 fraction digits and seconds up to 2^53 - 1: nothing is rounded, so a non-zero duration never prints “0 seconds” and “PT9007199254740991.999999999S” renders exactly.
  • To render fewer fraction digits, round the string first with parseDuration, e.g. { smallestUnit: “millisecond”, roundingMode: “halfExpand” } for the 3-digit output this function produced before (parseDuration’s default roundingMode “trunc” drops the digits).
  • A zero-length duration (e.g. “PT0S”) always renders its seconds component (“0 seconds”) even when zero components are left out, since omitting every component would otherwise produce "".
  • Negative durations render each component with a leading ”-” (Temporal stores every field of a negative duration as a negative number).
  • Returns "" for invalid input: non-string value or invalid duration string.
ParameterTypeDescription
valuestringISO 8601 duration string
localestring | string[]BCP 47 locale tag, passed to Intl.NumberFormat/Intl.ListFormat; system default if omitted, or a preference list of tags (ECMA-402)

options

How unit names are written, and whether zero components are shown

How formatDuration writes unit names, and whether it writes zero components.

import type { FormatDurationOptions } from "@northguild/gmt";
OptionTypeDefaultDescription
style?"long" | "short" | "narrow""long"The length of each unit name, as the unitDisplay of Intl.NumberFormat: "long" (“90 minutes”), "short" (“90 min”) or "narrow" (“90m”). The components are joined as a long list (“1 day, 2 hours, and 30 minutes”) for "long" and as a short list otherwise.
zero?booleanfalseWhether components that are zero are written. false leaves them out, so "P1DT0H30M" reads “1 day and 30 minutes”; true writes every unit from years to seconds.

human-readable rendering of the duration, or "" on invalid input

import { formatDuration } from "@northguild/gmt/duration/format";
formatDuration("P1DT2H30M", "en-US") // "1 day, 2 hours, and 30 minutes"
output 

duration/format/formatDuration.ts