Работа с Temporal интерфейсом

В библиотеке js-joda работа со временем строится вокруг унифицированной модели временных типов, основанной на идеях Java Time API. Центральное место занимает контракт Temporal, определяющий набор операций, применимых к любому объекту, представляющему момент или календарную сущность.

Temporal описывает поведение объектов, которые поддерживают арифметику времени: добавление и вычитание единиц, модификацию отдельных полей и взаимодействие с корректировщиками временных значений.


Иерархия временных абстракций

В основе модели лежит несколько взаимосвязанных интерфейсов:

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

Temporal Расширяет TemporalAccessor и добавляет возможность модификации временных значений. Определяет операции изменения, включая добавление единиц времени и применение корректировщиков.

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

Эта структура формирует разделение между доступом к данным и их трансформацией.


Базовые операции Temporal

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

Арифметика времени

Ключевым механизмом выступают операции добавления и вычитания:

  • добавление временных единиц (дни, часы, минуты, месяцы);
  • вычитание временных интервалов;
  • поддержка как фиксированных, так и календарных единиц.

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

const date = LocalDate.of(2024, 5, 10);
const result = date.plusDays(5);

Операция не изменяет исходное значение, а формирует производное состояние.


Корректировка временных значений

Механизм with(…) реализует точечное изменение отдельных полей временного объекта. Temporal определяет поведение, при котором изменение одного компонента не затрагивает остальные.

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

  • установка конкретного значения поля;
  • применение предопределённых корректоров;
  • перенос к ближайшим допустимым значениям календаря.
const date = LocalDate.of(2024, 5, 10);
const adjusted = date.withMonth(12);

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


TemporalAccessor как базовый слой чтения

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

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

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


TemporalAdjuster и стратегия преобразования

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

  • вход: произвольный Temporal;
  • выход: модифицированный Temporal.

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

const lastDay = TemporalAdjusters.lastDayOfMonth();
const result = date.with(lastDay);

Корректировщик инкапсулирует правила изменения, отделяя их от самих временных объектов.


Реализация Temporal в основных типах js-joda

Различные классы библиотеки реализуют Temporal-поведение на разных уровнях детализации времени.

LocalDate

LocalDate представляет календарную дату без временной зоны и времени суток. Поддерживает:

  • добавление дней, месяцев, лет;
  • изменение отдельных полей даты;
  • применение календарных корректировщиков.

Арифметика учитывает календарные правила, включая различную длину месяцев.


LocalTime

LocalTime описывает время суток без привязки к дате. Temporal-операции включают:

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

LocalDateTime

LocalDateTime объединяет дату и время без зоны. Поведение Temporal операций включает комбинированную корректировку:

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

Instant

Instant представляет абсолютный момент времени в UTC. Temporal операции здесь ориентированы на:

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

Длительности и периоды в контексте Temporal

Временные преобразования используют два различных типа интервалов:

Duration Представляет точный интервал времени в секундах и наносекундах. Применяется к линейным шкалам времени, таким как Instant.

Period Описывает календарные интервалы: годы, месяцы, дни. Используется с типами, содержащими календарную структуру.

Разделение этих сущностей влияет на поведение Temporal операций: одинаковое количество дней может интерпретироваться по-разному в зависимости от контекста.


Неизменяемость временных объектов

Модель Temporal в js-joda основана на неизменяемости. Любая операция:

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

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

const base = LocalDate.of(2024, 1, 1);
const modified = base.plusMonths(2).plusDays(10);

Каждый этап вычисления формирует независимое промежуточное значение.


Семантика поддерживаемых единиц времени

Temporal определяет набор стандартных единиц, используемых в операциях:

  • наносекунды;
  • секунды;
  • минуты;
  • часы;
  • дни;
  • недели;
  • месяцы;
  • годы.

Поддержка единицы зависит от конкретного типа. Например, Instant не оперирует месяцами, тогда как LocalDate поддерживает календарные единицы.


Совместимость временных типов через Temporal

Единый интерфейс Temporal позволяет унифицировать операции над разными типами времени. Общие алгоритмы могут работать с абстракцией, не привязываясь к конкретной реализации.

Поведение операций определяется конкретным классом, но контракт остаётся одинаковым:

  • plus / minus реализуются во всех Temporal;
  • with обеспечивает точечную модификацию;
  • adjustInto используется через TemporalAdjuster.

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

Модель операций поддерживает композицию:

  • последовательное добавление интервалов;
  • комбинирование корректировщиков;
  • каскадное изменение временных полей.

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

const result = LocalDateTime
  .of(2024, 1, 1, 10, 0)
  .plusDays(3)
  .plusHours(5)
  .withMinute(30);

Каждая операция интерпретируется в рамках контракта Temporal и сохраняет согласованность типов.