Module  java.base

Package java.time

日期,时间,瞬间和持续时间的主要API。

这里定义的类代表主要的日期时间概念,包括时刻,持续时间,日期,时间,时区和时段。 它们基于ISO日历系统,这是遵循激进的格里高利规则的事实上的世界日历。 所有的类都是不可变的,线程安全的。

每个日期时间实例由API方便地提供的字段组成。 对于较低级别的访问,请参阅java.time.temporal软件包。 每个类都支持打印和解析各种日期和时间。 有关自定义选项,请参阅java.time.format包。

java.time.chrono包包含日历中立API ChronoLocalDateChronoLocalDateTimeChronoZonedDateTimeEra 这适用于需要使用本地化日历的应用程序。 建议应用程序在系统边界使用ISO-8601日期和时间类,例如数据库或跨网络。 日历中性API应保留用于与用户的交互。

日期和时间

Instant本质上是一个数字时间戳。 当前Instant可以从Clock检索。 这对于一个时间点的记录和持久性是有用的,并且在过去已经与从System.currentTimeMillis()存储结果相关联。

LocalDate存储一个没有时间的日期。 它存储一个像“2010-12-03”这样的日期,可以用来存储一个生日。

LocalTime存储没有日期的时间。 这样可以储存一个像“11:30”这样的时间,可以用来存储一个开或关的时间。

LocalDateTime存储日期和时间。 这样可以存储像2010-12-03T11:30这样的日期。

ZonedDateTime存储具有时区的日期和时间。 如果您想要考虑到ZoneId (如“欧洲/巴黎”)的日期和时间进行准确计算,这很有用。 在可能的情况下,建议在没有时区的情况下使用更简单的类。 时区的广泛使用往往会增加应用程序的相当大的复杂性。

期限和期限

除了日期和时间之外,API还允许存储期间和持续时间。 A Duration是以纳秒为单位的时间线的简单测量。 A Period以对人类有意义的单位(例如年数或日期)表示一段时间。

附加价值类型

Month自己存储一个月。 这个单独的一个月是独立的,比如“十二月”。

DayOfWeek自己存储一周的一天。 这样就可以隔离一个星期,例如“TUESDAY”。

Year自己存储一年。 这个单独的一年是独立的,比如“2010”。

YearMonth存储一年没有一天或一个时间的年份和月份。 这可以存储一年和一个月,如“2010-12”,可用于信用卡到期。

MonthDay存储一个月,一天没有一年或一个时间。 这可以存储一个月和一个月的日期,例如“ - 12-03”,可以用来存储年度事件,如生日,而不存储年份。

OffsetTime存储与UTC没有日期的时间和偏移量。 这样可以存储像'11:30 + 01:00'的日期。 ZoneOffset的形式是“+01:00”。

OffsetDateTime存储与UTC的日期和时间和偏移量。 这样可以存储像2010-12-03T11:30 + 01:00这样的日期。 这有时在XML消息和其他形式的持久性中找到,但是包含的信息少于全时区。

包装规格

除非另有说明,否则在此包中的任何类或接口中将null参数传递给构造函数或方法将导致抛出NullPointerException Javadoc“@param”定义用于总结空行为。 @throws NullPointerException ”没有在每个方法中明确记录。

所有计算应检查数字溢出并抛出ArithmeticExceptionDateTimeException

设计说明(非规范性)

API已被设计为提前拒绝null并清除此行为。 一个关键的例外是任何接受对象并返回布尔值的方法,为了检查或验证,通常会为null返回false。

该API旨在在主要高级API中合理的情况下是类型安全的。 因此,对于日期,时间和日期时间的不同概念,还有偏移和时区的变体,都有单独的类。 这似乎是很多类,但大多数应用程序只能开始五个日期/时间类型。

  • Instant - 时间戳
  • LocalDate - 没有时间的日期,或任何对偏移或时区的引用
  • LocalTime - 没有日期的时间,或任何对偏移量或时区的引用
  • LocalDateTime - 结合日期和时间,但仍没有任何偏移或时区
  • ZonedDateTime - 一个“完整”的日期时间与时区和解决偏离UTC /格林威治

