ISO Week Number and Week Start Date
Calculate ISO 8601 week numbers and convert a year plus week back to the Monday that starts it, with round-trip validation.
Code
export function isoWeek(date = new Date()) {
const value = toUtcDate(date);
const thursday = new Date(value.getTime());
const weekday = value.getUTCDay() || 7;
thursday.setUTCDate(value.getUTCDate() + 4 - weekday);
const year = thursday.getUTCFullYear();
const firstThursday = new Date(Date.UTC(year, 0, 4));
const offset = firstThursday.getUTCDay() || 7;
firstThursday.setUTCDate(firstThursday.getUTCDate() + 4 - offset);
const week = 1 + Math.round((thursday - firstThursday) / (7 * 24 * 60 * 60 * 1000));
return { year, week };
}
export function isoWeekStart(year, week) {
if (!Number.isInteger(year) || year < 1 || year > 9999) throw new RangeError("year out of range");
if (!Number.isInteger(week) || week < 1 || week > 53) throw new RangeError("week out of range");
const januaryFourth = new Date(Date.UTC(year, 0, 4));
const weekday = januaryFourth.getUTCDay() || 7;
const monday = new Date(januaryFourth.getTime());
monday.setUTCDate(januaryFourth.getUTCDate() - weekday + 1 + (week - 1) * 7);
const check = isoWeek(monday);
if (check.year !== year || check.week !== week) {
throw new RangeError("week does not exist in that ISO year");
}
return monday;
}
function toUtcDate(date) {
if (!(date instanceof Date) || Number.isNaN(date.getTime())) {
throw new TypeError("date must be a valid Date");
}
return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
}
const week = isoWeek(new Date("2026-01-01T00:00:00Z"));
console.log(week);
console.log(isoWeekStart(week.year, week.week).toISOString().slice(0, 10));
console.log(isoWeek(new Date("2024-12-30T00:00:00Z")));Report a problem with this exampleOpens a pre-filled issue on GitHub.