Skip navigation links
Java™ Platform
Standard Ed. 8

Package java.time

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

See: 描述

Package java.time Description

日期,时间,瞬间和持续时间的主要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是最接近的相当类别java.util.Date ZonedDateTime是最接近等价类java.util.GregorianCalendar

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

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

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

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

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

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

多个日历系统是设计挑战的难题。 第一个主要是大多数用户想要标准的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);
   } 
从以下版本开始:
JDK1.8
Skip navigation links
Java™ Platform
Standard Ed. 8