Цепочки вызовов

Библиотека Luxon построена вокруг принципа неизменяемости (immutability). Каждый объект даты и времени представляет собой самостоятельное значение, которое не модифицируется после создания. Любая операция — добавление дней, смена часового пояса, округление — возвращает новый экземпляр.

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

import { DateTime } from "luxon";

const dt = DateTime.now();

Объект dt остаётся неизменным независимо от дальнейших операций.


Принцип формирования цепочек методов

Цепочка вызовов в Luxon — это последовательное применение методов, каждый из которых возвращает новый объект DateTime. Благодаря этому возможно строить компактные и выразительные выражения преобразования даты.

const result = DateTime.now()
  .setZone("Europe/Moscow")
  .plus({ days: 3 })
  .minus({ hours: 5 })
  .startOf("day");

Каждый метод в цепочке:

  • принимает текущее состояние даты;
  • выполняет преобразование;
  • возвращает новый экземпляр DateTime.

Исходный объект не изменяется ни на одном этапе.


Основные методы, поддерживающие цепочки

setZone

Метод изменяет часовой пояс объекта времени.

DateTime.now()
  .setZone("UTC")
  .toString();

Применение setZone особенно важно при работе с международными временными данными, где требуется приведение к единому стандарту.


plus и minus

Методы plus и minus выполняют арифметические операции над датой.

DateTime.now()
  .plus({ days: 10 })
  .minus({ minutes: 30 });

Поддерживаются следующие единицы:

  • years
  • months
  • weeks
  • days
  • hours
  • minutes
  • seconds
  • milliseconds

Цепочное использование позволяет строить сложные временные смещения без промежуточных переменных.


startOf и endOf

Методы округления времени до начала или конца указанного интервала.

DateTime.now()
  .startOf("month")
  .endOf("day");

Часто применяются для построения диапазонов дат:

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

set и setLocale

Метод set позволяет изменять отдельные компоненты даты.

DateTime.now()
  .set({ hour: 9, minute: 0 });

Метод setLocale задаёт локализацию отображения даты.

DateTime.now()
  .setLocale("ru")
  .toLocaleString(DateTime.DATE_FULL);

Оба метода органично встраиваются в цепочки без нарушения структуры данных.


Формирование сложных временных выражений

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

const deadline = DateTime.now()
  .setZone("UTC")
  .plus({ days: 14 })
  .startOf("day")
  .minus({ hours: 3 });

Такая конструкция эквивалентна последовательному выполнению:

  1. получение текущего времени;
  2. перевод в UTC;
  3. добавление 14 дней;
  4. округление до начала дня;
  5. смещение на 3 часа назад.

Комбинирование с форматированием

Цепочки часто завершаются преобразованием в строку или число.

const isoString = DateTime.now()
  .setZone("Europe/Paris")
  .plus({ hours: 2 })
  .toISO();
const timestamp = DateTime.now()
  .minus({ days: 1 })
  .toMillis();

Финальные методы:

  • toISO()
  • toString()
  • toLocaleString()
  • toMillis()

разрывают цепочку, возвращая примитивное значение.


Условные цепочки через промежуточные переменные

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

let dt = DateTime.now();

dt = dt.setZone("UTC");

if (true) {
  dt = dt.plus({ days: 5 });
}

dt = dt.startOf("hour");

Каждое присваивание фактически продолжает цепочку, сохраняя иммутабельность.


Поведение при ошибочных значениях

Luxon сохраняет цепочечный интерфейс даже при некорректных операциях. Вместо исключений создаётся объект с состоянием Invalid.

const dt = DateTime.now()
  .setZone("Invalid/Zone")
  .plus({ days: 2 });

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

dt.isValid;
dt.invalidReason;

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


Композиция цепочек и переиспользование логики

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

const normalizeToBusinessDay = (dt) =>
  dt.setZone("UTC")
    .startOf("day")
    .plus({ hours: 9 });

const result = normalizeToBusinessDay(DateTime.now())
  .plus({ days: 1 });

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


Порядок вызовов и его влияние на результат

Порядок методов в цепочке напрямую влияет на итоговое значение.

DateTime.now()
  .plus({ days: 1 })
  .startOf("day");

и

DateTime.now()
  .startOf("day")
  .plus({ days: 1 });

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


Ограничения цепочного подхода

Несмотря на гибкость, цепочки требуют внимательного контроля порядка операций:

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

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