系列中的上一篇
当前教程
旧版日期时间代码
这是本系列的最后一篇!

系列中的上一篇: 非 ISO 日期转换

旧版日期时间代码

在 Java SE 8 版本之前,Java 日期和时间机制由 java.util.Datejava.util.Calendarjava.util.TimeZone 类及其子类(如 java.util.GregorianCalendar)提供。这些类存在一些缺点,包括

  • Calendar 类不是类型安全的。
  • 由于这些类是可变的,因此不能在多线程应用程序中使用它们。
  • 由于月份编号不寻常以及缺乏类型安全性,应用程序代码中的错误很常见。

 

与旧版代码的互操作性

也许您有使用 java.util 日期和时间类的旧版代码,并且您希望利用 java.time 功能,同时对代码进行最少的更改。

JDK 8 版本中添加了一些方法,允许在 java.utiljava.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();

 

将旧版日期和时间功能映射到日期时间 API

由于 Java 中的日期和时间实现已在 Java SE 8 版本中完全重新设计,因此您无法将一种方法替换为另一种方法。如果您想使用 java.time 包提供的丰富功能,最简单的解决方案是使用上一节中列出的 toInstant()toZonedDateTime() 方法。但是,如果您不想使用这种方法,或者它不足以满足您的需求,那么您必须重写日期时间代码。

概述 页面上介绍的 表格 是一个很好的起点,可以评估哪些 java.time 类满足您的需求。

这两个 API 之间没有一对一的映射对应关系,但下表让您大致了解 java.util 日期和时间类中的哪些功能映射到 java.time API。

旧版 Date 和 Instant 之间的对应关系

InstantDate 类很相似。每个类

  • 表示时间轴上的一个瞬时时间点(UTC)
  • 保存与时区无关的时间
  • 表示为纪元秒(自 1970-01-01T00:00:00Z 以来)加上纳秒

Date.from(Instant)Date.toInstant() 方法允许在这些类之间进行转换。

GregorianCalendar 和 ZonedDateTime 之间的对应关系

ZonedDateTime 类是 GregorianCalendar 的替代品。它提供了以下类似的功能。人类时间表示如下

GregorianCalendar.from(ZonedDateTime)GregorianCalendar.toZonedDateTime() 方法便于在这些类之间进行转换。

旧版 TimeZone 和 ZoneId 或 ZoneOffset 之间的对应关系

ZoneId 类指定一个时区标识符,并可以访问每个时区使用的规则。 ZoneOffset 类仅指定与格林威治/UTC 的偏移量。有关更多信息,请参见 时区和偏移量类

日期设置为 1970-01-01 的 GregorianCalendar 与 LocalTime 之间的对应关系

将日期设置为 1970-01-01 的 GregorianCalendar 实例以使用时间组件的代码可以替换为 LocalTime 的实例。

时间设置为 00:00 的 GregorianCalendar 与 LocalDate 之间的对应关系

将时间设置为 00:00 的 GregorianCalendar 实例以使用日期组件的代码可以替换为 LocalDate 的实例。(这种 GregorianCalendar 方法存在缺陷,因为由于夏令时的转换,一些国家/地区每年都会出现午夜。)

 

日期和时间格式化

尽管java.time.format.DateTimeFormatter 提供了强大的日期和时间值格式化机制,但您也可以直接使用java.time 基于时间类的java.util.FormatterString.format(),使用与java.util 日期和时间类相同的基于模式的格式化。


上次更新: 2022 年 1 月 27 日


系列中的上一篇
当前教程
旧版日期时间代码
这是本系列的最后一篇!

系列中的上一篇: 非 ISO 日期转换