Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
java.time.temporal 包中的 TemporalAdjuster 接口提供了采用 Temporal 值并返回调整后的值的方法。调节器可以与任何基于时间的类型一起使用。
如果调整器与 ZonedDateTime 一起使用,则计算新日期以保留原始时间和时区值。
TemporalAdjusters 类(注意复数)提供了一组预定义的调整器,用于查找月份的第一天或最后一天,一年的第一天或最后一天,一个月的最后一个星期三,或特定日期之后的第一个星期二,举几个例子。预定义的调整器被定义为静态方法,旨在与 static import 语句一起使用。
以下示例使用几个 TemporalAdjusters 方法,结合基于时间的类中定义的 with 方法,根据 2000 年 10 月 15 日的原始日期计算新日期:
LocalDate date = LocalDate.of(2000, Month.OCTOBER, 15); DayOfWeek dotw = date.getDayOfWeek(); System.out.printf("%s is on a %s%n", date, dotw); System.out.printf("first day of Month: %s%n", date.with(TemporalAdjusters.firstDayOfMonth())); System.out.printf("first Monday of Month: %s%n", date.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY))); System.out.printf("last day of Month: %s%n", date.with(TemporalAdjusters.lastDayOfMonth())); System.out.printf("first day of next Month: %s%n", date.with(TemporalAdjusters.firstDayOfNextMonth())); System.out.printf("first day of next Year: %s%n", date.with(TemporalAdjusters.firstDayOfNextYear())); System.out.printf("first day of Year: %s%n", date.with(TemporalAdjusters.firstDayOfYear()));
这会产生以下输出:
2000-10-15 is on a SUNDAY first day of Month: 2000-10-01 first Monday of Month: 2000-10-02 last day of Month: 2000-10-31 first day of next Month: 2000-11-01 first day of next Year: 2001-01-01 first day of Year: 2000-01-01
你还可以创建自己的自定义调节器。为此,你将创建一个使用 adjustInto(Temporal) 方法实现 TemporalAdjuster 接口的类。NextPayday
示例中的 PaydayAdjuster
类是自定义调整器。PaydayAdjuster 计算传入日期并返回下一个发薪日,假设发薪日每月发生两次:在 15 日,再次在该月的最后一天。如果计算的日期发生在周末,则使用上一个星期五。假设当前日历年。
/** * The adjustInto method accepts a Temporal instance * and returns an adjusted LocalDate. If the passed in * parameter is not a LocalDate, then a DateTimeException is thrown. */ public Temporal adjustInto(Temporal input) { LocalDate date = LocalDate.from(input); int day; if (date.getDayOfMonth() < 15) { day = 15; } else { day = date.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth(); } date = date.withDayOfMonth(day); if (date.getDayOfWeek() == DayOfWeek.SATURDAY || date.getDayOfWeek() == DayOfWeek.SUNDAY) { date = date.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY)); } return input.with(date); }
使用 with 方法以与预定义调整器相同的方式调用调整器。以下代码行来自 NextPayday 示例:
LocalDate nextPayday = date.with(new PaydayAdjuster());
2013 年 6 月 15 日和 6 月 30 日都是周末。运行具有相应日期 6 月 3 日和 6 月 18 日(2013 年)的 NextPayday 示例,得出以下结果:
Given the date: 2013 Jun 3 the next payday: 2013 Jun 14 Given the date: 2013 Jun 18 the next payday: 2013 Jun 28