intervalCountZoned
Signature
Section titled “Signature”intervalCountZoned(start: string, end: string, unit: string): numberimport { intervalCountZoned } from "@northguild/gmt/zoned/interval";Count how many unit boundaries a zoned interval crosses.
- Counts local calendar boundaries touched by the half-open interval
[start, end)— distinct fromdiffZoned, which measures exact elapsed duration. - The end boundary is excluded: midnight to midnight two days later counts 2 days.
- A zero-length interval counts 1 when it sits mid-unit and 0 when it sits exactly on a unit boundary.
- 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.
- When
startandendcarry different time zones, boundaries are counted instart’s zone. - Weeks start on Monday (ISO 8601).
- Accepts singular or plural units (
"day"and"days"behave identically). - Accepts GMT 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 the tags mismatch, or either endpoint is bare ISO, it falls back to Gregorian/ISO rather than returning the sentinel (E7’s D5-zoned). The fallback is mandatory, not a convenience:ZonedDateTime.prototype.untilthrows across mismatched calendars for EVERYlargestUnit— verified, including"hour"and"nanosecond". - Returns
nullon invalid input (unparseable start/end,start > end, unsupported unit, leap-second strings).
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
start |
string |
ISO 8601 zoned datetime string for the interval start |
end |
string |
ISO 8601 zoned datetime string for the interval end |
unit |
string |
unit string — any DateTimeUnit |
Returns
Section titled “Returns”number of unit boundaries touched, or null on invalid input
Examples
Section titled “Examples”intervalCountZoned("2024-01-01T23:59:00+00:00[UTC]", "2024-01-02T00:01:00+00:00[UTC]", "day") // 2intervalCountZoned("2024-03-10T00:00:00-05:00[America/New_York]", "2024-03-11T00:00:00-04:00[America/New_York]", "hour") // 23 (spring forward)intervalCountZoned("2024-11-03T00:00:00-04:00[America/New_York]", "2024-11-04T00:00:00-05:00[America/New_York]", "hour") // 25 (fall back)intervalCountZoned("2024-01-01T00:00:00-05:00[America/New_York]", "2024-01-03T00:00:00+09:00[Asia/Tokyo]", "day") // 2 (counted in America/New_York)intervalCountZoned("2024-01-01T05:00:00+00:00[UTC]", "2024-01-01T05:00:00+00:00[UTC]", "day") // 1 (zero-length, mid-day)intervalCountZoned("2024-01-01T00:00:00+00:00[UTC]", "2024-01-01T00:00:00+00:00[UTC]", "day") // 0 (zero-length, on the boundary)intervalCountZoned("5784-01-01T00:00:00-04:00[u-ca=hebrew][America/New_York]", "5785-01-01T00:00:00-04:00[u-ca=hebrew][America/New_York]", "month") // 13 (Hebrew leap year; the ISO equivalent is 14)intervalCountZoned("invalid", "2024-01-02T00:00:00+00:00[UTC]", "day") // null