Во многих странах и бизнес-системах календарные операции строятся не вокруг конкретного дня месяца, а вокруг номера недели. Такой подход активно используется в:
Библиотека Luxon позволяет создавать даты не только из привычных
компонентов (year, month, day),
но и из:
Это особенно важно при работе с ISO-8601, где неделя считается основной единицей календаря.
ISO-8601 определяет собственную систему недель:
1 до 52 или
53.Например:
| Дата | ISO-неделя |
|---|---|
| 2024-01-01 | 1 |
| 2024-12-31 | 1 (следующего ISO-года) |
| 2025-01-03 | 1 |
Из-за этого ISO-год и календарный год могут отличаться.
weekYear, weekNumber и
weekdayДля создания даты из номера недели используется метод
DateTime.fromObject().
import { DateTime } from "luxon";
const date = DateTime.fromObject({
weekYear: 2025,
weekNumber: 10,
weekday: 3
});
console.log(date.toISO());
Результат:
2025-03-05T00:00:00.000+03:00
weekYearISO-год.
weekYear: 2025
Не всегда совпадает с обычным календарным годом.
weekNumberНомер недели в году.
weekNumber: 10
Допустимый диапазон:
1 - 52
или
1 - 53
в зависимости от года.
weekdayНомер дня недели.
| Значение | День |
|---|---|
| 1 | Понедельник |
| 2 | Вторник |
| 3 | Среда |
| 4 | Четверг |
| 5 | Пятница |
| 6 | Суббота |
| 7 | Воскресенье |
Пример:
const monday = DateTime.fromObject({
weekYear: 2025,
weekNumber: 1,
weekday: 1
});
console.log(monday.toISODate());
Чаще всего требуется получить понедельник определённой недели.
const startOfWeek = DateTime.fromObject({
weekYear: 2025,
weekNumber: 20,
weekday: 1
});
console.log(startOfWeek.toISODate());
Для воскресенья используется weekday: 7.
const endOfWeek = DateTime.fromObject({
weekYear: 2025,
weekNumber: 20,
weekday: 7
});
console.log(endOfWeek.toISODate());
Иногда необходимо построить массив всех дней недели.
const days = [];
for (let i = 1; i <= 7; i++) {
days.push(
DateTime.fromObject({
weekYear: 2025,
weekNumber: 15,
weekday: i
}).toISODate()
);
}
console.log(days);
Результат:
[
'2025-04-07',
'2025-04-08',
'2025-04-09',
'2025-04-10',
'2025-04-11',
'2025-04-12',
'2025-04-13'
]
weekdayЕсли weekday не указан, Luxon использует
понедельник.
const date = DateTime.fromObject({
weekYear: 2025,
weekNumber: 8
});
console.log(date.toISODate());
Некоторые годы содержат 53 недели, некоторые — нет.
Некорректная комбинация создаёт невалидную дату.
const date = DateTime.fromObject({
weekYear: 2025,
weekNumber: 53,
weekday: 1
});
console.log(date.isValid);
if (!date.isValid) {
console.log(date.invalidReason);
}
Возможный результат:
unit out of range
Дата может быть создана сразу в нужной временной зоне.
const date = DateTime.fromObject(
{
weekYear: 2025,
weekNumber: 10,
weekday: 5
},
{
zone: "Europe/Berlin"
}
);
console.log(date.toString());
const utcDate = DateTime.fromObject(
{
weekYear: 2025,
weekNumber: 1,
weekday: 1
},
{
zone: "utc"
}
);
console.log(utcDate.toISO());
Одно из самых распространённых применений.
function getDateFromWeek(year, week, weekday = 1) {
return DateTime.fromObject({
weekYear: year,
weekNumber: week,
weekday
});
}
const result = getDateFromWeek(2025, 30, 4);
console.log(result.toISODate());
Пример вычисления даты начала рабочей недели.
const quarterWeek = DateTime.fromObject({
weekYear: 2025,
weekNumber: 14,
weekday: 1
});
console.log(quarterWeek.startOf("day").toISO());
const meetings = [];
for (let week = 1; week <= 4; week++) {
meetings.push(
DateTime.fromObject({
weekYear: 2025,
weekNumber: week,
weekday: 2
}).toFormat("yyyy-MM-dd")
);
}
console.log(meetings);
Luxon использует ISO-логику по умолчанию.
Это означает:
Обычное создание:
DateTime.fromObject({
year: 2025,
month: 3,
day: 5
});
Создание через неделю:
DateTime.fromObject({
weekYear: 2025,
weekNumber: 10,
weekday: 3
});
Во втором случае дата вычисляется через ISO-календарь.
const now = DateTime.now();
console.log(now.weekYear);
console.log(now.weekNumber);
console.log(now.weekday);
Пример результата:
2025
18
5
Частая ситуация — хранение только:
const saved = {
weekYear: 2025,
weekNumber: 40,
weekday: 2
};
const restored = DateTime.fromObject(saved);
console.log(restored.toISODate());
const calendar = [];
for (let week = 1; week <= 5; week++) {
const row = [];
for (let day = 1; day <= 7; day++) {
row.push(
DateTime.fromObject({
weekYear: 2025,
weekNumber: week,
weekday: day
}).toISODate()
);
}
calendar.push(row);
}
console.log(calendar);
const date = DateTime.fromObject({
weekYear: 2025,
weekNumber: 22,
weekday: 6
});
console.log(
date.toFormat("cccc, dd LLLL yyyy")
);
Результат:
Saturday, 31 May 2025
const monday = DateTime.fromObject({
weekYear: 2025,
weekNumber: 18,
weekday: 1
});
const sunday = monday.plus({ days: 6 });
console.log(monday.toISODate());
console.log(sunday.toISODate());
const weeks = [];
for (let week = 20; week <= 25; week++) {
weeks.push(
DateTime.fromObject({
weekYear: 2025,
weekNumber: week,
weekday: 1
}).toISODate()
);
}
console.log(weeks);
Недельные идентификаторы удобны для:
Пример структуры:
{
weekYear: 2025,
weekNumber: 12,
revenue: 150000
}
const date = DateTime.now();
console.log({
weekYear: date.weekYear,
weekNumber: date.weekNumber,
weekday: date.weekday
});
Можно одновременно указать время.
const date = DateTime.fromObject({
weekYear: 2025,
weekNumber: 35,
weekday: 4,
hour: 14,
minute: 30
});
console.log(date.toISO());
Нельзя одновременно использовать:
year;month;day;и:
weekYear;weekNumber;weekday.Некорректный пример:
DateTime.fromObject({
year: 2025,
month: 5,
weekNumber: 10
});
Это приведёт к ошибке валидации.
function getWorkWeekStart(weekYear, weekNumber) {
return DateTime.fromObject({
weekYear,
weekNumber,
weekday: 1
});
}
const workWeek = getWorkWeekStart(2025, 42);
console.log(workWeek.toISODate());
function sprintStart(weekNumber) {
return DateTime.fromObject({
weekYear: 2025,
weekNumber,
weekday: 1
});
}
const sprint = sprintStart(16);
console.log(
sprint.toFormat("dd LLL yyyy")
);
const delivery = DateTime.fromObject({
weekYear: 2025,
weekNumber: 28,
weekday: 5,
hour: 9
});
console.log(delivery.toISO());
function buildReportDate(weekYear, weekNumber) {
return DateTime.fromObject({
weekYear,
weekNumber,
weekday: 7
});
}
const reportDate = buildReportDate(2025, 50);
console.log(reportDate.toISODate());