Научитесь использовать 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 и о том, как использовать его фабричные методы для управления датами в сложных случаях использования.