Часовой пояс

Работа с временными зонами в Luxon строится вокруг строгого разделения момента времени и его представления в конкретной зоне. Любая дата в библиотеке описывается через объект DateTime, который всегда включает информацию о зоне, даже если она не указана явно.


Базовое понятие зоны

В Luxon время хранится как абсолютный момент (timestamp), а отображается через часовой пояс (zone).

Ключевые особенности:

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

Пример создания текущего времени:

import { DateTime } from "luxon";

const dt = DateTime.now();

Зона берётся из среды выполнения (браузер или Node.js).


Основные типы временных зон

Luxon опирается на IANA Time Zone Database и поддерживает несколько типов зон.

IANA-зоны

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

DateTime.now().setZone("Europe/Paris");
DateTime.now().setZone("Asia/Almaty");

IANA-зоны учитывают:

  • переходы на летнее/зимнее время;
  • исторические изменения правил;
  • региональные особенности.

UTC-зона

UTC — базовая универсальная зона:

DateTime.now().toUTC();

или:

DateTime.utc();

UTC используется как нейтральная точка отсчёта без смещения.


Смещённые зоны (FixedOffsetZone)

Фиксированные смещения от UTC:

DateTime.now().setZone("UTC+5");

или через объект:

DateTime.fromObject(
  { hour: 10 },
  { zone: "UTC-3" }
);

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

  • не учитывают летнее время;
  • всегда фиксированы;
  • используются для простых вычислений.

Системная зона

Системная зона определяется окружением:

DateTime.local();

Эквивалент:

DateTime.now().zoneName;

Установка и смена временной зоны

setZone

Основной метод переключения зон:

const dt = DateTime.now();
const parisTime = dt.setZone("Europe/Paris");

Важно: момент времени остаётся тем же, меняется только отображение.


Сохранение локального времени

При смене зоны можно сохранить «человеческое» время:

const dt = DateTime.now();

const shifted = dt.setZone("Asia/Tokyo", {
  keepLocalTime: true
});

Поведение:

  • часы, минуты и секунды остаются прежними;
  • изменяется абсолютный момент времени.

Это используется при интерпретации пользовательского ввода.


Конвертация между зонами

Одна из ключевых возможностей Luxon — преобразование одного времени в разные зоны.

const base = DateTime.fromISO("2026-01-01T10:00:00", {
  zone: "UTC"
});

const moscow = base.setZone("Europe/Moscow");
const newYork = base.setZone("America/New_York");

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


Работа с UTC и локальным временем

Перевод в UTC

const local = DateTime.local();
const utc = local.toUTC();

Возврат в локальную зону

const utcTime = DateTime.utc();
const localTime = utcTime.toLocal();

Разница между зонами

Luxon позволяет вычислять разницу между моментами, учитывая зоны:

const a = DateTime.fromISO("2026-01-01T10:00", { zone: "UTC" });
const b = DateTime.fromISO("2026-01-01T10:00", { zone: "Asia/Almaty" });

const diff = a.diff(b, "hours").hours;

Результат учитывает фактическое смещение между зонами.


DST и переходы времени

IANA-зоны включают правила перехода на летнее время.

Пример:

const winter = DateTime.fromISO("2026-01-15", { zone: "Europe/Berlin" });
const summer = DateTime.fromISO("2026-07-15", { zone: "Europe/Berlin" });

console.log(winter.offset);
console.log(summer.offset);

Сдвиг может отличаться в зависимости от сезона.


Проверка и анализ зоны

Получение информации о зоне

const dt = DateTime.now();

console.log(dt.zoneName);
console.log(dt.offset);
  • zoneName — название зоны
  • offset — смещение в минутах от UTC

Проверка фиксированной зоны

dt.isOffsetFixed;

Возвращает true, если зона не учитывает DST.


Работа через Settings

Luxon позволяет задавать глобальную зону по умолчанию:

import { Settings } from "luxon";

Settings.defaultZone = "utc";

или:

Settings.defaultZone = "Europe/Moscow";

После этого все операции используют заданную зону, если не указано иное.


Создание даты с явной зоной

fromObject

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

fromISO с зоной

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

Особенности поведения setZone

Изменение представления

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

const shifted = dt.setZone("Europe/Moscow");

Абсолютное время одинаково, меняется только отображение.


Сохранение локального времени

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

const interpreted = dt.setZone("Europe/Moscow", {
  keepLocalTime: true
});

Теперь 10:00 интерпретируется как московское время, что даёт другой timestamp.


Нормализация зон

Luxon автоматически нормализует некорректные зоны:

  • неизвестные IANA-зоны приводят к invalid DateTime;
  • неправильные строки могут быть интерпретированы как fixed offset или UTC.

Проверка:

const dt = DateTime.fromISO("2026-01-01", { zone: "Invalid/Zone" });

dt.isValid;

Влияние зоны на форматирование

Форматирование всегда зависит от текущей зоны объекта:

const dt = DateTime.now().setZone("Asia/Tokyo");

dt.toLocaleString(DateTime.DATETIME_FULL);

При смене зоны изменяется:

  • часовой пояс;
  • смещение;
  • итоговое отображение времени.

Сравнение временных зон

При сравнении учитывается абсолютный момент:

const a = DateTime.fromISO("2026-01-01T10:00", { zone: "UTC" });
const b = DateTime.fromISO("2026-01-01T15:00", { zone: "Asia/Almaty" });

console.log(a.equals(b));

Результат зависит от совпадения timestamp, а не строкового представления.


Практика работы с несколькими зонами

Типовой сценарий:

const utc = DateTime.utc();

const zones = [
  "Europe/London",
  "Europe/Moscow",
  "Asia/Tokyo"
];

const mapped = zones.map(zone =>
  utc.setZone(zone).toISO()
);

Каждая строка отражает один и тот же момент времени в разных регионах.


Итоговая модель поведения зон

Luxon использует единую модель:

  • хранение: абсолютное время (timestamp)
  • отображение: зона (IANA / UTC / offset)
  • преобразование: setZone без изменения момента
  • интерпретация: keepLocalTime изменяет смысл времени

Эта модель обеспечивает предсказуемость при работе с распределёнными системами, API и пользовательскими интерфейсами, где данные поступают из разных часовых поясов.