Skip to content

intervalCountZoned

intervalCountZoned(start: string, end: string, unit: string): number | null

Count how many unit boundaries a zoned interval crosses.

  • Counts local calendar boundaries touched by the half-open interval [start, end) — distinct from diffZoned, which measures exact elapsed duration.
  • The end boundary is excluded: midnight to midnight two days later counts 2 days.
  • A zero-length interval (start === end) returns 0: the empty [start, start) holds no instant, so it touches no unit (before 1.16.0 it counted 1 when mid-unit).
  • DST-aware: a local day that springs forward counts 23 hour boundaries and one that falls back counts 25. A local day whose midnight is skipped entirely starts at 01:00.
  • A fixed 24-hour span touches 25 local hour boundaries in zones offset by :30/:45.
  • Counts the real local buckets floorToZone/bucketRange walk: a bucket shorter than its unit still counts once (Pacific/Chatham’s 15-minute 03:00 hour on its spring-forward), and a local day the zone deleted counts not at all (Pacific/Apia’s 2011-12-30).
  • The count equals bucketRange(...).length wherever bucketRange is within its 10,000-bucket cap. Counting has its own, separate cap of 10,000 zone transitions, so it keeps answering past bucketRange’s: two years by hour counts 17,544 while bucketRange returns [].
  • Returns null when the span crosses more than 10,000 zone transitions.
  • When start and end carry different time zones, boundaries are counted in start’s zone.
  • Weeks start on Monday (ISO 8601).
  • Accepts singular or plural units ("day" and "days" behave identically).
  • Accepts RFC 9557 calendar-annotated zoned strings (as produced by convertZonedToCalendar) as well as bare ISO ones — E7 (issue #152). When BOTH endpoints carry the same calendar tag the measurement is made in that calendar. When they name different calendars (a bare ISO string names iso8601) the result is null in every unit, "hour" included, as ZonedDateTime.prototype.until throws when TC39 CalendarEquals is false (before 1.16.0 it was measured in ISO).
  • Returns null on invalid input (unparseable start/end, start > end, unsupported unit, leap-second strings).
  • 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.
ParameterTypeDescription
startstringISO 8601 zoned datetime string for the interval start
endstringISO 8601 zoned datetime string for the interval end
unitstringunit string — any DateTimeUnit

number of unit boundaries touched, or null on invalid input

import { intervalCountZoned } from "@northguild/gmt/zoned/interval";
intervalCountZoned("2024-01-01T23:59:00+00:00[UTC]", "2024-01-02T00:01:00+00:00[UTC]", "day") // 2
output 

zoned/interval/intervalCountZoned.ts