Эра и смещение

В календарной системе Luxon используется григорианская шкала с поддержкой исторического разделения времени на эпохи. Под эпохой понимается метка, отражающая положение даты относительно условной точки отсчёта — до и после начала текущей эры.

В рамках объекта DateTime значение эры доступно через свойство era. Оно принимает ограниченный набор строковых значений, отражающих положение даты в исторической шкале.

Основные значения эры:

  • AD — текущая эра (Anno Domini)
  • BC — до нашей эры (Before Christ)

При работе с датами Luxon автоматически определяет эру на основе года:

import { DateTime } from "luxon";

const dt1 = DateTime.local(2026, 5, 23);
console.log(dt1.era); // "AD"

const dt2 = DateTime.local(-100, 1, 1);
console.log(dt2.era); // "BC"

Эра тесно связана с годовым значением, но не заменяет его. Год в Luxon всегда остаётся числовым, а эра служит дополнительным контекстом интерпретации.


Год в контексте эры

В Luxon используется астрономическая нумерация лет, где отрицательные значения соответствуют периодам до начала нашей эры. Однако для отображения исторических данных важна комбинация двух параметров: year и era.

const dt = DateTime.local(-44, 3, 15);

console.log(dt.year); // -44
console.log(dt.era);  // "BC"

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


Смещение (offset) и его роль

Смещение времени — ключевой элемент работы с часовыми поясами. Оно определяет разницу между локальным временем зоны и UTC в минутах.

В Luxon смещение доступно через свойство:

DateTime.offset

Представление смещения

Смещение выражается в минутах относительно UTC:

const dt = DateTime.local();
console.log(dt.offset);

Примеры значений:

  • 0 — UTC
  • 180 — UTC+3
  • -300 — UTC−5

Смещение является динамическим значением и зависит от текущей временной зоны и правил перехода на летнее/зимнее время.


Часовые пояса и их влияние на offset

Luxon использует IANA Time Zone Database для определения правил временных зон. Это означает, что смещение не является фиксированным числом для зоны, а может изменяться во времени.

import { DateTime } from "luxon";

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

console.log(dt.offset); // зависит от сезона

В летний период значение смещения может увеличиваться из-за перехода на летнее время.


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

Метод setZone изменяет временную зону объекта DateTime, что автоматически пересчитывает смещение.

const dt = DateTime.local();

const berlin = dt.setZone("Europe/Berlin");
const tokyo = dt.setZone("Asia/Tokyo");

console.log(berlin.offset);
console.log(tokyo.offset);

Важное поведение setZone

При смене зоны существует два принципиальных режима:

  • пересчёт абсолютного момента времени
  • сохранение локального времени

Пример сохранения локального времени:

const dt = DateTime.local(2026, 5, 23, 12, 0);

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

В этом случае изменяется интерпретация времени, но не сам набор числовых компонентов.


UTC и нормализация смещения

UTC представляет собой базовую систему отсчёта, в которой смещение равно нулю. Luxon предоставляет методы для перехода в UTC-режим.

const dt = DateTime.local(2026, 5, 23, 12, 0);

const utc = dt.toUTC();

console.log(utc.offset); // 0

Обратное преобразование возвращает локальную интерпретацию:

const local = utc.toLocal();

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


Форматирование смещения

Luxon позволяет получать человекочитаемое представление смещения через методы форматирования.

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

console.log(dt.toFormat("Z"));   // +03:00
console.log(dt.toFormat("ZZ"));  // GMT+3

Также доступны свойства:

  • offset — числовое значение в минутах
  • offsetNameShort — краткое имя зоны
  • offsetNameLong — полное имя
console.log(dt.offsetNameShort);
console.log(dt.offsetNameLong);

Смещение и переходы летнего времени

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

const winter = DateTime.fromObject(
  { year: 2026, month: 1, day: 15 },
  { zone: "Europe/Berlin" }
);

const summer = DateTime.fromObject(
  { year: 2026, month: 7, day: 15 },
  { zone: "Europe/Berlin" }
);

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

Разница между значениями отражает переход на летнее время.


Взаимосвязь эры и смещения

Эра и смещение относятся к разным уровням модели времени:

  • эра описывает историческую шкалу (BC/AD)
  • смещение описывает географическую локализацию момента времени

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

const dt = DateTime.fromObject(
  { year: -50, month: 6, day: 1 },
  { zone: "UTC" }
);

console.log(dt.era);    // "BC"
console.log(dt.offset); // 0

В современном календарном использовании смещение не применяется к историческим датам напрямую, однако Luxon сохраняет единообразие модели представления времени.


Особенности парсинга ISO-строк со смещением

При разборе ISO-формата Luxon извлекает смещение из строки и фиксирует его как часть временного контекста.

const dt = DateTime.fromISO("2026-05-23T10:00:00+03:00");

console.log(dt.offset); // 180

Если указано Z, смещение интерпретируется как UTC:

const dt = DateTime.fromISO("2026-05-23T10:00:00Z");

console.log(dt.offset); // 0

Нормализация и сохранение момента времени

Любое значение DateTime в Luxon можно рассматривать как комбинацию:

  • абсолютного момента времени (timestamp)
  • локальной интерпретации (zone + offset)
  • календарных компонентов (year, month, day, era)

При изменении зоны или смещения изменяется только интерпретация, но не сам момент.

const dt = DateTime.local(2026, 5, 23, 12, 0);

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

console.log(dt.toISO());
console.log(shifted.toISO());

Практическое использование эры и смещения в одной модели

Совместная работа с историческими данными и временными зонами требует строгого разделения смыслов.

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

const dt = DateTime.fromObject(
  { year: -300, month: 4, day: 10 },
  { zone: "UTC" }
);

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

console.log(dt.era);
console.log(shifted.offset);

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