时间调整员

原文: https://docs.oracle.com/javase/tutorial/datetime/iso/adjusters.html

TemporalAdjuster 接口,在java.time.temporal包中,提供了采用Temporal值并返回调整值的方法。调节器可以与任何基于时间的类型一起使用。

如果调节器与ZonedDateTime一起使用,则计算新日期以保留原始时间和时区值。

预定义的调节器

TemporalAdjusters 类(注意复数)提供了一组预定义的调整器,用于查找月份的第一天或最后一天,一年的第一天或最后一天,以及这个月,或特定日期后的第一个星期二,举几个例子。预定义的调整器被定义为静态方法,旨在与静态导入语句一起使用。

以下示例使用多个TemporalAdjusters方法,结合和基于时间的类中定义的方法,根据 2000 年 10 月 15 日的原始日期计算新日期:

  1. LocalDate date = LocalDate.of(2000, Month.OCTOBER, 15);
  2. DayOfWeek dotw = date.getDayOfWeek();
  3. System.out.printf("%s is on a %s%n", date, dotw);
  4. System.out.printf("first day of Month: %s%n",
  5. date.with(TemporalAdjusters.firstDayOfMonth()));
  6. System.out.printf("first Monday of Month: %s%n",
  7. date.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)));
  8. System.out.printf("last day of Month: %s%n",
  9. date.with(TemporalAdjusters.lastDayOfMonth()));
  10. System.out.printf("first day of next Month: %s%n",
  11. date.with(TemporalAdjusters.firstDayOfNextMonth()));
  12. System.out.printf("first day of next Year: %s%n",
  13. date.with(TemporalAdjusters.firstDayOfNextYear()));
  14. System.out.printf("first day of Year: %s%n",
  15. date.with(TemporalAdjusters.firstDayOfYear()));

这会产生以下输出:

  1. 2000-10-15 is on a SUNDAY
  2. first day of Month: 2000-10-01
  3. first Monday of Month: 2000-10-02
  4. last day of Month: 2000-10-31
  5. first day of next Month: 2000-11-01
  6. first day of next Year: 2001-01-01
  7. first day of Year: 2000-01-01

自定义调节器

您还可以创建自己的自定义调整器。为此,您创建一个类,该类使用 adjustInto(Temporal) 方法实现TemporalAdjuster接口。来自 `NextPayday `实例的 `PaydayAdjuster `类是自定义调节器。 PaydayAdjuster评估传入日期并返回下一个发薪日,假设发薪日每月发生两次:在 15 日,再次在该月的最后一天。如果计算的日期发生在周末,则使用上一个星期五。假设当前日历年。

  1. /**
  2. * The adjustInto method accepts a Temporal instance
  3. * and returns an adjusted LocalDate. If the passed in
  4. * parameter is not a LocalDate, then a DateTimeException is thrown.
  5. */
  6. public Temporal adjustInto(Temporal input) {
  7. LocalDate date = LocalDate.from(input);
  8. int day;
  9. if (date.getDayOfMonth() < 15) {
  10. day = 15;
  11. } else {
  12. day = date.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();
  13. }
  14. date = date.withDayOfMonth(day);
  15. if (date.getDayOfWeek() == DayOfWeek.SATURDAY ||
  16. date.getDayOfWeek() == DayOfWeek.SUNDAY) {
  17. date = date.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));
  18. }
  19. return input.with(date);
  20. }

使用方法,以与预定义调整器相同的方式调用调整器。以下代码行来自NextPayday示例:

  1. LocalDate nextPayday = date.with(new PaydayAdjuster());

2013 年,6 月 15 日和 6 月 30 日周末都会发生。运行NextPayday示例,其日期分别为 6 月 3 日和 6 月 18 日(2013 年),结果如下:

  1. Given the date: 2013 Jun 3
  2. the next payday: 2013 Jun 14
  3. Given the date: 2013 Jun 18
  4. the next payday: 2013 Jun 28