UNPKG

@burglekitt/gmt

Version:

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

45 lines (44 loc) 1.91 kB
import { Temporal } from "@js-temporal/polyfill"; // Week 1 of a locale week-year always contains January's `minimalDays`-th // day: the week starting on/before Jan 1 has k days in January, where k // ranges from `minimalDays` (the threshold to still count as week 1) up // to 7 (a full week starting exactly on Jan 1) — so day `minimalDays` of // January falls within that range no matter which end it lands on. This // generalizes ISO 8601's own rule (minimalDays = 4, so week 1 always // contains Jan 4). function startOfWeek1(year, firstDay, minimalDays) { const anchor = Temporal.PlainDate.from({ year, month: 1, day: minimalDays, }); const daysSinceFirstDay = (anchor.dayOfWeek - firstDay + 7) % 7; return anchor.subtract({ days: daysSinceFirstDay }); } /** * Resolve the locale week-numbering year `date` belongs to, and the * `[start, end)` bounds (in calendar days) of that week-year, given a * locale's `firstDay` (1 = Monday .. 7 = Sunday) and `minimalDays` (the * minimum January days a week must have to count as week 1) — both from * `Intl.Locale.prototype.weekInfo`. * * Shared by `getLocaleWeekYear` (the year itself) and * `getWeeksInLocaleWeekYear` (the week count, derived from `start`/`end`). */ export function getLocaleWeekYearBounds(date, firstDay, minimalDays) { let weekYear = date.year; let start = startOfWeek1(weekYear, firstDay, minimalDays); if (Temporal.PlainDate.compare(date, start) < 0) { weekYear -= 1; start = startOfWeek1(weekYear, firstDay, minimalDays); } else { const nextStart = startOfWeek1(weekYear + 1, firstDay, minimalDays); if (Temporal.PlainDate.compare(date, nextStart) >= 0) { weekYear += 1; start = nextStart; } } const end = startOfWeek1(weekYear + 1, firstDay, minimalDays); return { weekYear, start, end }; }