Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
在 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 实现已在 Java SE 8 发行版中完全重新设计,因此你无法将一种方法替换为另一种方法。如果要使用 java.time 包提供的丰富功能,最简单的解决方案是使用列出的 toInstant 或 toZonedDateTime 方法上一节。但是,如果你不想使用该方法或者它不足以满足你的需求,那么你必须重写日期时间代码。
Overview 页面上介绍的表是开始计算哪些 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 的偏移量。有关更多信息,请参阅 Time Zone and Offset Classes。 |
GregorianCalendar,日期设为 1970-01-01 | java.time.LocalTime | 在 GregorianCalendar 实例中将日期设置为 1970-01-01 以便使用时间组件的代码可以替换为 LocalTime 的实例。 |
GregorianCalendar,时间设置为 00:00. | java.time.LocalDate | 为了使用日期组件,在 GregorianCalendar 实例中将时间设置为 00:00 的代码可以替换为 LocalDate 的实例。(这种 GregorianCalendar 方法存在缺陷,因为由于过渡到夏令时,有些国家每年不发生一次午夜。) |
虽然 java.time.format.DateTimeFormatter 提供了一种强大的日期和时间值格式化机制,但你也可以直接将 java.time 基于时间的类与 java.util.Formatter 和 String.format 一起使用,使用与 java.util 日期和时间类相同的基于模式的格式。