Класс Zone

Класс Zone в Luxon представляет слой абстракции над часовыми поясами и смещениями времени. Он не хранит дату или время, а описывает правила интерпретации времени относительно UTC: смещение, переходы на летнее время, идентификатор зоны и поведение форматирования. Именно через Zone осуществляется вся работа Luxon с временными зонами в DateTime.

Внутренняя архитектура построена на полиморфизме: Zone выступает базовым классом, а конкретные реализации разделяются на специализированные типы, такие как IANA-зоны, фиксированные смещения и невалидные зоны.


Базовая роль Zone в модели времени Luxon

Любой объект DateTime в Luxon содержит ссылку на зону:

  • DateTime.zone — экземпляр Zone

  • зона определяет:

    • смещение относительно UTC
    • название зоны для конкретного момента времени
    • правила форматирования offset
    • корректность зоны

Таким образом, Zone — это не просто строка вроде "Europe/Paris", а полноценный объект, способный вычислять поведение времени в зависимости от timestamp.


Иерархия классов Zone

Базовый класс Zone является абстрактным и не используется напрямую. Реальные экземпляры создаются через подклассы:

IANAZone

Представляет зоны из базы IANA ("Europe/Moscow", "Asia/Almaty").

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

  • поддерживает переходы на летнее/зимнее время
  • использует системные или встроенные данные о временных правилах
  • зависит от окружения (Intl API или встроенная база Luxon)

FixedOffsetZone

Представляет фиксированное смещение от UTC:

  • "UTC+2", "+0300"
  • не имеет переходов времени
  • offset постоянен для всех timestamp

InvalidZone

Используется при ошибках парсинга зоны:

  • некорректная строка зоны
  • отсутствующая IANA зона
  • результат защитных механизмов Luxon

Создание экземпляров Zone

Zone.create(name)

Основной способ создания зоны из строки.

Поведение:

  • если строка соответствует IANA идентификатору → создаётся IANAZone
  • если строка выглядит как фиксированный offset → создаётся FixedOffsetZone
  • иначе → InvalidZone

Пример логики:

  • "Europe/London" → IANAZone
  • "+03:00" → FixedOffsetZone
  • "Mars/Phobos" → InvalidZone

Zone.invalid(reason)

Создаёт экземпляр невалидной зоны.

Используется внутри Luxon при ошибках разбора:

  • некорректные входные данные
  • невозможность интерпретации строки зоны

Объект остаётся безопасным для использования: вместо падения возвращается InvalidZone, который возвращает предсказуемые значения.


Основные свойства Zone

name

Строковое имя зоны.

  • у IANAZone: "Europe/Berlin"
  • у FixedOffsetZone: строковое представление смещения
  • у InvalidZone: служебное имя

isValid

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

  • true — IANAZone и FixedOffsetZone
  • false — InvalidZone

Используется для защиты цепочек вычислений DateTime.


type

Строковый идентификатор типа зоны:

  • "iana"
  • "fixed"
  • "invalid"

Позволяет быстро различать стратегию обработки без instanceof.


Методы класса Zone

offset(ts)

Возвращает смещение зоны в минутах для конкретного timestamp.

Сигнатура:

offset(ts: number): number

Параметр ts — Unix-время в миллисекундах.

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

  • для IANAZone смещение зависит от даты (учёт DST)
  • для FixedOffsetZone возвращается константа
  • для InvalidZone обычно возвращается 0

Пример логики:

  • Europe/Moscow:

    • зимой: +180 минут
    • летом (если применимо): может изменяться
  • UTC+2: всегда +120 минут


offsetName(ts, options)

Возвращает человекочитаемое имя смещения или зоны.

Сигнатура:

offsetName(ts: number, options?: object): string

Поведение зависит от реализации:

  • IANAZone:

    • может вернуть "GMT+3", "EET", "MSK" (если доступны алиасы)
  • FixedOffsetZone:

    • возвращает строку вида "+03:00"
  • InvalidZone:

    • обычно пустая строка

Параметры options позволяют контролировать форматирование (например, выбор short/long формата через Intl, если используется системная поддержка).


formatOffset(ts, format)

Форматирует смещение в строку.

Сигнатура:

formatOffset(ts: number, format?: string): string

Типичные форматы:

  • +03:00
  • +0300
  • Z для UTC

Поведение:

  • IANAZone вычисляет offset и форматирует его
  • FixedOffsetZone возвращает предсказуемую строку без вычислений
  • InvalidZone возвращает пустой результат или +00:00 в зависимости от контекста Luxon

equals(otherZone)

Сравнение зон.

Сигнатура:

equals(other: Zone): boolean

Сравнение происходит по логике:

  • одинаковый тип
  • одинаковое имя
  • для FixedOffsetZone — одинаковое смещение
  • для IANAZone — совпадение идентификатора

Примеры равенства:

  • Zone.create("Europe/Moscow")Zone.create("UTC")
  • FixedOffsetZone(+180) == FixedOffsetZone(+180)

toString()

Возвращает строковое представление зоны.

Формат зависит от типа:

  • IANAZone → "Europe/Paris"
  • FixedOffsetZone → "+03:00"
  • InvalidZone → "InvalidZone"

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


Поведение IANAZone

IANAZone — наиболее сложная реализация, так как учитывает:

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

Вычисление offset

Для каждого timestamp происходит:

  1. определение периода (DST или стандартное время)
  2. выбор соответствующего правила
  3. вычисление смещения в минутах

Это делает IANAZone динамической относительно времени.


Поведение FixedOffsetZone

FixedOffsetZone представляет упрощённую модель:

  • нет календарной логики
  • нет переходов времени
  • offset постоянен

Используется для:

  • UTC-смещения из API
  • ручных временных вычислений
  • нормализации времени

Поведение InvalidZone

InvalidZone является защитным механизмом Luxon.

Характеристики:

  • все вычисления безопасны
  • offset возвращает нейтральные значения
  • форматирование не вызывает ошибок
  • isValid всегда false

Используется как результат fallback-логики при парсинге:

  • некорректные строки зон
  • отсутствующие идентификаторы IANA
  • ошибки окружения Intl

Взаимодействие Zone и DateTime

Каждый DateTime хранит ссылку на Zone:

  • DateTime.zone.offset(ts) определяет локальное время
  • DateTime.setZone(...) заменяет экземпляр Zone
  • арифметика времени учитывает offset из Zone

Пример поведения:

  • UTC timestamp одинаков
  • локальное отображение зависит от Zone
  • форматирование (toString, toISO) использует Zone

Роль Zone в форматировании времени

Zone участвует в:

  • вычислении локального времени
  • генерации строковых представлений
  • конвертации между зонами

При вызове:

  • toISO()
  • toFormat()
  • toLocaleString()

внутренне используется:

  • offset(ts)
  • formatOffset(ts)

Особенности внутренней модели

Luxon использует Zone как стратегию вычисления времени:

  • базовый интерфейс → Zone
  • конкретные стратегии → подклассы
  • отсутствие прямой мутации

Это обеспечивает:

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

Типичные сценарии использования Zone внутри Luxon

  • конвертация UTC → локальное время
  • определение смещения для timestamp
  • отображение времени в UI
  • сериализация временных значений
  • обработка API-дат с разными зонами

Zone выступает центральным элементом между:

  • сырыми timestamp
  • календарной логикой
  • человекочитаемым временем