旧版日期 - 时间码
原文: https://docs.oracle.com/javase/tutorial/datetime/iso/legacy.html
在 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.toInstant()
将Calendar
对象转换为Instant
。GregorianCalendar.toZonedDateTime()
将GregorianCalendar
实例转换为ZonedDateTime
。GregorianCalendar.from(ZonedDateTime)
使用来自ZonedDateTime
实例的默认语言环境创建GregorianCalendar
对象。Date.from(即时)
从Instant
创建Date
对象。Date.toInstant()
将Date
对象转换为Instant
。TimeZone.toZoneId()
将TimeZone
对象转换为ZoneId
。
以下示例将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.util 日期和时间功能映射到 java.time
由于日期和时间的 Java 实现已在 Java SE 8 发行版中完全重新设计,因此您无法将一种方法替换为另一种方法。如果您想使用java.time
软件包提供的丰富功能,最简单的解决方案是使用上一节中列出的toInstant
或toZonedDateTime
方法。但是,如果您不想使用该方法或者它不足以满足您的需求,那么您必须重写日期时间代码。
在概述页面上介绍的表是开始评估哪些java.time
类满足您需求的好地方。
两个 API 之间没有一对一的映射关系,但是下表让您大致了解java.util
日期和时间类中哪些功能映射到java。时间
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
:当前偏离 GMTGregorianCalendar.from(ZonedDateTime)
和GregorianCalendar.to(ZonedDateTime)
方法促进这些类之间的转换。 | |java.util.TimeZone
|java.time.ZoneId
或java.time.ZoneOffset
|ZoneId
类指定时区标识符,并且可以访问每个时区使用的规则。ZoneOffset
类仅指定格林威治/ UTC 的偏移量。有关更多信息,请参阅时区和偏移类。 | |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
日期和时间类相同的基于模式的格式。