В библиотеке Luxon основная сущность для работы с датами и временем —
объект DateTime. Он представляет собой неизменяемую
структуру, где любые операции возвращают новый экземпляр, а не
модифицируют существующий. Это критично при работе с календарными
компонентами, такими как год, месяц и день, поскольку исключает побочные
эффекты и упрощает предсказуемость кода.
Luxon предоставляет несколько способов создания даты, в которых явно задаются год, месяц и день.
Основной способ — DateTime.local():
import { DateTime } from "luxon";
const dt = DateTime.local(2026, 5, 23);
Порядок аргументов строго фиксирован:
Месяцы в Luxon нумеруются с 1, а не с 0, как в стандартном JavaScript
Date. Это устраняет типичную ошибку смещения индексов
месяцев.
Создание даты через объект:
const dt = DateTime.local({
year: 2026,
month: 5,
day: 23
});
Такой подход повышает читаемость при работе с конфигурационными или динамически формируемыми значениями.
Объект DateTime предоставляет прямой доступ к
календарным частям:
const dt = DateTime.local(2026, 5, 23);
dt.year; // 2026
dt.month; // 5
dt.day; // 23
Эти свойства являются вычисляемыми и не изменяют объект.
Дополнительно доступны производные компоненты:
dt.weekday; // день недели (1 — понедельник, 7 — воскресенье)
dt.ordinal; // порядковый день года (1–365/366)
dt.weekNumber;
Для изменения отдельных частей даты используется метод
set().
const dt = DateTime.local(2026, 5, 23);
const upd ated = dt.se t({
year: 2027,
month: 1,
day: 10
});
Важно учитывать:
DateTimeЧастичное обновление:
const nextMonth = dt.set({ month: 6 });
const nextYear = dt.set({ year: 2027 });
Luxon автоматически нормализует некорректные календарные значения.
DateTime.local(2026, 2, 31);
Результат будет приведён к корректной дате:
Такое поведение называется clamping / normalization и предотвращает получение невалидных дат.
Для календарных вычислений часто требуется получить начало или конец месяца, года или дня.
const dt = DateTime.local(2026, 5, 23);
dt.startOf("year"); // 2026-01-01
dt.startOf("month"); // 2026-05-01
dt.startOf("day"); // 2026-05-23 00:00:00
dt.endOf("year"); // 2026-12-31 23:59:59.999
dt.endOf("month"); // 2026-05-31 23:59:59.999
dt.endOf("day"); // 2026-05-23 23:59:59.999
Эти методы особенно важны при построении диапазонов дат, фильтрации данных и аналитических запросах.
Luxon корректно парсит ISO 8601, сохраняя календарную структуру:
const dt = DateTime.fromISO("2026-05-23");
После парсинга доступны те же поля:
dt.year; // 2026
dt.month; // 5
dt.day; // 23
Если строка содержит только дату без времени, время устанавливается в
00:00:00.
Метод toFormat() используется для получения строкового
представления.
const dt = DateTime.local(2026, 5, 23);
dt.toFormat("yyyy"); // "2026"
dt.toFormat("MM"); // "05"
dt.toFormat("dd"); // "23"
dt.toFormat("yyyy-MM-dd"); // "2026-05-23"
Основные токены:
yyyy — годMM — месяц с ведущим нулёмM — месяц без ведущего нуляdd — день с ведущим нулёмd — день без ведущего нуляLuxon разделяет календарные компоненты и абсолютное время.
const dt = DateTime.local(2026, 5, 23);
Этот объект одновременно содержит:
Изменение календарной части не обязательно изменяет смысл времени, если не затрагивается зона или время суток.
DateTime.local(2026, 1, 1); // январь
Количество дней зависит от месяца и високосного года.
DateTime.local(2024, 2, 29); // корректно (високосный год)
DateTime.local(2026, 2, 29); // будет нормализовано
Luxon учитывает календарную систему Gregorian.
Любая операция изменения года, месяца или дня фактически создаёт новый объект:
const base = DateTime.local(2026, 5, 23);
const a = base.set({ year: 2027 });
const b = base.set({ month: 6 });
const c = base.set({ day: 1 });
Все три результата независимы друг от друга и от
base.
Комбинация startOf("month") и явной установки
компонентов даёт эквивалентный результат:
const dt = DateTime.local(2026, 5, 23);
const start1 = dt.startOf("month");
const start2 = dt.set({ day: 1, hour: 0, minute: 0, second: 0, millisecond: 0 });
Разница заключается в уровне абстракции: startOf()
работает декларативно, set() — явно.
Luxon позволяет сравнивать даты напрямую:
const a = DateTime.local(2026, 5, 10);
const b = DateTime.local(2026, 5, 23);
a < b; // true
Сравнение основано на timestamp, но при равенстве календарных частей оно эквивалентно сравнению year/month/day.
Особенность, связанная с длиной месяцев:
DateTime.local(2026, 1, 31).set({ month: 2 });
Результат:
Это поведение важно учитывать при построении календарных интерфейсов и автоматических сдвигов дат.
Все операции с годом, месяцем и днём в Luxon изолированы:
DateTimeconst original = DateTime.local(2026, 5, 23);
const modified = original.set({ day: 1 });
original.day; // 23
modified.day; // 1
Методы можно комбинировать:
const dt = DateTime.local()
.set({ year: 2026 })
.set({ month: 5 })
.set({ day: 23 })
.startOf("day");
Цепочки особенно полезны при формировании дат из разрозненных данных.
Luxon защищает от некорректных календарных состояний:
DateTime.local(2026, 0, 10); // декабрь предыдущего года
Такое поведение делает работу с календарём устойчивой к ошибкам входных данных.
Хотя year/month/day универсальны, их отображение зависит от локали при форматировании:
dt.setLocale("ru").toLocaleString(DateTime.DATE_FULL);
Календарная структура остаётся неизменной, изменяется только представление.
Получение диапазона месяца через календарные компоненты:
const start = dt.startOf("month");
const end = dt.endOf("month");
Эти значения используются для:
Год, месяц и день зависят от текущей зоны:
const dt = DateTime.local().setZone("Asia/Almaty");
Изменение зоны может привести к изменению календарного дня, если момент времени пересекает границу суток в новой зоне.
Luxon позволяет легко переходить между разными уровнями детализации:
const dt = DateTime.local(2026, 5, 23);
dt.toISODate(); // "2026-05-23"
dt.toISO(); // полная дата и время
Календарные компоненты сохраняются во всех представлениях ISO.
При построении дат из пользовательского ввода используется строгая сборка:
function buildDate(y, m, d) {
return DateTime.local(y, m, d).startOf("day");
}
Такой подход фиксирует: