Руководство Java TemporalAdjuster
1. TemporalAdjuster
Интерфейс TemporalAdjuster - это инструмент для настройки объекта Temporal для создания копии. По сути, TemporalAdjuster существует для экстернализации (externalize) процесса настройки объектов Temporal вместо их прямой настройки.
@FunctionalInterface
public interface TemporalAdjuster {
Temporal adjustInto(Temporal temporal);
}
Например: Мы создаем класс TruncateTimeAdjuster для усечения времени (часов, минут, секунд, наносекунд) объекта Temporal.
Temporal | Example | Apply TruncateTimeAdjuster |
LocalDateTime | 2020-11-25 13:30:45 | 2020-11-25 00:00:00 |
ZonedDateTime | 2020-11-25 13:30:45+06:00[Asia/Bishkek] | 2020-11-25 00:00:00+06:00[Asia/Bishkek] |
LocalTime | 13:30:45 | 00:00:00 |
TruncateTimeAdjuster.java
package org.o7planning.temporaladjuster.ex;
import java.time.temporal.ChronoField;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjuster;
public class TruncateTimeAdjuster implements TemporalAdjuster {
@Override
public Temporal adjustInto(Temporal temporal) {
Temporal adjustedTemporal = temporal;
if (temporal.isSupported(ChronoField.HOUR_OF_DAY)) {
adjustedTemporal = adjustedTemporal.with(ChronoField.HOUR_OF_DAY, 0);
}
if (temporal.isSupported(ChronoField.MINUTE_OF_HOUR)) {
adjustedTemporal = adjustedTemporal.with(ChronoField.MINUTE_OF_HOUR, 0);
}
if (temporal.isSupported(ChronoField.SECOND_OF_MINUTE)) {
adjustedTemporal = adjustedTemporal.with(ChronoField.SECOND_OF_MINUTE, 0);
}
if (temporal.isSupported(ChronoField.NANO_OF_SECOND)) {
adjustedTemporal = adjustedTemporal.with(ChronoField.NANO_OF_SECOND, 0);
}
return adjustedTemporal;
}
}
Использование TruncateTemporalAdjuster:
TruncateTimeAdjuster_ex1.java
TruncateTimeAdjuster truncateTimeAdjuster = new TruncateTimeAdjuster();
// Create a Temporal object from LocalDateTime
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime adjustedLocalDateTime = (LocalDateTime) truncateTimeAdjuster.adjustInto(localDateTime);
System.out.printf("localDateTime: %s%n", localDateTime);
System.out.printf("adjustedLocalDateTime: %s%n%n", adjustedLocalDateTime);
// Create a Temporal object from ZonedDateTime
ZonedDateTime zonedDateTime = ZonedDateTime.now();
ZonedDateTime adjustedZonedDateTime = (ZonedDateTime) truncateTimeAdjuster.adjustInto(zonedDateTime);
System.out.printf("zonedDateTime: %s%n", zonedDateTime);
System.out.printf("adjustedZonedDateTime: %s%n%n", adjustedZonedDateTime);
// Create a Temporal object from OffsetDateTime
OffsetDateTime offsetDateTime = OffsetDateTime.now();
OffsetDateTime adjustedOffsetDateTime = (OffsetDateTime) truncateTimeAdjuster.adjustInto(offsetDateTime);
System.out.printf("offsetDateTime: %s%n", offsetDateTime);
System.out.printf("adjustedOffsetDateTime: %s%n", adjustedOffsetDateTime);
Output:
localDateTime: 2021-07-05T00:30:09.309188
adjustedLocalDateTime: 2021-07-05T00:00
zonedDateTime: 2021-07-05T00:30:09.322306+06:00[Asia/Bishkek]
adjustedZonedDateTime: 2021-07-05T00:00+06:00[Asia/Bishkek]
offsetDateTime: 2021-07-05T00:30:09.323143+06:00
adjustedOffsetDateTime: 2021-07-05T00:00+06:00
В Java Date Time API есть много классов, которые реализуют (implement) интерфейс TemporalAdjuster, это означает, что они способны настраивать другие объекты Temporal:
- IsoEra
- MinguoEra
- LocalDateTime
- LocalTime
- ZoneOffset
- HijrahEra
- MonthDay
- Month
- DayOfWeek
- LocalDate
- JapaneseEra
- YearMonth
- OffsetTime
- Instant
- Era
- Year
- OffsetDateTime
- ThaiBuddhistEra
- ChronoLocalDate
- ThaiBuddhistDate
- MinguoDate
- JapaneseDate
- HijrahDate
- ChronoLocalDateTime
- TemporalAdjusters
Существует два способа настройки объекта Temporal, из них рекомендуется второй подход.
// these two lines are equivalent, but the second approach is recommended
adjustedTemporal = thisAdjuster.adjustInto(temporal); // (1)
adjustedTemporal = temporal.with(thisAdjuster); // (2)
2. Basic Examples
Например: Настройте все заданные объекты Temporal на май 2000 года, остальные поля (field) останутся неизменными.
TemporalAdjuster_ex1.java
package org.o7planning.temporaladjuster.ex;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAdjuster;
public class TemporalAdjuster_ex1 {
public static void main(String[] args) {
TemporalAdjuster adjuster = YearMonth.of(2020, 5); // May 2020.
// Create a Temporal object from ZonedDateTime
ZonedDateTime zonedDateTime = ZonedDateTime.now();
ZonedDateTime adjustedZonedDateTime = (ZonedDateTime) adjuster.adjustInto(zonedDateTime);
System.out.printf("zonedDateTime: %s%n", zonedDateTime);
System.out.printf("adjustedZonedDateTime: %s%n%n", adjustedZonedDateTime);
// Create a Temporal object from LocalDate
LocalDate localDate = LocalDate.now();
LocalDate adjustedLocalDate = (LocalDate) adjuster.adjustInto(localDate);
System.out.printf("localDate: %s%n", localDate);
System.out.printf("adjustedLocalDate: %s%n", adjustedLocalDate);
}
}
Output:
zonedDateTime: 2021-07-05T00:51:07.837210+06:00[Asia/Bishkek]
adjustedZonedDateTime: 2020-05-05T00:51:07.837210+06:00[Asia/Bishkek]
localDate: 2021-07-05
adjustedLocalDate: 2020-05-05
Например: Отрегулируйте смещение часового пояса (zone-offset) для заданных объектов OffsetDateTime на +15;
TemporalAdjuster_ex2.java
TemporalAdjuster adjuster = ZoneOffset.ofHours(15);
// Create a Temporal object from OffsetDateTime
OffsetDateTime offsetDateTime1 = OffsetDateTime.now();
OffsetDateTime adjustedOffsetDateTime1 = (OffsetDateTime) adjuster.adjustInto(offsetDateTime1);
System.out.printf("offsetDateTime1: %s%n", offsetDateTime1);
System.out.printf("adjustedOffsetDateTime1: %s%n%n", adjustedOffsetDateTime1);
// Create a Temporal object from OffsetDateTime
OffsetDateTime offsetDateTime2 = OffsetDateTime.parse("2000-01-01T01:00+01:00");
OffsetDateTime adjustedOffsetDateTime2 = (OffsetDateTime) adjuster.adjustInto(offsetDateTime2);
System.out.printf("offsetDateTime2: %s%n", offsetDateTime2);
System.out.printf("adjustedOffsetDateTime2: %s%n%n", adjustedOffsetDateTime2);
Output:
offsetDateTime1: 2021-07-05T01:15:48.372665+06:00
adjustedOffsetDateTime1: 2021-07-05T01:15:48.372665+15:00
offsetDateTime2: 2000-01-01T01:00+01:00
adjustedOffsetDateTime2: 2000-01-01T01:00+15:00
- OffsetDateTime
- ZonedDateTime
- LocalDate
3. Custom TemporalAdjuster Examples
Предположим, что рабочие дни недели - с понедельника по пятницу. Мы пишем класс NextWorkingDayAdjuster, чтобы найти следующий рабочий день после указанной даты.
NextWorkingDayAdjuster.java
package org.o7planning.temporaladjuster.ex;
import java.time.DayOfWeek;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjuster;
public class NextWorkingDayAdjuster implements TemporalAdjuster {
@Override
public Temporal adjustInto(Temporal temporal) {
int field = temporal.get(ChronoField.DAY_OF_WEEK);
DayOfWeek dayOfWeek = DayOfWeek.of(field);
int daysToAdd = 1;
if (DayOfWeek.FRIDAY.equals(dayOfWeek)) {
daysToAdd = 3;
} else if (DayOfWeek.SATURDAY.equals(dayOfWeek)) {
daysToAdd = 2;
}
return temporal.plus(daysToAdd, ChronoUnit.DAYS);
}
}
Например, с помощью использования класса NextWorkingDayAdjuster:
NextWorkingDayAdjuster_ex1.java
package org.o7planning.temporaladjuster.ex;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAdjuster;
public class NextWorkingDayAdjuster_ex1 {
public static void main(String[] args) {
TemporalAdjuster adjuster = new NextWorkingDayAdjuster();
// Create a Temporal object from LocalDate
LocalDate localDate = LocalDate.now();
LocalDate nextWorkingDay = (LocalDate) adjuster.adjustInto(localDate);
System.out.printf("localDate: %s%n", localDate);
System.out.printf("nextWorkingDay: %s%n", nextWorkingDay);
System.out.println(" ----- ");
// Create a Temporal object from ZonedDateTime
ZonedDateTime zonedDateTime = ZonedDateTime.now();
ZonedDateTime adjustedZonedDateTime = (ZonedDateTime) adjuster.adjustInto(zonedDateTime);
nextWorkingDay = adjustedZonedDateTime.toLocalDate();
System.out.printf("zonedDateTime: %s%n", zonedDateTime);
System.out.printf("adjustedZonedDateTime: %s%n", adjustedZonedDateTime);
System.out.printf("nextWorkingDay: %s%n", nextWorkingDay);
}
}
Output:
localDate: 2021-07-05
nextWorkingDay: 2021-07-06
-----
zonedDateTime: 2021-07-05T01:34:09.112648+06:00[Asia/Bishkek]
adjustedZonedDateTime: 2021-07-06T01:34:09.112648+06:00[Asia/Bishkek]
nextWorkingDay: 2021-07-06
Например: Напишите класс NextChristmasAdjuster, чтобы найти следующую дату Рождества:
NextChristmasAdjuster.java
package org.o7planning.temporaladjuster.ex;
import java.time.Period;
import java.time.temporal.ChronoField;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjuster;
public class NextChristmasAdjuster implements TemporalAdjuster {
@Override
public Temporal adjustInto(Temporal temporal) {
int month = temporal.get(ChronoField.MONTH_OF_YEAR);
int day = temporal.get(ChronoField.DAY_OF_MONTH);
if(month == 12 && day > 25) {
temporal = temporal.plus(Period.ofYears(1));
}
return temporal.with(ChronoField.MONTH_OF_YEAR, 12).with(ChronoField.DAY_OF_MONTH, 25);
}
}
Использование класса NextChristmasAdjuster:
NextChristmasAdjuster_ex1.java
package org.o7planning.temporaladjuster.ex;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjuster;
public class NextChristmasAdjuster_ex1 {
public static void main(String[] args) {
TemporalAdjuster adjuster = new NextChristmasAdjuster();
// Create a Temporal object from LocalDate
LocalDate localDate1 = LocalDate.of(2021, 7, 5);
LocalDate nextChristmasDay = (LocalDate) adjuster.adjustInto(localDate1);
System.out.printf("localDate1: %s%n", localDate1);
System.out.printf("nextChristmasDay: %s%n", nextChristmasDay);
System.out.println(" ----- ");
// Create a Temporal object from LocalDate
LocalDate localDate2 = LocalDate.of(2021, 12, 26);
nextChristmasDay = (LocalDate) adjuster.adjustInto(localDate2);
System.out.printf("localDate2: %s%n", localDate2);
System.out.printf("nextChristmasDay: %s%n", nextChristmasDay);
}
}
Output:
localDate1: 2021-07-05
nextChristmasDay: 2021-12-25
-----
localDate2: 2021-12-26
nextChristmasDay: 2022-12-25
- ChronoField
- Temporal
- ZonedDateTime
- DayOfWeek
4. TemporalAdjusters Examples
Класс TemporalAdjusters предоставляет статические методы для получения стандартных TemporalAdjuster. К ним относятся:
- Поиск первого или последнего дня месяца.
- Поиск первого дня следующего месяца.
- Поиск первого или последнего дня в году.
- Поиск первого дня следующего года.
- Поиск первого или последнего "дня недели" (day-of-week) в месяце, например "первая среда июня".
- Поиск следующего или предыдущего "дня недели" (day-of-week), например "следующего четверга".
Руководства Java Date Time
- Руководство Java ZoneId
- Руководство Java Temporal
- Руководство Java Period
- Руководство Java TemporalAdjusters
- Руководство Java MinguoDate
- Руководство Java TemporalAccessor
- Руководство Java JapaneseEra
- Руководство Java HijrahDate
- Руководство Java Date Time
- Что такое летнее время (DST)?
- Руководство Java LocalDate
- Руководство Java LocalTime
- Руководство Java ZonedDateTime
- Руководство Java JapaneseDate
- Руководство Java Duration
- Руководство Java TemporalQuery
- Руководство Java TemporalAdjuster
- Руководство Java ChronoUnit
- Руководство Java TemporalQueries
Show More
- Руководства Java Web Services
- Руководства Java Servlet/JSP
- Руководства JavaFX
- Руководства Java SWT
- Руководства Oracle Java ADF
- Java Basic
- Руководства Java Collections Framework
- Руководства Java IO
- Руководства Struts2 Framework
- Руководства Spring Boot
- Руководства Spring Cloud
- Руководства Maven
- Руководства Gradle