Luxon построена вокруг строгой модели работы с календарным временем и
часовыми поясами, где каждое значение времени всегда связано с
конкретной временной зоной или явно переводится между зонами. В отличие
от встроенного объекта Date, который хранит момент времени
в UTC и лишь отображает его в локальной зоне окружения, Luxon делает
работу с зонами явной частью API, минимизируя неоднозначность при
преобразованиях.
В основе системы часовых поясов в Luxon лежат IANA time zone
identifiers, такие как Europe/Moscow,
Asia/Almaty, UTC,
America/New_York. Эти идентификаторы задают правила
смещения относительно UTC, включая переходы на летнее время.
Каждый объект DateTime содержит три ключевых
компонента:
Ключевая особенность заключается в том, что один и тот же момент времени может быть представлен в разных часовых поясах без изменения своей абсолютной природы.
Luxon предоставляет несколько способов создания даты-времени с привязкой к часовому поясу.
import { DateTime } from "luxon";
const dt = DateTime.local();
Такой вызов использует системный часовой пояс среды выполнения (браузера или сервера Node.js).
const dt = DateTime.local().setZone("Asia/Almaty");
или напрямую через конфигурацию:
const dt = DateTime.now().setZone("Europe/Moscow");
В этом случае Luxon не изменяет момент времени, а лишь пересчитывает его представление в новой зоне.
const dt = DateTime.utc();
UTC в Luxon используется как базовая опорная система отсчёта, исключающая влияние локальных смещений и летнего времени.
Одним из ключевых методов является setZone, который
позволяет изменить представление времени без изменения самого
момента.
const dt = DateTime.fromISO("2026-01-01T12:00:00Z");
const moscow = dt.setZone("Europe/Moscow");
const newYork = dt.setZone("America/New_York");
Важно, что dt, moscow и
newYork ссылаются на один и тот же момент времени, но
отображаются по-разному.
Частая ошибка при работе с часовыми поясами — путаница между преобразованием зоны и нормализацией к UTC.
const dt = DateTime.local();
const utc = dt.toUTC();
toUTC() переводит текущее значение в универсальную
временную зону UTC, фактически нормализуя представление.
Luxon опирается на встроенную поддержку ICU (International Components for Unicode), которая обеспечивает:
Пример:
const dt = DateTime.fromObject(
{ year: 2026, month: 6, day: 1, hour: 12 },
{ zone: "Europe/Berlin" }
);
В зависимости от даты Luxon автоматически применит правильное смещение (например, UTC+2 летом и UTC+1 зимой).
Переключение между зонами является основным сценарием использования при работе с распределёнными системами.
const base = DateTime.fromISO("2026-05-23T10:00:00Z");
const tokyo = base.setZone("Asia/Tokyo");
const london = base.setZone("Europe/London");
const sydney = base.setZone("Australia/Sydney");
Каждый результат сохраняет одинаковую временную точку, но отображается согласно локальным правилам региона.
Luxon предоставляет доступ к числовому смещению относительно UTC в минутах:
const dt = DateTime.now().setZone("Asia/Almaty");
console.log(dt.offset);
Значение offset:
Это полезно при низкоуровневой работе с API, где требуется передавать числовые смещения вместо строковых зон.
Luxon позволяет определить текущую зону окружения:
const zone = DateTime.local().zoneName;
или через системный доступ:
const zone = Intl.DateTimeFormat().resolvedOptions().timeZone;
Luxon интегрируется с этим механизмом и использует его как базу для
DateTime.local().
При парсинге ISO-строк Luxon учитывает встроенную информацию о зоне:
const dt1 = DateTime.fromISO("2026-05-23T12:00:00+06:00");
const dt2 = DateTime.fromISO("2026-05-23T06:00:00Z");
Оба значения представляют один и тот же момент времени, несмотря на разное представление.
Некоторые операции в Luxon могут сбрасывать или сохранять информацию о зоне в зависимости от метода.
const upd ated = dt.se t({ hour: 15 });
При создании нового объекта через fromObject зона может
быть переопределена:
const dt = DateTime.fromObject(
{ year: 2026, month: 5, day: 23 },
{ zone: "UTC" }
);
Luxon автоматически учитывает переходы DST.
Пример проблемной ситуации без корректной обработки:
Luxon решает это через ICU-правила:
const dt = DateTime.fromObject(
{ year: 2026, month: 3, day: 29, hour: 2 },
{ zone: "Europe/Berlin" }
);
Если время попадает в несуществующий интервал, Luxon корректирует его согласно правилам зоны.
Luxon позволяет управлять поведением при некорректных данных:
Пример:
DateTime.fromObject(
{ year: 2026, month: 2, day: 30 },
{ zone: "Asia/Almaty", numberingSystem: "latn" }
);
Такое значение будет нормализовано в зависимости от правил календаря.
Разница между моментами времени не зависит от зоны, но отображение может влиять на восприятие:
const a = DateTime.fromISO("2026-01-01T00:00:00Z");
const b = DateTime.fromISO("2026-01-01T12:00:00Z");
const diff = b.diff(a, "hours").hours;
Результат всегда вычисляется в абсолютном времени, а не в локальных представлениях.
Luxon обеспечивает корректное сравнение через внутренние timestamp-значения:
const a = DateTime.fromISO("2026-05-23T10:00:00+06:00");
const b = DateTime.fromISO("2026-05-23T04:00:00Z");
console.log(a.equals(b));
Сравнение происходит не по строковому виду, а по абсолютному моменту.
В архитектуре Luxon UTC выступает как универсальный посредник:
Это снижает количество ошибок при конвертации и делает цепочки преобразований детерминированными.
Часто встречающиеся проблемы:
+3, -5) вместо
IANA-зонLuxon минимизирует эти ошибки за счёт явных API:
DateTime.fromObject({ hour: 12 }, { zone: "UTC" });
или
DateTime.now().setZone("UTC");
Система часовых поясов в Luxon строится на трёх принципах:
Такая модель делает работу с распределёнными системами, логами, событиями и расписаниями предсказуемой и устойчивой к ошибкам преобразования времени.