在java.time.LocalDateTime和java.util.Date之间进行转换

问题:

Java 8具有日期和时间的全新API。此API中最有用的类之一是LocalDateTime,用于保存与时区无关的日期与时间值。
为此,可能使用传统类java.util.Date的数百万行代码。因此,当连接旧的和新的代码时,将需要在两者之间进行转换。由于似乎没有直接的方法来完成这个,怎么做呢?

回答:

简答:

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

说明:
(基于this questionLocalDate
尽管它的名称,java.util.Date表示时间线上的即时,而不是“日期”。存储在对象中的实际数据是自1970-01-01T00:00Z(1970年GMT / UTC开始的午夜)以来的毫秒数的long计数。
JSR-310中的等价类为java.util.DateInstant,因此有方便的方式提供来回转换:

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的实际状态的一部分
Instant也不包含有关时区的任何信息。因此,要从Instant转换为本地日期时间,需要指定时区。这可能是默认区域 – ZoneId.systemDefault() – 或者它可能是应用程序控制的时区,例如来自用户首选项的时区。 LocalDateTime具有方便的工厂方法,同时具有时间和时区:

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

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

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

请注意,从LocalDateTimeZonedDateTime的转换有可能引入意想不到的行为。这是因为夏令时不存在每个本地的日期时间。在秋季/秋季,当地时间线上出现两次相同的本地日期时间的重叠。春天有一个差距,一小时消失。请参阅atZone(ZoneId)的Javadoc更多地定义转换将会做什么。
总结如果您将java.util.Date往返LocalDateTime并返回java.util.Date,则由于夏令时,您可能会遇到不同的时刻。
附加信息:还有另一个区别将影响非常古老的日期。 java.util.Date使用可能在1582年10月15日之前的日历,之前的日期使用朱利安历而不是公历。相比之下,java.time.*始终使用ISO日历系统(相当于公历)。在大多数用例中,ISO日历系统是您想要的,但在比较1582年之前的日期时您可能会看到奇怪的效果。

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: Converting between java.time.LocalDateTime and java.util.Date

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

− 6 = 3