在 java.time.LocalDateTime 和 java.util.Date 之间转换 [英] Converting between java.time.LocalDateTime and java.util.Date

查看:32
本文介绍了在 java.time.LocalDateTime 和 java.util.Date 之间转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java 8 具有用于日期和时间的全新 API.此 API 中最有用的类之一是 LocalDateTime,用于保存与时区无关的日期时间值.

Java 8 has a completely new API for date and time. One of the most useful classes in this API is LocalDateTime, for holding a timezone-independent date-with-time value.

可能有数百万行代码使用遗留类 java.util.Date 用于此目的.因此,当连接新旧代码时,需要在两者之间进行转换.好像没有直接的方法可以实现,怎么做呢?

There are probably millions of lines of code using the legacy class java.util.Date for this purpose. As such, when interfacing old and new code there will be a need for converting between the two. As there seems to be no direct methods for accomplishing this, how can it be done?

推荐答案

简答:

Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());

说明:(基于这个问题关于LocalDate)

尽管名称如此,java.util.Date 表示时间线上的一个瞬间,而不是日期".对象中存储的实际数据是自 1970-01-01T00:00Z(格林威治标准时间 1970/UTC 开始时的午夜)以来的 long 毫秒计数.

Despite its name, java.util.Date represents an instant on the time-line, not a "date". The actual data stored within the object is a long count of milliseconds since 1970-01-01T00:00Z (midnight at the start of 1970 GMT/UTC).

JSR-310中java.util.Date的等价类是Instant,因此有方便的方法来提供来回转换:

The equivalent class to java.util.Date in JSR-310 is Instant, thus there are convenient methods to provide the conversion to and fro:

Date input = new Date();
Instant instant = input.toInstant();
Date output = Date.from(instant);

java.util.Date 实例没有时区的概念.如果您在 java.util.Date 上调用 toString(),这可能看起来很奇怪,因为 toString 是相对于时区的.然而,该方法实际上使用 Java 的默认时区即时提供字符串.时区不是 java.util.Date 的实际状态的一部分.

A java.util.Date instance has no concept of time-zone. This might seem strange if you call toString() on a java.util.Date, because the toString is relative to a time-zone. However that method actually uses Java's default time-zone on the fly to provide the string. The time-zone is not part of the actual state of java.util.Date.

Instant 也不包含任何有关时区的信息.因此,要将 Instant 转换为本地日期时间,必须指定时区.这可能是默认区域 - ZoneId.systemDefault() - 或者它可能是您的应用程序控制的时区,例如来自用户首选项的时区.LocalDateTime 有一个方便的工厂方法,可以同时获取即时和时区:

An Instant also does not contain any information about the time-zone. Thus, to convert from an Instant to a local date-time it is necessary to specify a time-zone. This might be the default zone - ZoneId.systemDefault() - or it might be a time-zone that your application controls, such as a time-zone from user preferences. LocalDateTime has a convenient factory method that takes both the instant and time-zone:

Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());

相反,LocalDateTime 时区是通过调用atZone(ZoneId) 方法指定的.ZonedDateTime 然后可以直接转换为 Instant:

In reverse, the LocalDateTime the time-zone is specified by calling the atZone(ZoneId) method. The ZonedDateTime can then be converted directly to an Instant:

LocalDateTime ldt = ...
ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
Date output = Date.from(zdt.toInstant());

请注意,从 LocalDateTimeZonedDateTime 的转换可能会引入意外行为.这是因为由于夏令时,并非每个本地日期时间都存在.在秋季/秋季,本地时间线存在重叠,同一本地日期时间出现两次.在春天,有一个缺口,一个小时消失了.参见的JavadocatZone(ZoneId) 有关转换将执行的操作的更多定义.

Note that the conversion from LocalDateTime to ZonedDateTime has the potential to introduce unexpected behaviour. This is because not every local date-time exists due to Daylight Saving Time. In autumn/fall, there is an overlap in the local time-line where the same local date-time occurs twice. In spring, there is a gap, where an hour disappears. See the Javadoc of atZone(ZoneId) for more the definition of what the conversion will do.

总结,如果您将 java.util.Date 往返到 LocalDateTime 并返回到 java.util.Date由于夏令时,可能会以不同的时刻结束.

Summary, if you round-trip a java.util.Date to a LocalDateTime and back to a java.util.Date you may end up with a different instant due to Daylight Saving Time.

附加信息:还有另一个差异会影响非常旧的日期.java.util.Date 使用在 1582 年 10 月 15 日更改的日历,在此之前的日期使用儒略历而不是公历.相比之下,java.time.* 始终使用 ISO 日历系统(相当于公历).在大多数用例中,ISO 日历系统正是您想要的,但在比较 1582 年之前的日期时,您可能会看到奇怪的效果.

Additional info: There is another difference that will affect very old dates. java.util.Date uses a calendar that changes at October 15, 1582, with dates before that using the Julian calendar instead of the Gregorian one. By contrast, java.time.* uses the ISO calendar system (equivalent to the Gregorian) for all time. In most use cases, the ISO calendar system is what you want, but you may see odd effects when comparing dates before year 1582.

这篇关于在 java.time.LocalDateTime 和 java.util.Date 之间转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