Java教程是针对JDK 8编写的。本页面中描述的示例和实践不利用后续版本中引入的改进,可能使用不再可用的技术。
请参阅Java语言更改,了解Java SE 9及后续版本中更新的语言特性的摘要。
请参阅JDK发行说明,了解所有JDK发行版的新功能、增强功能和已移除或弃用选项的信息。
java.time.temporal
这些接口旨在在最低级别使用。典型的应用代码应该使用具体类型,比如LocalDate或ZonedDateTime,而不是使用Temporal接口。这与声明String类型的变量相同,而不是声明CharSequence类型的变量。
Temporal接口提供了访问基于时间的对象的框架,被实现在基于时间的类中,比如Instant、LocalDateTime和ZonedDateTime。这个接口提供了添加或减去时间单位的方法,使得基于时间的算术在各种日期和时间类中易于使用和一致。TemporalAccessor接口提供了Temporal接口的只读版本。
无论Temporal还是TemporalAccessor对象都是基于字段来定义的,正如在TemporalField接口中指定的那样。ChronoField枚举是TemporalField接口的一个具体实现,提供了一组丰富的定义常量,比如DAY_OF_WEEK、MINUTE_OF_HOUR和MONTH_OF_YEAR。
这些字段的单位由TemporalUnit接口指定。ChronoUnit枚举实现了TemporalUnit接口。字段ChronoField.DAY_OF_WEEK是ChronoUnit.DAYS和ChronoUnit.WEEKS的组合。ChronoField和ChronoUnit枚举在下面的章节中进行了讨论。
Temporal接口中的基于算术的方法需要以TemporalAmount值为参数。Period和Duration类(在Period和Duration中讨论)实现了TemporalAmount接口。
ChronoField 枚举实现了 TemporalField 接口,提供了一组用于访问日期和时间值的常量。一些例子包括 CLOCK_HOUR_OF_DAY、NANO_OF_DAY 和 DAY_OF_YEAR。这个枚举可以用于表示时间的概念方面,比如一年中的第三周、一天中的第11小时或一个月中的第一个星期一。当遇到未知类型的 Temporal 时,可以使用 TemporalAccessor.isSupported(TemporalField) 方法来确定 Temporal 是否支持特定的字段。下面这行代码返回 false,表示 LocalDate 不支持 ChronoField.CLOCK_HOUR_OF_DAY:
boolean isSupported = LocalDate.now().isSupported(ChronoField.CLOCK_HOUR_OF_DAY);
特定于 ISO-8601 日历系统的其他字段在 IsoFields 类中定义。以下示例展示了如何使用 ChronoField 和 IsoFields 获取字段的值:
time.get(ChronoField.MILLI_OF_SECOND) int qoy = date.get(IsoFields.QUARTER_OF_YEAR);
另外还有两个类定义了其他可能有用的字段,它们是 WeekFields 和 JulianFields。
ChronoUnit 枚举实现了 TemporalUnit 接口,并提供了一组基于日期和时间的标准单位,从毫秒到千年。注意,并非所有的 ChronoUnit 对象都被所有类支持。例如,Instant 类不支持 ChronoUnit.MONTHS 或 ChronoUnit.YEARS。Date-Time API 中的类包含 isSupported(TemporalUnit) 方法,可以用来验证一个类是否支持特定的时间单位。下面这个对 isSupported 的调用返回 false,确认 Instant 类不支持 ChronoUnit.DAYS。
Instant instant = Instant.now(); boolean isSupported = instant.isSupported(ChronoUnit.DAYS);