UNPKG

vremel

Version:

JavaScript date utility library for Temporal API

85 lines (78 loc) 2.25 kB
import { isPlainDate, isZonedDateTime } from "../type-utils.js"; import type { Temporal } from "../types.js"; import { endOfTimeForZonedDateTime } from "./_endOfTimeForZonedDateTime.js"; export interface EndOfWeekOptions { /** * First day of the week. * For example, in ISO calendar Monday is `1`, Sunday is `7`. */ firstDayOfWeek: number; } function endOfWeekWithDayPrecision( dt: Temporal.PlainDate, firstDayOfWeek: number, ): Temporal.PlainDate; function endOfWeekWithDayPrecision( dt: Temporal.PlainDateTime, firstDayOfWeek: number, ): Temporal.PlainDateTime; function endOfWeekWithDayPrecision( dt: Temporal.PlainDate | Temporal.PlainDateTime, firstDayOfWeek: number, ) { return dt.add({ days: (firstDayOfWeek + dt.daysInWeek - dt.dayOfWeek - 1) % dt.daysInWeek, }); } /** * Returns the end of a week for the given datetime. * 'end of a week' is ambiguous and locale-dependent, * so `firstDayOfWeek` option is required. * This function supports a calendar with a fixed `daysInWeek`, * even if the week contains more or less than 7 days. * But it doesn't support a calendar which lacks a fixed number of days. * * @param dt datetime object which includes date info * @returns Temporal object which represents the end of a week */ export function endOfWeek< DateTime extends | Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime, >(dt: DateTime, options: EndOfWeekOptions): DateTime { const firstDayOfWeek = options.firstDayOfWeek; if ( !Number.isInteger(firstDayOfWeek) || firstDayOfWeek < 1 || firstDayOfWeek > dt.daysInWeek ) { throw new Error(`${firstDayOfWeek} isn't a valid day of week`); } const timeArg = { hour: 23, minute: 59, second: 59, millisecond: 999, microsecond: 999, nanosecond: 999, }; if (isZonedDateTime(dt)) { const endOfWeek = endOfWeekWithDayPrecision( dt.toPlainDate(), firstDayOfWeek, ); return endOfTimeForZonedDateTime(dt, { year: endOfWeek.year, month: endOfWeek.month, day: endOfWeek.day, ...timeArg, }) as DateTime; } if (isPlainDate(dt)) { return endOfWeekWithDayPrecision(dt, firstDayOfWeek) as DateTime; } return endOfWeekWithDayPrecision(dt, firstDayOfWeek).with( timeArg, ) as DateTime; }