Skip to content

cycleZoned

cycleZoned(value: string, field: DateTimeCycleField, amount: number, options?: { round?: boolean; overflow?: "reject" | "constrain" | undefined; disambiguation?: "compatible" | "earlier" | "later" | "reject" | undefined; offset?: "reject" | "use" | "prefer" | "ignore" | undefined; }): string

Return a ZonedDateTime ISO string with field cycled by amount, wrapping at that field’s own min/max instead of carrying into the next larger field.

  • cycleZoned is not addZoned: cycling December’s month by +1 stays in the same year, and cycling hour 23 by +1 stays on the same day. Reach for addZoned for calendar/clock arithmetic; reach for cycleZoned when a single field (e.g. a datepicker segment) must stay isolated from the others.
  • Wrap bounds are computed the same way as cycleDateTime — plain local-field bounds (hour always 0–23, etc.), not DST-aware absolute-time bounds. The wrapped local time is then handed to setZoned, whose .with() call — via disambiguation and offset — resolves whatever DST edge case results (the wrapped local time landing in a gap or an overlap) exactly the way it resolves any other field-set call. This is deliberately simpler than deriving DST-aware wrap boundaries directly.
  • Compatibility: before 1.16.0 offset defaulted to "ignore". Pass { offset: "ignore" } to keep that resolution.
  • Returns "" for an invalid value, an invalid field, or an amount that is not a finite number.
ParameterTypeDescription
valuestringzoned ISO 8601 datetime string
fieldDateTimeCycleFieldthe field to cycle: “year” | “month” | “day” | “hour” | “minute” | “second” | “millisecond” | “microsecond” | “nanosecond”
amountnumbersigned amount to cycle by

options

optional settings for rounding the step and resolving the cycled wall-clock time

OptionTypeDefaultDescription
round?booleanfalseWhether to step to the next multiple of amount in the direction of its sign (up for a positive amount, down for a negative one) instead of adding amount to the current value. It is the next multiple, not the nearest one; see cycleDate and cycleTime for worked examples.
overflow?"reject" | "constrain" (Overflow)"constrain", Temporal’s default.What happens when the result names a day its month does not have, such as cycling month from 31 January to February. "constrain" clamps to the last valid day; "reject" returns "".
disambiguation?"compatible" | "earlier" | "later" | "reject" (Disambiguation)"compatible", Temporal’s default.How the new wall-clock time resolves when it falls in a DST gap or overlap and offset does not settle it. 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.
offset?"reject" | "use" | "prefer" | "ignore" (Offset)"prefer", Temporal’s default.How the source’s UTC offset is treated at the new wall-clock time, as in Temporal’s ZonedDateTime#with. "prefer" keeps it while it is still valid there (a repeated fall-back hour) and otherwise resolves through disambiguation; "ignore" always resolves through disambiguation. "use" keeps the offset even when that moves the wall clock, and "reject" returns "" when the offset is not valid for the new wall time.

zoned ISO 8601 string with field cycled, or "" on invalid input

import { cycleZoned } from "@northguild/gmt/zoned/calculate";
cycleZoned("2024-06-15T09:30:00-05:00[America/Chicago]", "hour", 1) // "2024-06-15T10:30:00-05:00[America/Chicago]"
output 

zoned/calculate/cycleZoned.ts