Java8引入了新的日期、时间库--即java.time包,TemporalAdjuster类是其中之一。时间调节器,将一个时间调节成另外一个时间
@FunctionalInterface
public interface TemporalAdjuster {
Temporal adjustInto(Temporal temporal);
}
有两种类等效的使用TemporalAdjuster的方式
//第一种
temporal = thisAdjuster.adjustInto(temporal);
//第二种
temporal = temporal.with(thisAdjuster);
建议使用第二种,读起来更清晰。
TemporalAdjusters类包含一些标准的调节器。
比如:
- 查找每个月的第一天或最后一天
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);
};
}
firstDayOfMonth
返回每个月第一天的调节器
public static TemporalAdjuster firstDayOfMonth() {
return (temporal) -> temporal.with(DAY_OF_MONTH, 1);
}
lastDayOfMonth
一个月的最后一天
public static TemporalAdjuster lastDayOfMonth() {
return (temporal) -> temporal.with(DAY_OF_MONTH, temporal.range(DAY_OF_MONTH).getMaximum());
}
firstDayOfNextMonth
下个月的最后一天
public static TemporalAdjuster firstDayOfNextMonth() {
return (temporal) -> temporal.with(DAY_OF_MONTH, 1).plus(1, MONTHS);
}
firstDayOfYear
一年的第一天
public static TemporalAdjuster firstDayOfYear() {
return (temporal) -> temporal.with(DAY_OF_YEAR, 1);
}
lastDayOfYear
一年的最后一天
public static TemporalAdjuster lastDayOfYear() {
return (temporal) -> temporal.with(DAY_OF_YEAR, temporal.range(DAY_OF_YEAR).getMaximum());
}
firstDayOfNextYear
下一年的第一天
public static TemporalAdjuster firstDayOfNextYear() {
return (temporal) -> temporal.with(DAY_OF_YEAR, 1).plus(1, YEARS);
}
firstInMonth
某月的第一个星期几
public static TemporalAdjuster firstInMonth(DayOfWeek dayOfWeek) {
return TemporalAdjusters.dayOfWeekInMonth(1, dayOfWeek);
}
lastInMonth
某月的最后一个星期几
public static TemporalAdjuster lastInMonth(DayOfWeek dayOfWeek) {
return TemporalAdjusters.dayOfWeekInMonth(-1, dayOfWeek);
}
dayOfWeekInMonth
某月的第几个星期几
ordinal为正数,则从这个月的前面开始算,为负数,则倒着算
public static TemporalAdjuster dayOfWeekInMonth(int ordinal, DayOfWeek dayOfWeek) {
Objects.requireNonNull(dayOfWeek, "dayOfWeek");
int dowValue = dayOfWeek.getValue();
if (ordinal >= 0) {
return (temporal) -> {
Temporal temp = temporal.with(DAY_OF_MONTH, 1);
int curDow = temp.get(DAY_OF_WEEK);
int dowDiff = (dowValue - curDow + 7) % 7;
dowDiff += (ordinal - 1L) * 7L; // safe from overflow
return temp.plus(dowDiff, DAYS);
};
} else {
return (temporal) -> {
Temporal temp = temporal.with(DAY_OF_MONTH, temporal.range(DAY_OF_MONTH).getMaximum());
int curDow = temp.get(DAY_OF_WEEK);
int daysDiff = dowValue - curDow;
daysDiff = (daysDiff == 0 ? 0 : (daysDiff > 0 ? daysDiff - 7 : daysDiff));
daysDiff -= (-ordinal - 1L) * 7L; // safe from overflow
return temp.plus(daysDiff, DAYS);
};
}
}
例子:
public static void main(String[] args) {
LocalDate localDate = LocalDate.now();
// 当月的第一个星期日的日期
localDate.with(TemporalAdjusters.firstInMonth(DayOfWeek.SUNDAY));
System.out.println(localDate.with(TemporalAdjusters.firstInMonth(DayOfWeek.SUNDAY)));
// 当月的第二个星期日的日期
TemporalAdjuster temporalAdjuster = TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.SUNDAY);
System.out.println(localDate.with(temporalAdjuster));
localDate.with(TemporalAdjusters.dayOfWeekInMonth(-1,DayOfWeek.SUNDAY));
// 当月的最后一个星期日的日期
System.out.println(localDate.with(TemporalAdjusters.dayOfWeekInMonth(-1,DayOfWeek.SUNDAY)));
// 当月的倒数第二个星期日的日期
System.out.println(localDate.with(TemporalAdjusters.dayOfWeekInMonth(-2,DayOfWeek.SUNDAY)));
}
next
The input 2011-01-15 (a Saturday) for parameter (SATURDAY) will return 2011-01-22 (seven days later)
下一个星期一是几月几号
public static TemporalAdjuster next(DayOfWeek dayOfWeek) {
int dowValue = dayOfWeek.getValue();
return (temporal) -> {
int calDow = temporal.get(DAY_OF_WEEK);
int daysDiff = calDow - dowValue;
return temporal.plus(daysDiff >= 0 ? 7 - daysDiff : -daysDiff, DAYS);
};
}
nextOrSame
The ISO calendar system behaves as follows:
The input 2011-01-15 (a Saturday) for parameter (MONDAY) will return 2011-01-17 (two days later).
The input 2011-01-15 (a Saturday) for parameter (WEDNESDAY) will return 2011-01-19 (four days later).
The input 2011-01-15 (a Saturday) for parameter (SATURDAY) will return 2011-01-15 (same as input).
public static TemporalAdjuster nextOrSame(DayOfWeek dayOfWeek) {
int dowValue = dayOfWeek.getValue();
return (temporal) -> {
int calDow = temporal.get(DAY_OF_WEEK);
if (calDow == dowValue) {
return temporal;
}
int daysDiff = calDow - dowValue;
return temporal.plus(daysDiff >= 0 ? 7 - daysDiff : -daysDiff, DAYS);
};
}
previous
public static TemporalAdjuster previous(DayOfWeek dayOfWeek) {
int dowValue = dayOfWeek.getValue();
return (temporal) -> {
int calDow = temporal.get(DAY_OF_WEEK);
int daysDiff = dowValue - calDow;
return temporal.minus(daysDiff >= 0 ? 7 - daysDiff : -daysDiff, DAYS);
};
}
previousOrSame
public static TemporalAdjuster previousOrSame(DayOfWeek dayOfWeek) {
int dowValue = dayOfWeek.getValue();
return (temporal) -> {
int calDow = temporal.get(DAY_OF_WEEK);
if (calDow == dowValue) {
return temporal;
}
int daysDiff = dowValue - calDow;
return temporal.minus(daysDiff >= 0 ? 7 - daysDiff : -daysDiff, DAYS);
};
}