文档

Java™ 教程-Java Tutorials 中文版
旧版日期时间代码
Trail: Date Time
Lesson: Standard Calendar

旧版日期时间代码

在 Java SE 8 发行版之前,Java 日期和时间机制由 java.util.Datejava.util.Calendarjava.util.TimeZone 类及其子类,例如 java.util.GregorianCalendar 提供。这些类有几个缺点,包括:

与旧版代码的互操作性

也许你有遗留代码使用 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()));

以下示例显示 DateInstant 之间的转换:

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.util 日期和时间功能映射到 java.time

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

Overview 页面上介绍的表是开始计算哪些 java.time 类满足你需求的好地方。

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

java.util 功能 java.time 功能 注释
java.util.Date java.time.Instant InstantDate 类相似。每个类:
- 表示时间线(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.ZoneIdjava.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.FormatterString.format 一起使用,使用与 java.util 日期和时间类相同的基于模式的格式。


Previous page: Non-ISO Date Conversion
Next page: Summary