1. Обзор
В этом уроке мы быстро рассмотрим TemporalAdjuster и используем его в нескольких практических сценариях.
Java 8 представила новую библиотеку для работы с датами и временем – java.time и TemporalAdjuster является ее частью. Если вы хотите узнать больше о java.time, проверьте эту вводную статью.
Проще говоря, TemporalAdjuster – это стратегия настройки Temporal объекта. Прежде чем приступить к использованию TemporalAdjuster , давайте взглянем на сам интерфейс Temporal|/.
2. Временная
A Temporal определяет представление даты, времени или их комбинацию, в зависимости от реализации, которую мы собираемся использовать.
Существует ряд реализаций интерфейса Temporal , в том числе:
- LocalDate – который представляет дату без часового пояса
- LocalDateTime – который представляет дату и время без часового пояса
- HijrahDate – который представляет дату в календарной системе хиджры
- MinguoDate – который представляет дату в календарной системе Minguo
- ThaiBuddhistDate – который представляет собой дату в тайской буддийской календарной системе
3. TemporalAdjuster
Одним из интерфейсов, включенных в эту новую библиотеку, является TemporalAdjuster .
TemporalAdjuster – это функциональный интерфейс, который имеет множество предопределенных реализаций в классе TemporalAdjusters . Интерфейс имеет один абстрактный метод с именем adjustInto () , который может быть вызван в любой из его реализаций путем передачи ему Временного объекта.
TemporalAdjuster позволяет нам выполнять сложные манипуляции с данными. Например , мы можем получить дату следующего воскресенья, последнего дня текущего месяца или первого дня следующего года. Конечно, мы можем сделать это, используя старый java.util.Календарь .
Однако новый API абстрагирует базовую логику, используя ее предопределенные реализации. Для получения дополнительной информации посетите Javadoc .
4. Предопределенные временные настройки
Класс TemporalAdjusters имеет множество предопределенных статических методов, которые возвращают TemporalAdjuster объект для настройки Temporal объектов различными способами, независимо от того, какой может быть реализация Temporal .
Вот краткий список этих методов и их краткое определение:
- dayOfWeekInMonth() – регулятор для порядкового дня недели. Например, дата второго вторника в марте
- firstDayOfMonth() – регулятор для даты первого дня текущего месяца
- firstDayOfNextMonth() – регулятор для даты первого дня следующего месяца
- firstDayOfNextYear() – регулятор для даты первого дня следующего года
- firstDayOfYear() – корректировщик на дату первого дня текущего года
- lastDayOfMonth() – регулятор для даты последнего дня текущего месяца
- nextOrSame() – регулятор для даты следующего наступления определенного дня недели или того же дня, если сегодняшний день соответствует требуемому дню недели
Как мы видим, названия методов в значительной степени объясняют сами себя. Для получения дополнительной информации TemporalAdjusters посетите Javadoc .
Давайте начнем с простого примера – вместо использования конкретной даты, как в примерах, мы можем использовать LocalDate.now() для получения текущей даты из системных часов.
Но в этом уроке мы будем использовать фиксированную дату, чтобы тесты не провалились позже, когда ожидаемый результат изменится. Давайте посмотрим, как мы можем использовать класс TemporalAdjusters для получения даты воскресенья после 2017-07-08:
@Test public void whenAdjust_thenNextSunday() { LocalDate localDate = LocalDate.of(2017, 07, 8); LocalDate nextSunday = localDate.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)); String expected = "2017-07-09"; assertEquals(expected, nextSunday.toString()); }
Вот как мы можем получить последний день текущего месяца:
LocalDate lastDayOfMonth = localDate.with(TemporalAdjusters.lastDayOfMonth());
5. Определение пользовательских Реализаций TemporalAdjuster
Мы также можем определить наши пользовательские реализации для TemporalAdjuster . Есть два разных способа сделать это.
5.1. Использование Лямбда-Выражений
Давайте посмотрим, как мы можем получить дату через 14 дней после 2017-07-08, используя метод Temporal.with() :
@Test public void whenAdjust_thenFourteenDaysAfterDate() { LocalDate localDate = LocalDate.of(2017, 07, 8); TemporalAdjuster temporalAdjuster = t -> t.plus(Period.ofDays(14)); LocalDate result = localDate.with(temporalAdjuster); String fourteenDaysAfterDate = "2017-07-22"; assertEquals(fourteenDaysAfterDate, result.toString()); }
В этом примере, используя лямбда-выражение, мы задаем объекту TemporalAdjuster добавление 14 дней к объекту local Data , который содержит дату (2017-07-08).
Давайте посмотрим, как мы можем получить дату рабочего дня сразу после 2017-07-08, определив наши собственные TemporalAdjuster реализации с помощью лямбда-выражения. Но на этот раз с помощью метода of Date Adjuster() static factory:
static TemporalAdjuster NEXT_WORKING_DAY = TemporalAdjusters.ofDateAdjuster(date -> { DayOfWeek dayOfWeek = date.getDayOfWeek(); int daysToAdd; if (dayOfWeek == DayOfWeek.FRIDAY) daysToAdd = 3; else if (dayOfWeek == DayOfWeek.SATURDAY) daysToAdd = 2; else daysToAdd = 1; return today.plusDays(daysToAdd); });
Тестирование нашего кода:
@Test public void whenAdjust_thenNextWorkingDay() { LocalDate localDate = LocalDate.of(2017, 07, 8); TemporalAdjuster temporalAdjuster = NEXT_WORKING_DAY; LocalDate result = localDate.with(temporalAdjuster); assertEquals("2017-07-10", date.toString()); }
5.2. Путем реализации интерфейса TemporalAdjuster
Давайте посмотрим, как мы можем написать пользовательский TemporalAdjuster , который получает рабочий день после 2017-07-08, реализовав интерфейс TemporalAdjuster :
public class CustomTemporalAdjuster implements TemporalAdjuster { @Override public Temporal adjustInto(Temporal temporal) { DayOfWeek dayOfWeek = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK)); int daysToAdd; if (dayOfWeek == DayOfWeek.FRIDAY) daysToAdd = 3; else if (dayOfWeek == DayOfWeek.SATURDAY) daysToAdd = 2; else daysToAdd = 1; return temporal.plus(daysToAdd, ChronoUnit.DAYS); } }
А теперь давайте проведем наш тест:
@Test public void whenAdjustAndImplementInterface_thenNextWorkingDay() { LocalDate localDate = LocalDate.of(2017, 07, 8); CustomTemporalAdjuster temporalAdjuster = new CustomTemporalAdjuster(); LocalDate nextWorkingDay = localDate.with(temporalAdjuster); assertEquals("2017-07-10", nextWorkingDay.toString()); }
6. Заключение
В этом уроке мы показали, что такое TemporalAdjuster , предопределенные TemporalAdjusters, как их можно использовать и как мы можем реализовать наши пользовательские TemporalAdjuster реализации двумя различными способами.
Полную реализацию этого руководства можно найти на GitHub .