Стандарт ISO 8601 определяет систему недель, которая отличается от привычного календарного деления года. Основные правила:
1 до 52
или 53;Например:
2021-01-01 относится к 53-й ISO-неделе 2020 года;2022-01-03 уже принадлежит первой ISO-неделе 2022
года.В Luxon работа с ISO-неделями встроена напрямую в объект
DateTime.
Свойство weekNumber возвращает номер недели по ISO
8601.
import { DateTime } from "luxon";
const dt = DateTime.fromISO("2024-03-15");
console.log(dt.weekNumber);
Результат:
11
Для ISO-недель используется отдельное понятие года —
weekYear.
const dt = DateTime.fromISO("2021-01-01");
console.log(dt.weekYear);
Результат:
2020
Хотя календарный год даты — 2021, ISO-неделя относится к предыдущему ISO-году.
Luxon использует ISO-нумерацию дней:
| День | Значение |
|---|---|
| Понедельник | 1 |
| Вторник | 2 |
| Среда | 3 |
| Четверг | 4 |
| Пятница | 5 |
| Суббота | 6 |
| Воскресенье | 7 |
Свойство weekday:
const dt = DateTime.now();
console.log(dt.weekday);
Luxon позволяет создавать дату через ISO-компоненты:
weekYearweekNumberweekdayconst dt = DateTime.fromObject({
weekYear: 2024,
weekNumber: 20,
weekday: 1
});
console.log(dt.toISODate());
Результат:
2024-05-13
Это понедельник 20-й ISO-недели 2024 года.
Если weekday не указан, Luxon использует
понедельник.
const dt = DateTime.fromObject({
weekYear: 2024,
weekNumber: 1
});
console.log(dt.toISODate());
Результат:
2024-01-01
Методы startOf() и endOf() поддерживают
единицу измерения week.
const dt = DateTime.fromISO("2024-03-14");
console.log(dt.startOf("week").toISO());
Результат:
2024-03-11T00:00:00.000+03:00
console.log(dt.endOf("week").toISO());
Результат:
2024-03-17T23:59:59.999+03:00
В Luxon неделя всегда начинается с понедельника в соответствии с ISO.
const nextWeek = dt.plus({ weeks: 1 });
console.log(nextWeek.toISODate());
const prevWeek = dt.minus({ weeks: 1 });
console.log(prevWeek.toISODate());
Особенно важно учитывать различия в последних и первых днях года.
const dt = DateTime.fromISO("2020-12-31");
console.log(dt.year);
console.log(dt.weekYear);
console.log(dt.weekNumber);
Результат:
2020
2020
53
Другой пример:
const dt2 = DateTime.fromISO("2021-01-01");
console.log(dt2.year);
console.log(dt2.weekYear);
console.log(dt2.weekNumber);
Результат:
2021
2020
53
Свойство weeksInWeekYear показывает, сколько ISO-недель
содержит ISO-год.
const dt = DateTime.fromISO("2020-06-01");
console.log(dt.weeksInWeekYear);
Результат:
53
Некоторые ISO-годы содержат 53 недели.
const dt = DateTime.fromObject({
weekYear: 2020,
weekNumber: 53,
weekday: 5
});
console.log(dt.toISODate());
Результат:
2021-01-01
53-я неделя 2020 ISO-года продолжается уже в календарном 2021 году.
const start = DateTime.fromObject({
weekYear: 2024,
weekNumber: 10,
weekday: 1
});
for (let i = 0; i < 7; i++) {
const day = start.plus({ days: i });
console.log(day.toISODate(), day.weekday);
}
Результат:
2024-03-04 1
2024-03-05 2
2024-03-06 3
2024-03-07 4
2024-03-08 5
2024-03-09 6
2024-03-10 7
Luxon поддерживает форматирование через toFormat().
const dt = DateTime.now();
console.log(dt.toFormat("WW"));
Пример результата:
21
console.log(dt.toFormat("kkkk"));
console.log(dt.toFormat("c"));
const dt = DateTime.now();
const result = dt.toFormat("kkkk-'W'WW-c");
console.log(result);
Пример:
2026-W21-6
Формат соответствует ISO 8601:
kkkk — ISO-год;WW — ISO-неделя;c — ISO-день недели.Luxon умеет разбирать ISO-недельные строки.
const dt = DateTime.fromFormat(
"2024-W12-5",
"kkkk-'W'WW-c"
);
console.log(dt.toISODate());
Результат:
2024-03-22
Для диапазонов удобно использовать Interval.
import { DateTime, Interval } from "luxon";
const start = DateTime.now().startOf("week");
const end = DateTime.now().endOf("week");
const interval = Interval.fromDateTimes(start, end);
console.log(interval.toString());
function sameWeek(a, b) {
return (
a.weekYear === b.weekYear &&
a.weekNumber === b.weekNumber
);
}
const a = DateTime.fromISO("2024-03-12");
const b = DateTime.fromISO("2024-03-15");
console.log(sameWeek(a, b));
Результат:
true
const start = DateTime.fromISO("2024-03-01");
const end = start.endOf("month");
const weeks = new Set();
let current = start;
while (current <= end) {
weeks.add(`${current.weekYear}-${current.weekNumber}`);
current = current.plus({ days: 1 });
}
console.log([...weeks]);
const start = DateTime.fromISO("2024-01-01").startOf("week");
for (let week = 0; week < 4; week++) {
const currentWeek = start.plus({ weeks: week });
console.log(
"Неделя:",
currentWeek.weekNumber
);
for (let day = 0; day < 7; day++) {
const currentDay = currentWeek.plus({ days: day });
console.log(currentDay.toISODate());
}
}
year и
weekYearНеправильно:
DateTime.fromObject({
year: 2024,
weekNumber: 10
});
Правильно:
DateTime.fromObject({
weekYear: 2024,
weekNumber: 10
});
ISO-компоненты должны использоваться совместно.
Luxon придерживается ISO 8601, поэтому:
dt.startOf("week")
всегда возвращает понедельник.
Некоторые годы содержат 53 недели:
console.log(
DateTime.fromISO("2020-01-01").weeksInWeekYear
);
Результат:
53
function getReportKey(date) {
return `${date.weekYear}-W${String(
date.weekNumber
).padStart(2, "0")}`;
}
const dt = DateTime.fromISO("2024-05-15");
console.log(getReportKey(dt));
Результат:
2024-W20
const dt = DateTime.now();
const quarterStart = dt
.startOf("quarter")
.startOf("week");
console.log(quarterStart.toISODate());
const records = [
{
date: "2024-03-12",
value: 10
},
{
date: "2024-03-15",
value: 20
},
{
date: "2024-03-25",
value: 30
}
];
const targetWeek = 11;
const filtered = records.filter(record => {
const dt = DateTime.fromISO(record.date);
return dt.weekNumber === targetWeek;
});
console.log(filtered);
const sales = [
{ date: "2024-03-11", amount: 100 },
{ date: "2024-03-12", amount: 150 },
{ date: "2024-03-18", amount: 200 }
];
const grouped = {};
for (const item of sales) {
const dt = DateTime.fromISO(item.date);
const key = `${dt.weekYear}-W${dt.weekNumber}`;
if (!grouped[key]) {
grouped[key] = [];
}
grouped[key].push(item);
}
console.log(grouped);
const start = DateTime.fromISO("2024-01-01");
const end = DateTime.fromISO("2024-03-01");
const diff = end.diff(start, "weeks");
console.log(diff.weeks);
function createWeekSchedule(weekYear, weekNumber) {
const days = [];
const start = DateTime.fromObject({
weekYear,
weekNumber,
weekday: 1
});
for (let i = 0; i < 7; i++) {
days.push(
start.plus({ days: i }).toISODate()
);
}
return days;
}
console.log(
createWeekSchedule(2024, 15)
);