# 时间包

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

[`java.time.temporal` ](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/package-summary.html)包提供了一组接口，类和枚举，支持日期和时间代码，特别是日期和时间计算。

这些接口旨在用于最低级别。典型的应用程序代码应根据具体类型声明变量和参数，例如 `LocalDate` 或 `ZonedDateTime` ，而不是 `Temporal` 接口。这与声明 `String` 类型的变量完全相同，而不是 `CharSequence` 类型。

## 时间和时间访问者

[`Temporal` ](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/Temporal.html)接口提供了一个访问基于时间的对象的框架，并由基于时间的类实现，例如 `Instant` ， `LocalDateTime` 和 `ZonedDateTime` 。此接口提供了添加或减去时间单位的方法，使基于时间的算术在各种日期和时间类中变得容易和一致。 [`TemporalAccessor` ](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalAccessor.html)界面提供 `Temporal` 界面的只读版本。

`Temporal` 和 `TemporalAccessor` 对象都是根据字段定义的，如 [`TemporalField`](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalField.html)接口中所述。 [`ChronoField` ](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoField.html)枚举是 `TemporalField` 接口的具体实现，提供了一组丰富的定义常量，如 `DAY_OF_WEEK` ， `] MINUTE_OF_HOUR` 和 `MONTH_OF_YEAR` 。

这些字段的单位由 [`TemporalUnit`](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalUnit.html)接口指定。 `ChronoUnit` 枚举实现了 `TemporalUnit` 接口。字段 `ChronoField.DAY_OF_WEEK` 是 `ChronoUnit.DAYS` 和 `ChronoUnit.WEEKS` 的组合。 `ChronoField` 和 `ChronoUnit` 枚举将在以下章节中讨论。

`Temporal` 界面中基于算法的方法需要根据 [`TemporalAmount`](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalAmount.html)值定义的参数。 `周期`和`持续时间`类（在[周期和持续时间](period.html)中讨论）实现 `TemporalAmount` 接口。

## ChronoField 和 IsoFields

实现 `TemporalField` 接口的 [`ChronoField`](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoField.html)枚举提供了一组丰富的常量来访问日期和时间值。一些例子是 `CLOCK_HOUR_OF_DAY` ， `NANO_OF_DAY` 和 `DAY_OF_YEAR` 。此枚举可用于表示时间的概念方面，例如一年中的第三周，一天中的第 11 个小时或该月的第一个星期一。当您遇到 `Temporal` 未知类型时，可以使用 [`TemporalAccessor.isSupported（TemporalField）`](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalAccessor.html#isSupported-java.time.temporal.TemporalField-) 方法确定 `Temporal` 是否支持一个特定的字段。以下代码行返回 `false` ，表示 `LocalDate` 不支持 `ChronoField.CLOCK_HOUR_OF_DAY` ：

```
boolean isSupported = LocalDate.now().isSupported(ChronoField.CLOCK_HOUR_OF_DAY);

```

ISO-8601 日历系统特有的附加字段在 [`IsoFields`](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/IsoFields.html)类中定义。以下示例显示如何使用 `ChronoField` 和 `IsoFields` 获取字段的值：

```
time.get(ChronoField.MILLI_OF_SECOND)
int qoy = date.get(IsoFields.QUARTER_OF_YEAR);

```

另外两个类定义了可能有用的附加字段， [`WeekFields`](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/WeekFields.html)和 [`JulianFields`](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/JulianFields.html)。

## ChronoUnit

[`ChronoUnit` ](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoUnit.html)枚举实现了 `TemporalUnit` 接口，并提供了一组基于日期和时间的标准单位，从几毫秒到几千年。请注意，并非所有类都支持所有 `ChronoUnit` 对象。例如， `Instant` 类不支持 `ChronoUnit.MONTHS` 或 `ChronoUnit.YEARS` 。 [`TemporalAccessor.isSupported（TemporalUnit）`](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalAccessor.html#isSupported-java.time.temporal.TemporalUnit-) 方法可用于验证类是否支持特定时间单位。以下调用 `isSupported` 返回 `false` ，确认 `Instant` 类不支持 `ChronoUnit.DAYS` 。

```
boolean isSupported = instant.isSupported(ChronoUnit.DAYS);

```