Skip to content

addZoned

addZoned(value: string, units: Partial<Record<keyof DurationLike, number>>, optionsArg?: { disambiguation?: "compatible" | "earlier" | "later" | "reject" | undefined; overflow?: "reject" | "constrain" | undefined; }): string

Add a temporal amount to a zoned ISO 8601 datetime string and return a zoned ISO 8601 string.

  • Uses Temporal.ZonedDateTime.add to add duration.
  • Validates duration units and values.
  • Accepts an RFC 9557 calendar-annotated zoned string (as Temporal.ZonedDateTime#toString() and convertZonedToCalendar write it, e.g. "2024-02-24T14:30:00-05:00[America/New_York][u-ca=hebrew]"), not just a bare ISO string (E7, issue #152). Calendar-unit arithmetic (“add 1 month”) resolves against that calendar (a Hebrew leap month, an Ethiopic Pagumen) and the DST rules of the zone, in one operation: Hebrew Adar I 15 in America/New_York +1 month moves both the month (Adar I -> Adar II) and the offset (-05:00 -> -04:00). The result carries the same calendar annotation. A bare ISO string is the "iso8601" calendar and returns a bare ISO string.
  • Compatibility: since 1.16.0 calendar strings are RFC 9557 (ISO digits, the [u-ca=<id>] annotation after the zone, canonical calendar ids); see isValidCalendarZonedDateTime.
  • Follows Temporal’s AddZonedDateTime: the date portion of the duration (years, months, weeks, days) moves the wall-clock date, then the time portion (hours and smaller) is added in exact time. disambiguation applies ONLY to the intermediate wall-clock date-time after the date portion, exactly as Temporal’s GetEpochNanosecondsFor resolves it. It never re-resolves the exact-time result.
  • Compatibility: before 1.16.0 a date portion landing in a spring-forward gap was always moved forward, whatever disambiguation said, so “earlier” matched “compatible” and “reject” did not fail. Pass “compatible” (or omit it) to keep the forward result.
  • Compatibility: before 1.16.0 a non-”compatible” disambiguation re-resolved the final wall clock (so + { minutes: 10 } from 01:30-05:00 with “earlier” returned 01:40-04:00, 50 minutes earlier in exact time). To get that value, re-resolve the result’s wall clock: setZoned(result, { hour, minute, second }, { disambiguation, offset: "ignore" }).
  • There is no offset option (removed in 1.16.0): the intermediate wall clock is resolved from a plain date-time, which has no UTC offset for it to act on (Temporal PlainDateTime#toZonedDateTime reads only disambiguation).
  • Returns "" for invalid input.
ParameterTypeDescription
valuestringISO 8601 zoned datetime string, optionally calendar-annotated
unitsPartial<Record<keyof DurationLike, number>>Partial<Record<DateTimeDurationUnit, number>> object specifying units to add

optionsArg

optional settings for resolving a DST gap or overlap and an out-of-range date

OptionTypeDefaultDescription
disambiguation?"compatible" | "earlier" | "later" | "reject" (Disambiguation)"compatible", Temporal’s default.How the intermediate wall-clock date-time, reached after the date portion of the duration is applied, resolves when it falls in a DST gap or overlap. In a fall-back overlap "compatible" and "earlier" take the earlier instant and "later" the later one; in a spring-forward gap "compatible" and "later" move the wall clock forward by the gap length and "earlier" back by it. "reject" returns "" for both, and a time-only duration ignores the option.
overflow?"reject" | "constrain" (Overflow)"constrain", Temporal’s default.What happens when the result names a day its month does not have, such as adding 1 month to 31 January. "constrain" clamps to the last valid day; "reject" returns "".

zoned ISO 8601 string on success, or "" on invalid input

import { addZoned } from "@northguild/gmt/zoned/calculate";
addZoned("2024-02-29T14:30:45.123-05:00[America/New_York]", { days: 1 }) // "2024-03-01T14:30:45.123-05:00[America/New_York]"
output 

zoned/calculate/addZoned.ts