Instant是最接近相当于java.util.Date类。 ZonedDateTime是最接近的等价类java.util.GregorianCalendar

如果可能的话,应用程序应该使用LocalDateLocalTimeLocalDateTime ,以更好的模型域。 例如,生日应该存储在代码LocalDate 请记住,任何使用time-zone (例如“欧洲/巴黎”)的计算增加了相当大的复杂性。 许多应用程序只能使用被写入LocalDateLocalTimeInstant ,与在用户界面(UI)层添加的时区。

基于偏移的日期时间类型OffsetTimeOffsetDateTime主要用于网络协议和数据库访问。 例如,大多数数据库不能自动存储像“欧洲/巴黎”这样的时区,但是它们可以存储像“+02:00”这样的偏移量。

还提供了一个迄今为止最重要的子部分,包括类MonthDayOfWeekYearYearMonthMonthDay 这些可用于建模更复杂的日期时间概念。 例如, YearMonth可用于表示信用卡到期。

请注意,虽然有大量代表日期不同方面的课程,但在时间的不同方面处理相对较少。 根据类型安全性,其逻辑结论将导致小时,小时 - 秒和小时 - 秒 - 二秒的课程。 虽然在逻辑上是纯粹的,但这不是一个实际的选择,因为日期和时间的组合,课程的数量几乎增加了两倍。 因此, LocalTime用于所有时间精度,零被用于暗示较低的精度。

在完全类型安全性的最终结论之后,也可能会争论在日期时间中每个字段的单独类,例如HourOfDay的类和DayOfMonth的另一个类。 这种方法被尝试,但是在Java语言中过于复杂,缺乏可用性。 周期也会出现类似的问题。 每个期间单位都有一个单独的课程,例如“年”和“分钟”类型。 但是,这会产生很多类和类型转换的问题。 因此,提供的日期 - 时间类型是纯度和实用性之间的妥协。

API方法的表面面积相对较大。 这是通过使用一致的方法前缀来管理的。

  • of - 静态工厂方法
  • parse - 静态工厂方法集中于解析
  • get - 获取某物的价值
  • is - 检查是否有事情
  • with - 不可变的相当于一个设定者
  • plus - 向对象添加金额
  • minus - 从对象中减去金额
  • to - 将此对象转换为另一种类型
  • at - 将此对象与另一个对象组合,如date.atTime(time)

多个日历系统是设计挑战的难题。 第一个原则是大多数用户想要标准的ISO日历系统。 因此,主要类别只有ISO。 第二个原则是,大多数希望使用非ISO日历系统的用户需要用户交互,因此它是一个UI本地化问题。 因此,日期和时间对象应该作为ISO对象在数据模型和永久存储中保存,只能转换为和从本地日历进行显示。 日历系统将分别存储在用户偏好中。

然而,有一些有限的用例,用户认为他们需要在整个应用程序中的任意日历系统中存储和使用日期。 这是由ChronoLocalDate支持,但是在使用该界面的Javadoc之前,请阅读所有相关警告至关重要。 总而言之,需要在多个日历系统之间进行通用互操作的应用程序通常需要以与使用ISO日历的方式完全不同的方式编写,因此大多数应用程序应仅使用ISO并避免使用ChronoLocalDate

API也是为了用户可扩展性设计的,因为有很多计算时间的方法。 fieldunit API,通过访问TemporalAccessorTemporal提供了很大的灵活应用。 此外, TemporalQueryTemporalAdjuster接口提供日常功能,允许代码阅读接近业务需求:

  LocalDate customerBirthday = customer.loadBirthdayFromDatabase();
   LocalDate today = LocalDate.now();
   if (customerBirthday.equals(today)) {
     LocalDate specialOfferExpiryDate = today.plusWeeks(2).with(next(FRIDAY));
     customer.sendBirthdaySpecialOffer(specialOfferExpiryDate);
   } 
从以下版本开始:
1.8