TemporalAdjuster
是调整时间对象的策略接口。有两种使用方式,更推荐第二种用法:
temporal = thisAdjuster.adjustInto(temporal);
temporal = temporal.with(thisAdjuster);
public interface TemporalAdjuster {
Temporal adjustInto(Temporal temporal);
}
TemporalAdjusters
实现了一些标准的调整器:
- 本月的第一天或最后一天
- 下个月的第一天
- 本年的第一天或最后一天
- 下一年的第一天
- 本月的第一个或最后一个周几
- 本月的第 N 个周几
- 下一个或上一个周几
- 自定义 LocalDate 的调整器
本月的第一天或最后一天:firstDayOfMonth、lastDayOfMonth
public static void main(String[] args) {
LocalDate now = LocalDate.now();
System.out.println(now);
firstDayOfMonth(now);
lastDayOfMonth(now);
}
public static void firstDayOfMonth(Temporal temporal) {
Temporal firstDayOfMonth = temporal.with(TemporalAdjusters.firstDayOfMonth());
System.out.println("firstDayOfMonth:" + firstDayOfMonth);
}
public static void lastDayOfMonth(Temporal temporal) {
Temporal lastDayOfMonth = temporal.with(TemporalAdjusters.lastDayOfMonth());
System.out.println("lastDayOfMonth:" + lastDayOfMonth);
}
2021-08-14
firstDayOfMonth:2021-08-01
lastDayOfMonth:2021-08-31
下个月的第一天:firstDayOfNextMonth
public static void main(String[] args) {
LocalDate now = LocalDate.now();
System.out.println(now);
firstDayOfNextMonth(now);
}
public static void firstDayOfNextMonth(Temporal temporal) {
Temporal firstDayOfNextMonth = temporal.with(TemporalAdjusters.firstDayOfNextMonth());
System.out.println("firstDayOfNextMonth:" + firstDayOfNextMonth);
}
2021-08-14
firstDayOfNextMonth:2021-09-01
本年的第一天或最后一天:firstDayOfYear、lastDayOfYear
public static void main(String[] args) {
LocalDate now = LocalDate.now();
System.out.println(now);
firstDayOfYear(now);
lastDayOfYear(now);
}
public static void firstDayOfYear(Temporal temporal) {
Temporal firstDayOfYear = temporal.with(TemporalAdjusters.firstDayOfYear());
System.out.println("firstDayOfYear:" + firstDayOfYear);
}
public static void lastDayOfYear(Temporal temporal) {
Temporal lastDayOfYear = temporal.with(TemporalAdjusters.lastDayOfYear());
System.out.println("lastDayOfYear:" + lastDayOfYear);
}
2021-08-14
firstDayOfYear:2021-01-01
lastDayOfYear:2021-12-31
下一年的第一天:firstDayOfNextYear
public static void main(String[] args) {
LocalDate now = LocalDate.now();
System.out.println(now);
firstDayOfNextYear(now);
}
public static void firstDayOfNextYear(Temporal temporal) {
Temporal firstDayOfNextYear = temporal.with(TemporalAdjusters.firstDayOfNextYear());
System.out.println("firstDayOfNextYear:" + firstDayOfNextYear);
}
2021-08-14
firstDayOfNextYear:2022-01-01
本月的第一个或最后一个周几:firstInMonth、lastInMonth
public static void main(String[] args) {
LocalDate now = LocalDate.now();
System.out.println(now);
firstInMonth(now, DayOfWeek.MONDAY);
lastInMonth(now, DayOfWeek.MONDAY);
}
public static void firstInMonth(Temporal temporal, DayOfWeek dayOfWeek) {
Temporal firstInMonth = temporal.with(TemporalAdjusters.firstInMonth(dayOfWeek));
System.out.println("firstInMonth:" + dayOfWeek + ":"+ firstInMonth);
}
public static void lastInMonth(Temporal temporal, DayOfWeek dayOfWeek) {
Temporal lastInMonth = temporal.with(TemporalAdjusters.lastInMonth(dayOfWeek));
System.out.println("lastInMonth:" + dayOfWeek + ":"+ lastInMonth);
}
2021-08-14
firstInMonth:MONDAY:2021-08-02
lastInMonth:MONDAY:2021-08-30
本月的第 N 个周几:dayOfWeekInMonth
public static void main(String[] args) {
LocalDate now = LocalDate.now();
System.out.println(now);
dayOfWeekInMonth(now, 2, DayOfWeek.SUNDAY);
}
public static void dayOfWeekInMonth(Temporal temporal, int ordinal, DayOfWeek dayOfWeek) {
Temporal dayOfWeekInMonth = temporal.with(TemporalAdjusters.dayOfWeekInMonth(ordinal, dayOfWeek));
System.out.println("dayOfWeekInMonth:" + ordinal + ":" + dayOfWeek + ":"+ dayOfWeekInMonth);
}
2021-08-14
dayOfWeekInMonth:2:SUNDAY:2021-08-08
下一个或上一个周几:next、nextOrSame、previous、previousOrSame
next、previous
与 nextOrSame、previousOrSame
的区别:如果今天已经是目标 DayOfWeek
了,nextOrSame、previousOrSame
会直接返回今天,而 next、previous
会跳过今天,再往后或往前寻找。
public static void main(String[] args) {
LocalDate now = LocalDate.now();
System.out.println(now + ":" + now.getDayOfWeek());
next(now,DayOfWeek.SATURDAY);
nextOrSame(now,DayOfWeek.SATURDAY);
previous(now,DayOfWeek.SATURDAY);
previousOrSame(now,DayOfWeek.SATURDAY);
}
public static void next(Temporal temporal, DayOfWeek dayOfWeek) {
Temporal next = temporal.with(TemporalAdjusters.next(dayOfWeek));
System.out.println("next:" + dayOfWeek + ":"+ next);
}
public static void nextOrSame(Temporal temporal, DayOfWeek dayOfWeek) {
Temporal nextOrSame = temporal.with(TemporalAdjusters.nextOrSame(dayOfWeek));
System.out.println("nextOrSame:" + dayOfWeek + ":"+ nextOrSame);
}
public static void previous(Temporal temporal, DayOfWeek dayOfWeek) {
Temporal previous = temporal.with(TemporalAdjusters.previous(dayOfWeek));
System.out.println("previous:" + dayOfWeek + ":"+ previous);
}
public static void previousOrSame(Temporal temporal, DayOfWeek dayOfWeek) {
Temporal previousOrSame = temporal.with(TemporalAdjusters.previousOrSame(dayOfWeek));
System.out.println("previousOrSame:" + dayOfWeek + ":"+ previousOrSame);
}
今天(2021-08-14)是周六,所以 nextOrSame、previousOrSame
直接返回了今天(2021-08-14):
2021-08-14:SATURDAY
next:SATURDAY:2021-08-21
nextOrSame:SATURDAY:2021-08-14
previous:SATURDAY:2021-08-07
previousOrSame:SATURDAY:2021-08-14
自定义 LocalDate 的调整器:ofDateAdjuster
public static TemporalAdjuster ofDateAdjuster(UnaryOperator<LocalDate> dateBasedAdjuster) {
Objects.requireNonNull(dateBasedAdjuster, "dateBasedAdjuster");
return (temporal) -> {
LocalDate input = LocalDate.from(temporal);
LocalDate output = dateBasedAdjuster.apply(input);
return temporal.with(output);
};
}
下个月的最后一天
static TemporalAdjuster LAST_DAY_OF_NEXT_MONTH = TemporalAdjusters.ofDateAdjuster(
(temporal) -> temporal.plusMonths(2).with(ChronoField.DAY_OF_MONTH, 1).minusDays(1));
public static void main(String[] args) {
LocalDate now = LocalDate.now();
System.out.println(now);
lastDayOfNextMonth(now);
}
public static void lastDayOfNextMonth(Temporal temporal) {
Temporal lastDayOfNextMonth = temporal.with(LAST_DAY_OF_NEXT_MONTH);
System.out.println("lastDayOfNextMonth:" + lastDayOfNextMonth);
}
2021-08-14
lastDayOfNextMonth:2021-09-30
N 天后的第一个周几
public static void main(String[] args) {
LocalDate now = LocalDate.now();
System.out.println(now);
// 6 天后的第一个周日
nextAfterDays(now, DayOfWeek.SUNDAY, 6);
}
public static void nextAfterDays(Temporal temporal, DayOfWeek dayOfWeek, int days) {
Temporal nextAfterDays = temporal.with(TemporalAdjusters.ofDateAdjuster(
(input) -> input.plusDays(days).with(TemporalAdjusters.next(dayOfWeek))));
System.out.println("nextAfterDays:" + nextAfterDays);
}
2021-08-14
nextAfterDays:2021-08-22