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

本文翻译自: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? 由于似乎没有直接的方法可以完成此操作,因此该怎么办呢?


#1楼

参考:https://stackoom.com/question/1JWx0/在java-time-LocalDateTime和java-util-Date之间进行转换


#2楼

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();
}

#3楼

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来反证)

Round-tripping: 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: 例:

Given: 鉴于:

Date date = new Date();
System.out.println(date + " long: " + date.getTime());

(1) 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);

(2) 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());

The output is: 输出为:

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

#4楼

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,请更改时间!


#5楼

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... 希望能帮助到你...


#6楼

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. 请注意,从LocalDateTimeZonedDateTime的转换可能会引入意外的行为。 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年之前的日期时,您可能会看到奇怪的效果。

你可能感兴趣的:(在java.time.LocalDateTime和java.util.Date之间进行转换)