Get the Start of the Week in a Timezone in JavaScript

To get the start of the week, subtract (dayOfWeek - firstDay) days from a Temporal.PlainDate, then take startOfDay() in the zone. Part of Working with ZonedDateTime Objects.

Why this scenario is tricky

Two decisions make this locale- and zone-sensitive: which day the week starts on (Monday in ISO, Sunday in the US) and the fact that the week's first instant is that day's startOfDay, which is not always midnight on a DST-transition day. Compute the civil date first, then resolve the instant in the zone.

Week start depends on locale and zoneAssuming Sunday and midnight both biteWeek start depends on locale and zonesubtract getDay(), set 00:00wrong first day + DST gapdayOfWeek math + startOfDaycorrect instantPick the first day explicitly, then resolve startOfDay in the zone.

Minimal working solution

import { Temporal } from '@js-temporal/polyfill';
function weekStart(d: Temporal.PlainDate, firstDay = 1 /*Mon*/) {
  const back = (d.dayOfWeek - firstDay + 7) % 7;
  return d.subtract({ days: back });
}

Back to the week startSubtract (dayOfWeek - firstDay) mod 7Back to the week startPlainDate(dow-first+7)%7week start date

Full production version

import { Temporal } from '@js-temporal/polyfill';
function weekStartInstant(date: Temporal.PlainDate, zone: string, firstDay = 1) {
  const back = (date.dayOfWeek - firstDay + 7) % 7;
  return date.subtract({ days: back }).toZonedDateTime(zone).startOfDay();
}

First instant of the weekCivil week start, then startOfDay in zoneFirst instant of the weekdate+zoneweek starttoZonedDateTimestartOfDay

Verification snippet

Start of the Week assertionsKey cases assert correctlyAssertions that prove the edge caseWed, Mon-firstback to MondaySun, Sun-firststays SundaystartOfDayfirst instantDST week startnot 00:00

Common pitfalls

Start of the Week pitfallsCommon mistakes and their fixesWrongRightassume Sunday startwrong in ISO localesexplicit firstDay paramlocale-correctset time to midnightDST gap invalidstartOfDay in zonevalid instant

Frequently Asked Questions

How do I get the start of the week for a date?

Subtract (dayOfWeek - firstDay + 7) % 7 days from a Temporal.PlainDate, where firstDay is 1 for Monday or 7 for Sunday. To get the exact first instant, call toZonedDateTime(zone).startOfDay() on the resulting date.

Does the week start on Monday or Sunday?

It depends on the locale — ISO 8601 and most of the world use Monday, while the US and some others use Sunday. Make it a parameter so the same function serves both, rather than hard-coding one convention.