UNPKG

@burglekitt/gmt

Version:

Temporal-based date and time utilities with timezone support and polyfill integration

50 lines (49 loc) 2.61 kB
import { Temporal } from "@js-temporal/polyfill"; import { isValidDateTimeUnit } from "../../plain/validate/index.js"; import { startOfZoned } from "../calculate/startOfZoned.js"; import { isValidZonedDateTime } from "../validate/index.js"; /** * Compare two zoned ISO datetime strings for equality at a given unit. * * - Equality is measured on each value's own local wall-clock fields (its own * time zone), not on the underlying instant or time zone identifier — the * same instant can be "the same day" in one zone and a different day in * another, and this function answers per each value's own zone, the way * Luxon's `dt.hasSame(other, unit)` does for zoned `DateTime`s. * - `"month"` requires the same month AND year, matching `areDateTimesEqualBy`. * - Returns false for an unsupported unit or invalid input. * * Mapping from date-fns (Decision 5, `context/roadmap/issues/J.md`): * - `isSameDay(a, b)` → `areZonedEqualBy(a, b, "day")` * - `isSameMonth(a, b)` → `areZonedEqualBy(a, b, "month")` * - `isSameYear(a, b)` → `areZonedEqualBy(a, b, "year")` * * @param value1 first zoned ISO datetime string * @param value2 second zoned ISO datetime string * @param unit Temporal.DateUnit | Temporal.TimeUnit to compare by * @param optionsArg optional: weekStartsOn ("monday" | "sunday") * @returns true if both values share the same local start-of-unit boundary, false on an unsupported unit or invalid input * * @example areZonedEqualBy("2024-03-15T10:00:00-04:00[America/New_York]", "2024-03-15T20:00:00+01:00[Europe/Berlin]", "day") // true (both are local March 15 in their own zone) * @example areZonedEqualBy("2024-03-15T23:30:00-04:00[America/New_York]", "2024-03-16T04:30:00+00:00[UTC]", "day") // false (same instant, different local calendar day per zone) * @example areZonedEqualBy("invalid", "2024-03-15T10:00:00-04:00[America/New_York]", "day") // false */ export function areZonedEqualBy(value1, value2, unit, optionsArg) { if (!isValidZonedDateTime(value1) || !isValidZonedDateTime(value2) || !isValidDateTimeUnit(unit)) { return false; } try { const start1 = startOfZoned(value1, unit, optionsArg); const start2 = startOfZoned(value2, unit, optionsArg); if (start1 === "" || start2 === "") return false; const local1 = Temporal.ZonedDateTime.from(start1).toPlainDateTime(); const local2 = Temporal.ZonedDateTime.from(start2).toPlainDateTime(); return Temporal.PlainDateTime.compare(local1, local2) === 0; } catch { return false; } }