本文翻译自:Converting between java.time.LocalDateTime and java.util.Date
Java 8 has a completely new API for date and time. Java 8具有用于日期和时间的全新API。 One of the most useful classes in this API is LocalDateTime
, for holding a timezone-independent date-with-time value. 此API中最有用的类之一是LocalDateTime
,用于保存与时区无关的date-with-time值。
There are probably millions of lines of code using the legacy class java.util.Date
for this purpose. 为此,可能使用遗留类java.util.Date
数百万行代码。 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? 由于似乎没有直接的方法可以完成此操作,因此该怎么办呢?
参考:https://stackoom.com/question/1JWx0/在java-time-LocalDateTime和java-util-Date之间进行转换
I'm not sure if this is the simplest or best way, or if there are any pitfalls, but it works: 我不确定这是最简单还是最好的方法,或者是否有任何陷阱,但是它可以工作:
static public LocalDateTime toLdt(Date date) {
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(date);
ZonedDateTime zdt = cal.toZonedDateTime();
return zdt.toLocalDateTime();
}
static public Date fromLdt(LocalDateTime ldt) {
ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
GregorianCalendar cal = GregorianCalendar.from(zdt);
return cal.getTime();
}
Here is what I came up with ( and like all Date Time conundrums it is probably going to be disproved based on some weird timezone-leapyear-daylight adjustment :D ) 这是我想出的(和所有日期时间难题一样,它可能会根据一些奇怪的时区-ap年-日光调整:D来反证)
Date
<<->> LocalDateTime
往返: Date
<<->> LocalDateTime
Given: Date date = [some date]
给定: Date date = [some date]
(1) LocalDateTime
<< Instant
<< Date
(1) LocalDateTime
<< Instant
<< Date
Instant instant = Instant.ofEpochMilli(date.getTime());
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
(2) Date
<< Instant
<< LocalDateTime
(2) Date
<< Instant
<< LocalDateTime
Instant instant = ldt.toInstant(ZoneOffset.UTC);
Date date = Date.from(instant);
Example: 例:
Date date = new Date();
System.out.println(date + " long: " + date.getTime());
LocalDateTime
<< Instant
<< Date
: (1) LocalDateTime
<< Instant
<< Date
: Create Instant
from Date
: 从Date
创建Instant
:
Instant instant = Instant.ofEpochMilli(date.getTime());
System.out.println("Instant from Date:\n" + instant);
Create Date
from Instant
(not necessary,but for illustration): 从Instant
创建Date
(不是必需的,但用于说明):
date = Date.from(instant);
System.out.println("Date from Instant:\n" + date + " long: " + date.getTime());
Create LocalDateTime
from Instant
从Instant
创建LocalDateTime
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
System.out.println("LocalDateTime from Instant:\n" + ldt);
Date
<< Instant
<< LocalDateTime
(2) Date
<< Instant
<< LocalDateTime
Create Instant
from LocalDateTime
: 从LocalDateTime
创建Instant
:
instant = ldt.toInstant(ZoneOffset.UTC);
System.out.println("Instant from LocalDateTime:\n" + instant);
Create Date
from Instant
: 从Instant
创建Date
:
date = Date.from(instant);
System.out.println("Date from Instant:\n" + date + " long: " + date.getTime());
Fri Nov 01 07:13:04 PDT 2013 long: 1383315184574
Instant from Date:
2013-11-01T14:13:04.574Z
Date from Instant:
Fri Nov 01 07:13:04 PDT 2013 long: 1383315184574
LocalDateTime from Instant:
2013-11-01T14:13:04.574
Instant from LocalDateTime:
2013-11-01T14:13:04.574Z
Date from Instant:
Fri Nov 01 07:13:04 PDT 2013 long: 1383315184574
Everything is here : http://blog.progs.be/542/date-to-java-time 一切都在这里: http : //blog.progs.be/542/date-to-java-time
The answer with "round-tripping" is not exact : when you do “往返”的答案并不确切:当您这样做时
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
if your system timezone is not UTC/GMT, you change the time ! 如果您的系统时区不是UTC / GMT,请更改时间!
the following seems to work when converting from new API LocalDateTime into java.util.date: 从新的API LocalDateTime转换为java.util.date时,以下方法似乎起作用:
Date.from(ZonedDateTime.of({time as LocalDateTime}, ZoneId.systemDefault()).toInstant());
the reverse conversion can be (hopefully) achieved similar way... 反向转换可以(希望)以类似的方式实现...
hope it helps... 希望能帮助到你...
Short answer: 简短答案:
Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
Explanation: (based on this question about LocalDate
) 说明:(基于有关LocalDate
问题 )
Despite its name, java.util.Date
represents an instant on the time-line, not a "date". 尽管其名称, java.util.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). 自1970-01-01T00:00Z(1970 GMT / UTC开始的午夜)以来,存储在对象中的实际数据是很long
的毫秒数。
The equivalent class to java.util.Date
in JSR-310 is Instant
, thus there are convenient methods to provide the conversion to and fro: JSR-310中与java.util.Date
等效的类是Instant
,因此有方便的方法来回转换:
Date input = new Date();
Instant instant = input.toInstant();
Date output = Date.from(instant);
A java.util.Date
instance has no concept of time-zone. 一个java.util.Date
实例没有时区的概念。 This might seem strange if you call toString()
on a java.util.Date
, because the toString
is relative to a time-zone. 如果在java.util.Date
上调用toString()
,这似乎很奇怪,因为toString
是相对于时区的。 However that method actually uses Java's default time-zone on the fly to provide the string. 但是,该方法实际上在运行时使用了Java的默认时区来提供字符串。 The time-zone is not part of the actual state of java.util.Date
. 时区不是java.util.Date
实际状态的一部分。
An Instant
also does not contain any information about the time-zone. Instant
也不包含有关时区的任何信息。 Thus, to convert from an Instant
to a local date-time it is necessary to specify a time-zone. 因此,要将Instant
时间转换为本地日期时间,必须指定一个时区。 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. 这可能是默认区域ZoneId.systemDefault()
-或可能是您的应用程序控制的时区,例如用户首选项中的时区。 LocalDateTime
has a convenient factory method that takes both the instant and time-zone: LocalDateTime
有一个方便的工厂方法,该方法同时使用即时和时区:
Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
In reverse, the LocalDateTime
the time-zone is specified by calling the atZone(ZoneId)
method. 相反,可以通过调用atZone(ZoneId)
方法来指定时区的LocalDateTime
。 The ZonedDateTime
can then be converted directly to an Instant
: 然后可以将ZonedDateTime
直接转换为Instant
:
LocalDateTime ldt = ...
ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
Date output = Date.from(zdt.toInstant());
Note that the conversion from LocalDateTime
to ZonedDateTime
has the potential to introduce unexpected behaviour. 请注意,从LocalDateTime
到ZonedDateTime
的转换可能会引入意外的行为。 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. 有关转换功能的更多定义,请参见atZone(ZoneId)
的Javadoc。
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
往返于LocalDateTime
并返回到java.util.Date
,则由于夏时制,最终结果可能会有所不同。
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. java.util.Date
使用一个日历,该日历在1582年10月15日更改,其日期之前使用儒略历而不是公历。 By contrast, java.time.*
uses the ISO calendar system (equivalent to the Gregorian) for all time. 相比之下, java.time.*
使用ISO日历系统(等同于公历)。 In most use cases, the ISO calendar system is what you want, but you may see odd effects when comparing dates before year 1582. 在大多数使用情况下,ISO日历系统是您所需要的,但是在比较1582年之前的日期时,您可能会看到奇怪的效果。