本教程适用于JDK 8。本页面描述的示例和实践不利用后续版本引入的改进,可能使用不再可用的技术。
有关Java SE 9及后续版本中更新的语言特性的摘要,请参阅Java语言变更。
有关所有JDK版本的新功能、增强功能以及删除或弃用选项的信息,请参阅JDK发行说明。
在Java SE 8发布之前,Java的日期和时间机制是由java.util.Date
,java.util.Calendar
和java.util.TimeZone
类及其子类(例如java.util.GregorianCalendar)提供的。这些类有一些缺点,包括:
也许您有使用java.util日期和时间类的旧代码,并且希望在代码中进行最少更改的情况下利用java.time的功能。
JDK 8发布中添加了几个方法,允许在java.util和java.time对象之间进行转换:
以下示例将Calendar实例转换为ZonedDateTime实例。请注意,必须提供时区才能从Instant转换为ZonedDateTime:
Calendar now = Calendar.getInstance(); ZonedDateTime zdt = ZonedDateTime.ofInstant(now.toInstant(), ZoneId.systemDefault()));
以下示例展示了一个 Date 到 Instant 的转换:
Instant inst = date.toInstant(); Date newDate = Date.from(inst);
以下示例将 GregorianCalendar 转换为 ZonedDateTime,然后将 ZonedDateTime 转换为 GregorianCalendar。其他基于时间的类使用 ZonedDateTime 实例创建:
GregorianCalendar cal = ...; TimeZone tz = cal.getTimeZone(); int tzoffset = cal.get(Calendar.ZONE_OFFSET); ZonedDateTime zdt = cal.toZonedDateTime(); GregorianCalendar newCal = GregorianCalendar.from(zdt); LocalDateTime ldt = zdt.toLocalDateTime(); LocalDate date = zdt.toLocalDate(); LocalTime time = zdt.toLocalTime();
由于 Java SE 8 版本中的 Java 日期和时间实现已完全重新设计,您不能仅仅替换一个方法来使用另一个方法。如果您想要使用 java.time 包提供的丰富功能,最简单的解决方案是使用前面部分列出的 toInstant 或 toZonedDateTime 方法。然而,如果您不想使用该方法或该方法不满足您的需求,则必须重写您的日期时间代码。
在 概述 页面上介绍的表格是评估哪个 java.time 类满足您需求的好起点。
两个 API 之间没有一一对应的映射关系,但下表大致列出了 java.util 日期和时间类的哪些功能对应到 java.time 的 API。
java.util功能 | java.time功能 | 备注 |
---|---|---|
java.util.Date | java.time.Instant | Instant和Date类相似。每个类: - 表示时间线上的一个瞬时点(UTC) - 持有独立于时区的时间 - 以纪元秒数(自1970-01-01T00:00:00Z起)加上纳秒来表示 Date.from(Instant)和Date.toInstant()方法允许在这些类之间进行转换。 |
java.util.GregorianCalendar | java.time.ZonedDateTime | ZonedDateTime类是GregorianCalendar的替代品。它提供了以下类似的功能。 人类时间表示如下: LocalDate:年、月、日 LocalTime:小时、分钟、秒、纳秒 ZoneId:时区 ZoneOffset:与GMT的当前偏移量 GregorianCalendar.from(ZonedDateTime)和GregorianCalendar.to(ZonedDateTime)方法可方便地在这些类之间进行转换。 |
java.util.TimeZone | java.time.ZoneId或java.time.ZoneOffset | ZoneId类指定时区标识符,并访问每个时区使用的规则。ZoneOffset类仅指定与格林威治/UTC的偏移量。更多信息,请参见时区和偏移量类。 |
日期设置为1970-01-01的GregorianCalendar | java.time.LocalTime | 将日期设置为1970-01-01的GregorianCalendar实例以使用时间组件的代码可以替换为LocalTime实例。 |
时间设置为00:00的GregorianCalendar | java.time.LocalDate | 将时间设置为00:00的GregorianCalendar实例以使用日期组件的代码可以替换为LocalDate实例。(这种GregorianCalendar方法存在缺陷,因为某些国家在每年转换到夏令时时,午夜不会发生。) |
尽管java.time.format.DateTimeFormatter提供了一个强大的机制来格式化日期和时间值,但你也可以直接使用java.time基于时间的类与java.util.Formatter和String.format一起使用,使用与java.util日期和时间类相同的基于模式的格式化。