Temporal Adjuster

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

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

Predefined Adjusters

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

Custom Adjusters

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

/**
 * 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