Установка часового пояса

Часовой пояс в Luxon определяется через IANA-идентификаторы зон, такие как Europe/Paris, Asia/Almaty, America/New_York. Внутри библиотеки работа с зонами построена поверх Intl API, поэтому корректность поддержки зависит от окружения исполнения JavaScript, однако в современных браузерах и Node.js это обычно не вызывает проблем.

Основной объект для работы с датой и временем — DateTime. Именно через него происходит привязка временной метки к конкретной временной зоне и последующее преобразование между зонами.

Каждый экземпляр DateTime содержит информацию о зоне через свойство zone. Это не строка, а объект зоны, реализующий интерфейс Luxon. Однако при создании и преобразовании чаще используются строковые идентификаторы.

Ключевые варианты задания зоны:

  • строковый IANA-идентификатор ("Asia/Almaty")
  • UTC ("utc")
  • локальная зона системы ("local")
  • смещение ("UTC+5", но используется ограниченно и менее предпочтительно)

Установка зоны при создании DateTime

При создании даты можно сразу указать нужную временную зону:

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 и его поведение

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 изменяется)

Работа с системной и UTC зонами

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");

Все три объекта представляют один и тот же момент времени, но с разной локальной интерпретацией.

Практическое различие зон в модели данных

При проектировании систем хранения времени обычно выделяют две стратегии:

  • хранение в UTC с последующей конвертацией
  • хранение в локальной зоне пользователя с явной привязкой зоны

Luxon ориентирован на первую модель. В таком подходе:

  • база данных хранит UTC
  • приложение конвертирует через setZone при отображении
  • пользовательские вводы интерпретируются через zone при создании DateTime

Особенности DST (летнего времени)

При переходах на летнее и зимнее время некоторые локальные часы могут не существовать или дублироваться. Luxon учитывает это через IANA-данные:

const dt = DateTime.fromObject(
  { year: 2026, month: 3, day: 29, hour: 2 },
  { zone: "Europe/Berlin" }
);

В зависимости от региона такое время может быть автоматически скорректировано или помечено как неоднозначное.


Если требуется продолжить тему, логическим развитием становится работа с длительностями и смещениями между зонами, а также обработка пограничных временных значений при сериализации и хранении данных.