Часовой пояс в Luxon определяется через IANA-идентификаторы зон,
такие как Europe/Paris, Asia/Almaty,
America/New_York. Внутри библиотеки работа с зонами
построена поверх Intl API, поэтому корректность поддержки
зависит от окружения исполнения JavaScript, однако в современных
браузерах и Node.js это обычно не вызывает проблем.
Основной объект для работы с датой и временем —
DateTime. Именно через него происходит привязка временной
метки к конкретной временной зоне и последующее преобразование между
зонами.
Каждый экземпляр DateTime содержит информацию о зоне
через свойство zone. Это не строка, а объект зоны,
реализующий интерфейс Luxon. Однако при создании и преобразовании чаще
используются строковые идентификаторы.
Ключевые варианты задания зоны:
"Asia/Almaty")"utc")"local")"UTC+5", но используется ограниченно и менее
предпочтительно)При создании даты можно сразу указать нужную временную зону:
import { DateTime } from "luxon";
const dt = DateTime.fromObject(
{ year: 2026, month: 1, day: 1, hour: 12 },
{ zone: "Asia/Almaty" }
);
Здесь важно понимать, что Luxon интерпретирует входные компоненты как локальное время в указанной зоне. Это означает, что «12:00» будет именно 12:00 по времени Алматы, а не преобразованное значение из системного времени.
Аналогично можно использовать ISO-строки:
const dt = DateTime.fromISO("2026-01-01T12:00", {
zone: "Europe/Paris"
});
Создание текущего времени с привязкой к зоне выполняется через
DateTime.now() или DateTime.local() с опцией
зоны:
const dt = DateTime.now().setZone("America/New_York");
Либо напрямую:
const dt = DateTime.local().setZone("America/New_York");
Разница заключается в том, что сначала создаётся локальное время системы, а затем происходит преобразование в указанную зону.
setZone — ключевой механизм переключения временной зоны
у уже существующего объекта DateTime.
const dtLocal = DateTime.local();
const dtTokyo = dtLocal.setZone("Asia/Tokyo");
Важно различать два режима работы setZone:
const dt = DateTime.fromISO("2026-01-01T12:00", { zone: "UTC" });
const converted = dt.setZone("Asia/Almaty");
Здесь происходит реальное пересчитывание момента времени. 12:00 UTC станет другим значением в Алматы, например 17:00 (в зависимости от смещения).
const dt = DateTime.fromISO("2026-01-01T12:00", { zone: "UTC" });
const sameTime = dt.setZone("Asia/Almaty", { keepLocalTime: true });
В этом случае Luxon сохраняет часы, минуты и секунды, но меняет интерпретацию зоны. Это приводит к изменению абсолютного момента времени, хотя визуально время остаётся прежним.
Это критический момент, так как поведение двух режимов принципиально различается:
keepLocalTime — меняется момент времени (timestamp
остаётся тем же)keepLocalTime — меняется смысл времени (timestamp
изменяется)Luxon поддерживает специальные зоны:
DateTime.local().setZone("local");
DateTime.local().setZone("utc");
Также можно явно использовать UTC:
const dt = DateTime.utc(2026, 1, 1, 12, 0);
UTC-зона часто используется как нейтральная база хранения времени, так как она исключает неоднозначности при переходах на летнее/зимнее время.
У экземпляра DateTime можно получить информацию о
зоне:
const dt = DateTime.local().setZone("Asia/Almaty");
dt.zoneName; // "Asia/Almaty"
dt.isOffsetFixed; // false для IANA зон
dt.offset; // смещение в минутах
offset возвращает разницу относительно UTC в текущий
момент времени, учитывая сезонные изменения, если они применимы к
зоне.
Если указана некорректная строка зоны, Luxon обычно не бросает исключение сразу, а создаёт объект с пометкой невалидности:
const dt = DateTime.local().setZone("Invalid/Zone");
dt.isValid; // false
dt.invalidReason;
Это важно учитывать при динамической работе с пользовательским вводом или внешними источниками данных.
Luxon позволяет задать глобальную зону, которая будет использоваться при создании дат без явного указания зоны:
import { Settings } from "luxon";
Settings.defaultZone = "Asia/Almaty";
После этого:
const dt = DateTime.local();
будет автоматически создаваться в указанной зоне, а не в системной.
Такой подход применяется в приложениях, где вся логика должна быть привязана к одной временной зоне независимо от сервера или клиента.
Зона влияет не только на вычисления, но и на вывод:
const dt = DateTime.fromISO("2026-01-01T12:00", { zone: "UTC" });
dt.toString();
dt.toLocaleString(DateTime.DATETIME_FULL);
При форматировании Luxon использует текущую зону объекта, а не системную. Это означает, что один и тот же момент времени может отображаться по-разному в зависимости от установленной зоны.
Luxon не изменяет исходный объект при смене зоны, а возвращает новый экземпляр:
const base = DateTime.utc(2026, 1, 1, 12);
const paris = base.setZone("Europe/Paris");
const tokyo = base.setZone("Asia/Tokyo");
Все три объекта представляют один и тот же момент времени, но с разной локальной интерпретацией.
При проектировании систем хранения времени обычно выделяют две стратегии:
Luxon ориентирован на первую модель. В таком подходе:
setZone при
отображенииzone при
создании DateTimeПри переходах на летнее и зимнее время некоторые локальные часы могут не существовать или дублироваться. Luxon учитывает это через IANA-данные:
const dt = DateTime.fromObject(
{ year: 2026, month: 3, day: 29, hour: 2 },
{ zone: "Europe/Berlin" }
);
В зависимости от региона такое время может быть автоматически скорректировано или помечено как неоднозначное.
Если требуется продолжить тему, логическим развитием становится работа с длительностями и смещениями между зонами, а также обработка пограничных временных значений при сериализации и хранении данных.