# 时间调整员

> 原文： [https://docs.oracle.com/javase/tutorial/datetime/iso/adjusters.html](https://docs.oracle.com/javase/tutorial/datetime/iso/adjusters.html)

[`TemporalAdjuster` ](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalAdjuster.html)接口，在 `java.time.temporal` 包中，提供了采用 `Temporal` 值并返回调整值的方法。调节器可以与任何基于时间的类型一起使用。

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

## 预定义的调节器

[`TemporalAdjusters` ](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalAdjusters.html)类（注意复数）提供了一组预定义的调整器，用于查找月份的第一天或最后一天，一年的第一天或最后一天，以及这个月，或特定日期后的第一个星期二，举几个例子。预定义的调整器被定义为静态方法，旨在与[静态导入](../../java/package/usepkgs.html#staticimport)语句一起使用。

以下示例使用多个 `TemporalAdjusters` 方法，结合`和基于时间的类中定义的`方法，根据 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）`](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalAdjuster.html#adjustInto-java.time.temporal.Temporal-) 方法实现 `TemporalAdjuster` 接口。来自 [``NextPayday` `](examples/NextPayday.java)实例的 [``PaydayAdjuster` `](examples/PaydayAdjuster.java)类是自定义调节器。 `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);
}

```

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

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

```

2013 年，6 月 15 日和 6 月 30 日周末都会发生。运行 `NextPayday` 示例，其日期分别为 6 月 3 日和 6 月 18 日（2013 年），结果如下：

```
Given the date:  2013 Jun 3
the next payday: 2013 Jun 14

Given the date:  2013 Jun 18
the next payday: 2013 Jun 28

```