Luxon строит работу с датами вокруг объекта DateTime,
который всегда существует в контексте временной зоны. При создании
экземпляра через DateTime.local, DateTime.utc,
DateTime.fromISO, DateTime.fromObject и другие
фабрики ключевую роль играет опция zone, определяющая
интерпретацию и отображение времени.
В Luxon временная зона — это не просто форматирование, а фундаментальная характеристика объекта. Одна и та же календарная дата может иметь разное абсолютное значение в зависимости от зоны, а одна и та же метка времени может быть представлена по-разному.
Опция zone передаётся в объекте параметров при создании
DateTime.
import { DateTime } from "luxon";
const dt = DateTime.fromISO("2026-01-15T10:00:00", {
zone: "Europe/Paris"
});
Здесь строка ISO интерпретируется как время в зоне
Europe/Paris. Это означает, что Luxon привязывает локальные
компоненты времени к конкретному часовому поясу, а затем вычисляет
абсолютный момент.
Luxon принимает несколько типов значений для zone:
Наиболее распространённый вариант:
DateTime.local({ zone: "Asia/Almaty" });
DateTime.local({ zone: "America/New_York" });
IANA-зоны обеспечивают корректную работу с переходами на летнее/зимнее время, историческими изменениями и региональными правилами.
Ключевой момент:
DateTime.fromObject(
{ year: 2026, month: 1, day: 15, hour: 10 },
{ zone: "utc" }
);
UTC фиксирует нулевое смещение и исключает любые локальные трансформации времени.
Особенность:
DateTime.local({ zone: "local" });
local использует часовую зону окружения (браузера или
Node.js).
Важно:
DateTime.fromISO("2026-01-15T10:00:00", {
zone: "UTC+5"
});
или
DateTime.fromObject(
{ hour: 10 },
{ zone: "UTC+5" }
);
Такой режим фиксирует смещение без привязки к географической зоне.
Ограничение:
При использовании DateTime.fromISO зона играет ключевую
роль в интерпретации строки.
DateTime.fromISO("2026-01-15T10:00:00", {
zone: "Asia/Tokyo"
});
Здесь строка считается локальным временем в зоне Tokyo.
DateTime.fromISO("2026-01-15T10:00:00+03:00", {
zone: "Asia/Tokyo"
});
Явный offset в строке имеет приоритет над интерпретацией, но результат может быть представлен в указанной зоне.
Опция zone задаёт исходную интерпретацию при создании
объекта.
Метод setZone изменяет представление уже созданного
DateTime.
const dt1 = DateTime.fromISO("2026-01-15T10:00:00", {
zone: "utc"
});
const dt2 = dt1.setZone("Asia/Almaty");
Ключевое различие:
zone — определяет, как прочитано исходное времяsetZone — меняет только отображение, не пересчитывая
момент времениconst dt = DateTime.local();
Эквивалент:
DateTime.local({ zone: "local" });
Но можно переопределить:
const dt = DateTime.local(2026, 1, 15, { zone: "utc" });
Это создаёт локальные компоненты даты, но интерпретирует их как UTC.
Luxon всегда хранит внутреннее представление как timestamp (миллисекунды Unix epoch), но zone влияет на преобразование компонентов:
const dt = DateTime.fromObject(
{ year: 2026, month: 1, day: 15, hour: 10 },
{ zone: "Europe/London" }
);
dt.toMillis();
При изменении зоны результат toMillis() может
измениться, если исходные компоненты интерпретируются по-разному.
Если передать неизвестную зону:
DateTime.fromObject(
{ hour: 10 },
{ zone: "Unknown/Zone" }
);
Luxon помечает объект как invalid:
dt.isValid; // false
dt.invalidReason; // "unsupported zone"
Это важно учитывать при работе с пользовательским вводом.
Luxon использует глобальную настройку
Settings.defaultZone.
import { Settings } from "luxon";
Settings.defaultZone = "Asia/Almaty";
Теперь:
DateTime.local();
будет создан в зоне Asia/Almaty, если не переопределено
явно.
При передаче zone в фабричные методы, оно имеет
приоритет над defaultZone.
DateTime.fromObject({
year: 2026,
month: 5,
day: 23,
hour: 12
}, {
zone: "utc"
});
Здесь важно различать:
Если не указать zone, используется defaultZone.
Для зон с переходом на летнее время:
DateTime.fromObject(
{ year: 2026, month: 3, day: 29, hour: 2 },
{ zone: "Europe/Berlin" }
);
Возможны несуществующие локальные времена.
Luxon обрабатывает это следующим образом:
Это поведение зависит от внутреннего алгоритма IANA time zone database.
const utc = DateTime.fromISO("2026-01-15T10:00:00Z");
const tokyo = utc.setZone("Asia/Tokyo");
const ny = utc.setZone("America/New_York");
Один и тот же момент времени:
Zone влияет только на представление, но не на сам timestamp.
const dt = DateTime.fromObject(
{ year: 2026, month: 1, day: 15 },
{ zone: "Asia/Almaty" }
);
dt.toISO();
Результат включает offset зоны.
Для UTC:
dt.setZone("utc").toISO();
Сравнение происходит через абсолютное время:
const a = DateTime.fromObject(
{ hour: 10 },
{ zone: "Asia/Almaty" }
);
const b = DateTime.fromObject(
{ hour: 8 },
{ zone: "UTC" }
);
a.equals(b);
Даже если локальные часы различаются, сравнение учитывает timestamp.
При создании DateTime выбор зоны определяет:
Разные зоны могут приводить к разным epoch-значениям даже при одинаковых входных полях, если не задана строгая семантика UTC.