Часовые пояса в Luxon основаны на модели IANA Time Zone Database и представляют собой строгую систему интерпретации времени, где каждая временная метка всегда связана с конкретной зоной. В отличие от упрощённых подходов, где хранится только смещение относительно UTC, Luxon оперирует полноценными часовыми зонами, учитывающими правила летнего времени, исторические изменения и региональные особенности.
Основной тип, с которым работает библиотека, — DateTime.
Каждый экземпляр DateTime содержит не только дату и время,
но и информацию о зоне (zone). Именно зона определяет, как
интерпретировать и отображать момент времени.
Luxon использует идентификаторы из базы IANA, например:
Europe/MoscowAsia/AlmatyAmerica/New_YorkUTCКаждый такой идентификатор описывает правила:
Важная особенность: одна и та же временная метка может отображаться по-разному в зависимости от зоны, но сам момент времени остаётся неизменным.
UTC (Coordinated Universal Time) в Luxon выступает базовой системой координат времени. Любое локальное время может быть приведено к UTC, после чего корректно преобразовано в другую зону.
Создание объекта в UTC:
import { DateTime } from "luxon";
const dt = DateTime.utc(2026, 5, 23, 12, 0);
UTC-зона в Luxon считается эталонной и не подвержена влиянию летнего времени.
При создании даты через DateTime.local() используется
системная зона окружения (браузера или Node.js):
const dt = DateTime.local(2026, 5, 23, 12, 0);
Эта зона определяется операционной системой. Luxon оборачивает её в
объект SystemZone, который динамически вычисляет смещение в
зависимости от окружения.
Ключевой момент: системная зона не фиксирована, она может меняться при переносе кода между окружениями.
Luxon позволяет явно задавать зону при создании объекта:
const dt = DateTime.fromObject(
{ year: 2026, month: 5, day: 23, hour: 12 },
{ zone: "Asia/Almaty" }
);
Здесь используется IANA-идентификатор, и Luxon применяет соответствующие правила смещения и DST.
Также поддерживается формат ISO:
const dt = DateTime.fromISO("2026-05-23T12:00:00", {
zone: "America/New_York"
});
Если зона не указана, используется системная.
Одна из ключевых операций — смена отображаемой зоны через
setZone.
const dt1 = DateTime.fromISO("2026-05-23T12:00:00", { zone: "UTC" });
const dt2 = dt1.setZone("Asia/Almaty");
В этом случае происходит преобразование одного и того же момента времени в другую зону. Время «пересчитывается», но абсолютный момент остаётся тем же.
Это поведение отличается от простого изменения поля зоны без пересчёта.
Метод setZone поддерживает параметр
keepLocal, который кардинально меняет смысл операции:
const dt = DateTime.local(2026, 5, 23, 12, 0);
const shifted = dt.setZone("UTC", { keepLocal: true });
При keepLocal: true сохраняются локальные компоненты
даты и времени (год, месяц, день, час), а зона просто подменяется. Это
приводит к изменению абсолютного момента времени.
Разница:
keepLocal: false — сохраняется момент времени, меняется
отображение.keepLocal: true — сохраняется отображение, меняется
момент времени.Это критическая концепция для корректной работы с временными данными в распределённых системах.
Помимо IANA-зон, Luxon поддерживает фиксированные смещения через
FixedOffsetZone.
Пример:
const dt = DateTime.fromObject(
{ year: 2026, month: 5, day: 23, hour: 12 },
{ zone: "UTC+5" }
);
Фиксированная зона не учитывает летнее время и исторические изменения. Она всегда применяет постоянное смещение.
Использование фиксированных зон оправдано только в системах, где время определяется исключительно offset-логикой, например в простых логах или протоколах.
IANA-зоны:
Фиксированные зоны:
Luxon выполняет конвертацию через приведение к UTC и последующее применение новой зоны.
const dt = DateTime.fromISO("2026-05-23T12:00:00", { zone: "Europe/Moscow" });
const converted = dt.setZone("Asia/Tokyo");
Внутренний процесс:
DateTime.Летнее время (Daylight Saving Time) учитывается автоматически при использовании IANA-зон.
Например, в Europe/Berlin:
Luxon самостоятельно определяет, какое правило применимо к конкретной дате:
const winter = DateTime.fromISO("2026-01-15", { zone: "Europe/Berlin" });
const summer = DateTime.fromISO("2026-07-15", { zone: "Europe/Berlin" });
Разница смещения вычисляется автоматически на основе календарных правил зоны.
Если передана неизвестная зона, Luxon создаёт
InvalidZone. Такой объект не может корректно выполнять
преобразования.
const dt = DateTime.fromObject(
{ year: 2026, month: 5, day: 23 },
{ zone: "Unknown/Zone" }
);
Результатом будет объект с ошибочной зоной, который следует проверять
через isValid.
Luxon оперирует несколькими основными реализациями:
SystemZone — системная зона окруженияIANAZone — стандартная временная зонаFixedOffsetZone — фиксированное смещениеInvalidZone — некорректная зонаКаждый тип реализует единый интерфейс, позволяющий вычислять offset и правила преобразования времени.
Каждый DateTime содержит вычисляемое смещение:
const dt = DateTime.fromISO("2026-05-23T12:00:00", { zone: "Asia/Almaty" });
console.log(dt.offset);
offset возвращает разницу в минутах относительно UTC.
Это значение динамическое и зависит от даты (из-за DST).
Luxon разделяет два уровня:
Все операции с зонами сводятся к преобразованию между этими уровнями.
Каждый объект DateTime содержит:
zoneName — строковое имя зоны (например,
“Europe/Moscow”);zone.type — тип зоны (IANA, system, fixed,
invalid).Эти свойства используются для диагностики и отладки временных преобразований.
Практически все операции в Luxon проходят через UTC как промежуточный слой. Это позволяет унифицировать преобразования между зонами и избежать накопления ошибок округления при смещениях.
const utc = dt.toUTC();
const back = utc.setZone("Europe/Moscow");
Такой подход гарантирует стабильность вычислений при многократных конвертациях.
Вся система часовых поясов Luxon строится на трёх уровнях:
Переход между этими уровнями всегда детерминирован и опирается на правила зоны, а не на статическое смещение.