В библиотеке js-joda работа со временем строится вокруг унифицированной модели временных типов, основанной на идеях Java Time API. Центральное место занимает контракт Temporal, определяющий набор операций, применимых к любому объекту, представляющему момент или календарную сущность.
Temporal описывает поведение объектов, которые поддерживают арифметику времени: добавление и вычитание единиц, модификацию отдельных полей и взаимодействие с корректировщиками временных значений.
В основе модели лежит несколько взаимосвязанных интерфейсов:
TemporalAccessor Представляет базовый уровень доступа к временным данным. Обеспечивает чтение значений полей, таких как год, месяц, день, час, минута. Не гарантирует возможности изменения.
Temporal Расширяет TemporalAccessor и добавляет возможность модификации временных значений. Определяет операции изменения, включая добавление единиц времени и применение корректировщиков.
TemporalAdjuster Отдельный контракт, описывающий стратегию преобразования временного объекта в другой. Используется для сложных правил модификации дат и времени.
Эта структура формирует разделение между доступом к данным и их трансформацией.
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 обеспечивает унифицированный доступ к временным полям без раскрытия полной модели объекта. Через него реализуется:
Этот уровень используется для работы с неоднородными временными структурами, где набор доступных полей может различаться.
TemporalAdjuster вводит отдельный слой логики трансформации временных объектов. Он описывает функцию преобразования:
Данный механизм используется для реализации сложных календарных правил, таких как переход к последнему дню месяца или следующему рабочему дню.
const lastDay = TemporalAdjusters.lastDayOfMonth();
const result = date.with(lastDay);
Корректировщик инкапсулирует правила изменения, отделяя их от самих временных объектов.
Различные классы библиотеки реализуют Temporal-поведение на разных уровнях детализации времени.
LocalDate представляет календарную дату без временной зоны и времени суток. Поддерживает:
Арифметика учитывает календарные правила, включая различную длину месяцев.
LocalTime описывает время суток без привязки к дате. Temporal-операции включают:
LocalDateTime объединяет дату и время без зоны. Поведение Temporal операций включает комбинированную корректировку:
Instant представляет абсолютный момент времени в UTC. 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-объект, формируя детерминированную цепочку вычислений, в которой промежуточные состояния сохраняют неизменность исходных данных.
const result = LocalDateTime
.of(2024, 1, 1, 10, 0)
.plusDays(3)
.plusHours(5)
.withMinute(30);
Каждая операция интерпретируется в рамках контракта Temporal и сохраняет согласованность типов.