Цепочка настроек

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

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

Ключевое следствие:

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

Базовый паттерн цепочки:

DateTime.now()
  .setZone('Europe/Paris')
  .plus({ days: 3 })
  .setLocale('ru')
  .toFormat('yyyy-MM-dd HH:mm')

Каждый вызов возвращает новый DateTime, позволяя последовательно наращивать трансформации.

Цепочка временных преобразований

Смещение во времени

Методы plus и minus формируют основу временных цепочек. Они принимают объект с единицами времени и возвращают новый экземпляр.

DateTime.now()
  .plus({ hours: 2 })
  .plus({ minutes: 30 })
  .minus({ seconds: 10 })

Несмотря на множественные вызовы, вычисление остаётся детерминированным, так как каждый шаг опирается на результат предыдущего.

Комбинирование календарных единиц

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

DateTime.now()
  .plus({ days: 1 })
  .plus({ weeks: 2 })
  .minus({ months: 1 })

При этом календарная арифметика учитывает особенности месяцев разной длины и переходы между годами.

Цепочка работы с часовыми поясами

Работа с зонами времени является одной из ключевых возможностей цепочного API.

Метод setZone создаёт новый объект с пересчётом времени в указанной зоне:

DateTime.now()
  .setZone('UTC')
  .plus({ hours: 5 })
  .setZone('Asia/Almaty')

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

Особенность цепочки зон:

  • преобразование всегда основано на UTC-опоре;
  • повторные setZone не накапливают смещения;
  • порядок вызовов влияет на итоговое локальное представление, но не на сам момент времени.

Цепочка локализации

Метод setLocale влияет на форматирование, но не изменяет саму временную сущность.

DateTime.now()
  .setLocale('en')
  .setLocale('ru')
  .toFormat('MMMM dd')

В цепочке сохраняется последнее установленное значение локали. Промежуточные вызовы не сохраняются как история — они перезаписывают состояние нового объекта.

Локаль влияет на:

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

Цепочка календарных систем

Luxon поддерживает альтернативные календари через настройку outputCalendar.

DateTime.now()
  .setLocale('ar')
  .reconfigure({ outputCalendar: 'islamic' })
  .toISODate()

Метод reconfigure участвует в цепочках как точка переопределения внутренних настроек. Он создаёт новый объект с изменёнными параметрами конфигурации.

Цепочка форматирования

Финальный этап большинства цепочек — преобразование в строку или примитивное значение.

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

DateTime.now()
  .plus({ days: 7 })
  .setZone('UTC')
  .toFormat('yyyy LLL dd')

Метод toFormat завершает цепочку, возвращая строку.

ISO-представления

DateTime.now()
  .setZone('local')
  .toISO()

или

DateTime.now()
  .toISO({ suppressMilliseconds: true })

Форматирование ISO не изменяет объект, а лишь сериализует его текущее состояние.

Цепочка разборов и преобразований

Парсинг часто используется как стартовая точка цепочек:

DateTime.fromISO('2026-01-01T10:00:00')
  .setZone('UTC')
  .plus({ days: 10 })
  .toFormat('dd.MM.yyyy')

Парсинг создаёт базовый DateTime, к которому применяются дальнейшие трансформации.

Дополнительные фабрики:

DateTime.fromJSDate(new Date())
  .plus({ hours: 1 })
DateTime.fromMillis(0)
  .setZone('Europe/London')

Цепочки конфигурации через Settings

Глобальные настройки влияют на все создаваемые объекты, но также могут комбинироваться с локальными вызовами.

Settings.defaultZone = 'UTC'
Settings.defaultLocale = 'en'

Далее локальные цепочки могут переопределять глобальные значения:

DateTime.now()
  .setZone('Europe/Paris')
  .setLocale('fr')
  .toFormat('dd LLLL')

Приоритеты:

  1. локальные вызовы (setZone, setLocale);
  2. глобальные Settings;
  3. системные значения среды выполнения.

Композиция цепочек

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

DateTime.fromISO('2026-03-01T08:00:00')
  .setZone('UTC')
  .plus({ weeks: 1, hours: 3 })
  .setZone('Asia/Almaty')
  .setLocale('ru')
  .toFormat('cccc, dd LLL yyyy HH:mm')

Такая композиция отражает полный цикл обработки временного значения: от исходного парсинга до локализованного представления.

Условные цепочки и разветвления

Так как каждый шаг возвращает новый объект, цепочка может быть разорвана промежуточными переменными:

const base = DateTime.now().setZone('UTC')

const future = base.plus({ days: 5 })

const formatted = future.toISO()

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

Поведение при ошибках в цепочках

Любая ошибка в одном из звеньев цепочки приводит к появлению Invalid DateTime. Дальнейшие вызовы сохраняются, но результат остаётся невалидным.

DateTime.fromISO('invalid')
  .plus({ days: 1 })
  .toFormat('yyyy')

Проверка состояния:

  • isValid указывает на корректность результата;
  • invalidReason описывает причину сбоя.

Согласованность цепочек

Цепочный стиль в Luxon поддерживает строгую детерминированность:

  • порядок вызовов фиксирует результат;
  • отсутствуют скрытые мутации;
  • каждый шаг независим от внешнего состояния, кроме глобального Settings.

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