当前教程
日期时间 API 概述
系列中的下一个

系列中的下一个: 标准日历

日期时间 API 概述

 

介绍日期时间 API

时间似乎是一个简单的主题;即使是廉价的手表也能提供相当准确的日期和时间。但是,仔细观察后,你会意识到影响你对时间的理解的微妙复杂性和许多因素。例如,将一个月添加到 1 月 31 日的结果对于闰年和非闰年是不同的。时区也增加了复杂性。例如,一个国家可能会在短时间内进出夏令时,或者一年中不止一次,或者它可能在某一年完全跳过夏令时。

日期时间 API 使用 ISO-8601 中定义的日历系统作为默认日历。此日历基于公历系统,并在全球范围内用作表示日期和时间的实际标准。日期时间 API 中的核心类具有诸如 LocalDateTimeZonedDateTimeOffsetDateTime 之类的名称。所有这些都使用 ISO 日历系统。如果你想使用其他日历系统,例如伊斯兰历或泰国佛教历,java.time.chrono 包允许你使用预定义的日历系统之一。或者你可以创建自己的。

日期时间 API 使用 Unicode 通用语言环境数据存储库 (CLDR)。此存储库支持世界语言,并包含世界上最大的语言环境数据集合。此存储库中的信息已本地化为数百种语言。日期时间 API 还使用 时区数据库 (TZDB)。该数据库提供有关自 1970 年以来全球每个时区变化的信息,以及自引入时区概念以来主要时区的历史记录。

 

日期时间设计原则

日期时间 API 是使用几个设计原则开发的。

清晰

API 中的方法定义明确,其行为清晰且符合预期。例如,使用空参数值调用日期时间方法通常会触发 NullPointerException

流畅

日期时间 API 提供了一个流畅的接口,使代码易于阅读。由于大多数方法不允许使用空值参数并且不返回空值,因此可以将方法调用链接在一起,并且可以快速理解生成的代码。例如

LocalDate today = LocalDate.now();
LocalDate payday = today.with(TemporalAdjusters.lastDayOfMonth()).minusDays(2);

不可变

日期时间 API 中的大多数类创建不可变的对象,这意味着在创建对象后,无法修改它。要更改不可变对象的值,必须构造一个作为原始对象的修改副本的新对象。这也意味着日期时间 API 本质上是线程安全的。这会影响 API,因为用于创建日期或时间对象的大多数方法都以 of、from 或 with 为前缀,而不是构造函数,并且没有 set 方法。例如

LocalDate dateOfBirth = LocalDate.of(2012, Month.MAY, 14);
LocalDate firstBirthday = dateOfBirth.plusYears(1);

可扩展

日期时间 API 在尽可能的情况下是可扩展的。例如,你可以定义自己的时间调整器和查询,或者构建自己的日历系统。

 

日期时间包

日期时间 API 由主包 java.time 和四个子包组成

  • java.time API 的核心,用于表示日期和时间。它包括用于日期、时间、日期和时间组合、时区、瞬间、持续时间和时钟的类。这些类基于 ISO-8601 中定义的日历系统,并且是不可变的和线程安全的。
  • java.time.chrono 用于表示除默认 ISO-8601 之外的日历系统的 API。你也可以定义自己的日历系统。本教程不会详细介绍此包。
  • java.time.format 用于格式化和解析日期和时间的类。
  • java.time.temporal 扩展 API,主要用于框架和库编写者,允许日期和时间类之间进行互操作、查询和调整。字段 (TemporalFieldChronoField) 和单位 (TemporalUnitChronoUnit) 在此包中定义。
  • java.time.zone 支持时区、时区偏移量和时区规则的类。如果使用时区,大多数开发人员只需要使用 ZonedDateTime 以及 ZoneIdZoneOffset

 

方法命名约定

日期时间 API 在一组丰富的类中提供了一组丰富的方法。方法名称在尽可能的情况下在类之间保持一致。例如,许多类提供了一个 now 方法,该方法捕获与该类相关的当前时刻的日期或时间值。有一些 from 方法允许从一个类转换为另一个类。

方法名称前缀也存在标准化。由于日期时间 API 中的大多数类都是不可变的,因此 API 不包含 set 方法。(创建后,不可变对象的值无法更改。set 方法的不可变等效项是 with。)下表列出了常用的前缀

 

前缀 方法类型 用途
of 静态工厂 创建实例,其中工厂主要验证输入参数,而不是转换它们。
from 静态工厂 将输入参数转换为目标类的实例,这可能涉及从输入中丢失信息。
parse 静态工厂 解析输入字符串以生成目标类的实例。
format 实例 使用指定的格式化程序将时间对象中的值格式化为字符串。
get 实例 返回目标对象状态的一部分。
is 实例 查询目标对象的状态。
with 实例 返回目标对象的副本,其中一个元素已更改;这是 JavaBean 上 set 方法的不可变等效项。
plus 实例 返回目标对象的副本,其中添加了一段时间。
minus 实例 返回目标对象的副本,其中减去了一段时间。
to 实例 将此对象转换为另一种类型。
at 实例 将此对象与另一个对象组合。

上次更新: 2022 年 1 月 27 日


当前教程
日期时间 API 概述
系列中的下一个

系列中的下一个: 标准日历