Опция zone при создании

Luxon строит работу с датами вокруг объекта DateTime, который всегда существует в контексте временной зоны. При создании экземпляра через DateTime.local, DateTime.utc, DateTime.fromISO, DateTime.fromObject и другие фабрики ключевую роль играет опция zone, определяющая интерпретацию и отображение времени.

В Luxon временная зона — это не просто форматирование, а фундаментальная характеристика объекта. Одна и та же календарная дата может иметь разное абсолютное значение в зависимости от зоны, а одна и та же метка времени может быть представлена по-разному.


Основные способы задания zone при создании

Опция zone передаётся в объекте параметров при создании DateTime.

import { DateTime } from "luxon";

const dt = DateTime.fromISO("2026-01-15T10:00:00", {
  zone: "Europe/Paris"
});

Здесь строка ISO интерпретируется как время в зоне Europe/Paris. Это означает, что Luxon привязывает локальные компоненты времени к конкретному часовому поясу, а затем вычисляет абсолютный момент.


Поддерживаемые типы zone

Luxon принимает несколько типов значений для zone:

1. IANA-идентификаторы

Наиболее распространённый вариант:

DateTime.local({ zone: "Asia/Almaty" });
DateTime.local({ zone: "America/New_York" });

IANA-зоны обеспечивают корректную работу с переходами на летнее/зимнее время, историческими изменениями и региональными правилами.

Ключевой момент:

  • зона влияет на смещение (offset)
  • автоматически учитываются DST-переходы

2. UTC-зона

DateTime.fromObject(
  { year: 2026, month: 1, day: 15, hour: 10 },
  { zone: "utc" }
);

UTC фиксирует нулевое смещение и исключает любые локальные трансформации времени.

Особенность:

  • отсутствие DST
  • стабильное представление времени

3. Local (системная зона)

DateTime.local({ zone: "local" });

local использует часовую зону окружения (браузера или Node.js).

Важно:

  • зависит от системы
  • может меняться при переносе приложения

4. Fixed offset (фиксированный сдвиг)

DateTime.fromISO("2026-01-15T10:00:00", {
  zone: "UTC+5"
});

или

DateTime.fromObject(
  { hour: 10 },
  { zone: "UTC+5" }
);

Такой режим фиксирует смещение без привязки к географической зоне.

Ограничение:

  • нет DST
  • не учитываются исторические изменения

Поведение zone при парсинге ISO-строк

При использовании 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

Опция zone задаёт исходную интерпретацию при создании объекта.

Метод setZone изменяет представление уже созданного DateTime.

const dt1 = DateTime.fromISO("2026-01-15T10:00:00", {
  zone: "utc"
});

const dt2 = dt1.setZone("Asia/Almaty");

Ключевое различие:

  • zone — определяет, как прочитано исходное время
  • setZone — меняет только отображение, не пересчитывая момент времени

Поведение при DateTime.local

const dt = DateTime.local();

Эквивалент:

DateTime.local({ zone: "local" });

Но можно переопределить:

const dt = DateTime.local(2026, 1, 15, { zone: "utc" });

Это создаёт локальные компоненты даты, но интерпретирует их как UTC.


Влияние zone на вычисление момента времени

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"

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


defaultZone и влияние на создание DateTime

Luxon использует глобальную настройку Settings.defaultZone.

import { Settings } from "luxon";

Settings.defaultZone = "Asia/Almaty";

Теперь:

DateTime.local();

будет создан в зоне Asia/Almaty, если не переопределено явно.

При передаче zone в фабричные методы, оно имеет приоритет над defaultZone.


zone в DateTime.fromObject и частичное поведение

DateTime.fromObject({
  year: 2026,
  month: 5,
  day: 23,
  hour: 12
}, {
  zone: "utc"
});

Здесь важно различать:

  • объектные поля не содержат временной зоны
  • zone задаёт контекст интерпретации

Если не указать zone, используется defaultZone.


Особенности переходов DST

Для зон с переходом на летнее время:

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

Возможны несуществующие локальные времена.

Luxon обрабатывает это следующим образом:

  • корректирует значение до ближайшего валидного времени
  • либо смещает на доступный интервал

Это поведение зависит от внутреннего алгоритма IANA time zone database.


Сравнение одинаковых моментов в разных zone

const utc = DateTime.fromISO("2026-01-15T10:00:00Z");

const tokyo = utc.setZone("Asia/Tokyo");
const ny = utc.setZone("America/New_York");

Один и тот же момент времени:

  • UTC сохраняет исходное значение
  • Tokyo показывает +9 часов
  • New York показывает отрицательное смещение

Zone влияет только на представление, но не на сам timestamp.


Использование zone при сериализации

const dt = DateTime.fromObject(
  { year: 2026, month: 1, day: 15 },
  { zone: "Asia/Almaty" }
);

dt.toISO();

Результат включает offset зоны.

Для UTC:

dt.setZone("utc").toISO();

Влияние zone на сравнение DateTime

Сравнение происходит через абсолютное время:

const a = DateTime.fromObject(
  { hour: 10 },
  { zone: "Asia/Almaty" }
);

const b = DateTime.fromObject(
  { hour: 8 },
  { zone: "UTC" }
);

a.equals(b);

Даже если локальные часы различаются, сравнение учитывает timestamp.


Практическое значение выбора zone

При создании DateTime выбор зоны определяет:

  • интерпретацию входных компонентов
  • корректность работы с локальными календарями
  • поведение при DST
  • стабильность сериализации

Разные зоны могут приводить к разным epoch-значениям даже при одинаковых входных полях, если не задана строгая семантика UTC.