Java TemporalAdjusters – Расчет повторяющихся дат

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

1. Обзор

В новом Java Date API интерфейс Temporal представляет дату, время или их комбинацию. Например, LocalDate, LocalDateTime и т. д.

TemporalAdjuster позволяет нам выполнять сложные вычисления даты и времени, такие как:

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

Названия большинства из них говорят вам прямо, что они делают. Если предоставленные корректоры не решают конкретные бизнес-требования, мы можем создать свой собственный TemporalAdjuster.

Затем мы можем применить его к любому временному объекту, используя метод with() этого объекта даты/времени. Например, в команде всегда есть еженедельное собрание каждый понедельник, а затем вычисляется список дат для следующих пяти собраний.

LocalDate localDate = LocalDate.of(2020, 5, 9);List<LocalDate> meetingDates = getWeeklyMeetingDates(localDate, 5);private static List<LocalDate> getWeeklyMeetingDates(LocalDate localDate, int count) {return Stream.iterate(localDate.with(TemporalAdjusters.next(DayOfWeek.MONDAY)),date -> date.with(TemporalAdjusters.next(DayOfWeek.MONDAY))).limit(count).collect(Collectors.toList());}

Вывод программы.

[2020-05-11,2020-05-18,2020-05-25,2020-06-01,2020-06-08]

2. Предопределенные корректировщики

Это список стандартных корректоров для простоты использования. Для получения подробной информации посетите официальный Java Doc.

Регулировщик Описание
первыйДеньМесяца() возвращает новую дату, устанавливая ее на первый день текущего месяца.
последнийДеньМесяца() возвращает новую дату, установленную на последний день текущего месяца.
первыйДеньСледующегоМесяца() возвращает новую дату, установленную на первый день следующего месяца.
первыйДеньГода() возвращает новую дату, установленную на первый день текущего года.
последнийДеньГода() возвращает новую дату, установленную на последний день текущего года.
первыйДеньСледующегоГода() возвращает новую дату, установленную на первый день следующего года.
первыйВМесяце() возвращает дату первого вхождения указанного дня недели перед скорректированной датой.
последнийВМесяце() возвращает новую дату в том же месяце с последним соответствующим днем недели.
деньНеделиВМесяце() возвращает новую дату в том же месяце с порядковым днем недели.
следующий() возвращает дату первого появления указанного дня недели после корректируемой даты.
предыдущий() возвращает дату первого появления указанного дня недели перед корректируемой датой.

Например, следующая программа Java демонстрирует использование этих методов для простых вариантов использования.

LocalDate localdate = localdate;// Calculate the first day of the current monthLocalDate firstDayOfMonth = localdate.with(TemporalAdjusters.firstDayOfMonth());// Calculate the last day of the current monthLocalDate lastDayOfMonth = localdate.with(TemporalAdjusters.lastDayOfMonth());// Calculate the first day of the next monthLocalDate firstDayNextMonth = localdate.with(TemporalAdjusters.firstDayOfNextMonth());// Calculate the next FridayLocalDate nextFriday = localdate.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));// Calculate the previous WednesdayLocalDate previousWednesday = localdate.with(TemporalAdjusters.previous(DayOfWeek.WEDNESDAY));// Calculate the last Sunday of the current monthLocalDate lastSundayOfMonth = localdate.with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));// Calculate the first Monday of the current yearLocalDate firstMondayOfYear = localdate.with(TemporalAdjusters.firstDayOfYear()).with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY));// Calculate the next working day(assuming Saturday and Sunday are weekends)LocalDate nextWorkingDay = localdate.with(date -> {DayOfWeek day = date.getDayOfWeek();return day == DayOfWeek.FRIDAY ? date.plusDays(3) : day == DayOfWeek.SATURDAY ? date.plusDays(2) : date.plusDays(1);});

3. Пользовательские корректоры

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

  • Реализовать интерфейс TemporalAdjuster
  • Встроенное лямбда-выражение
//1. With TemporalAdjuster interfaceclass NextBirthDay implements TemporalAdjuster{@Overridepublic Temporal adjustInto(Temporal temporal){return temporal.with(ChronoField.MONTH_OF_YEAR, 11).with(ChronoField.DAY_OF_MONTH, 22);}}//2. With lambda expressionsTemporalAdjuster temporalAdjuster = t -> t.plus(Period.ofDays(7));

4. Заключение

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

Исходный код Скачать

Прокрутить вверх