Temporal API

Базовый Java
≈ 2 мин чтения

Общие детали разных классов времени

У LocalDate, LocalDateTime, Instant и ZonedDateTime разные задачи, но многие операции у них похожи: прочитать поле, прибавить единицу времени, проверить поддержку поля или выполнить корректировку. Эти общие возможности собраны вокруг Temporal API.

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

Temporal и TemporalAccessor

TemporalAccessor описывает объект, из которого можно читать временные поля. Temporal добавляет возможность создавать изменённые значения через операции вроде with(), plus() и minus().

Например, форматтер умеет работать с TemporalAccessor, поэтому один механизм форматирования подходит разным классам даты и времени.

ChronoUnit — единицы времени

Вместо отдельного метода для каждой ситуации можно передать единицу явно. ChronoUnit содержит стандартные единицы от наносекунд до лет.

LocalDate date = LocalDate.of(2026, 9, 18);
LocalDate later = date.plus(10, ChronoUnit.DAYS);

long days = ChronoUnit.DAYS.between(date, later);

Не каждый временной тип поддерживает каждую единицу. Например, у LocalDate нет времени суток, поэтому прибавление часов к нему не имеет смысла и завершится ошибкой.

ChronoField — поля времени

ChronoField представляет стандартные поля вроде дня месяца, месяца года или часа суток. Конкретные методы, такие как getYear(), обычно читаются лучше, но поля полезны в обобщённом коде.

LocalDate date = LocalDate.of(2026, 9, 18);
int day = date.get(ChronoField.DAY_OF_MONTH);

TemporalAdjusters — готовые календарные корректировки

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

LocalDate date = LocalDate.of(2026, 9, 18);
LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfMonth());

Или ближайший следующий понедельник:

LocalDate monday = date.with(
        TemporalAdjusters.next(DayOfWeek.MONDAY)
);
Не обобщай раньше времени. Если метод действительно работает только с датой, параметр LocalDate обычно понятнее абстрактного Temporal. Общие интерфейсы полезны тогда, когда общность является частью задачи.