Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting between java.time.LocalDateTime and java.util.Date

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.

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?

like image 574
Knut Arne Vedaa Avatar asked Oct 17 '13 15:10

Knut Arne Vedaa


People also ask

What is the difference between LocalDateTime and date in Java?

LocalDate is introduced in Java API in version 1.8 version of java. The LocalDate represents a date in ISO format (yyyy-MM-dd) without time.It can be used to store dates like birthdays and paydays. Actually this new Time-Date is introduced in Java 1.8 to provide immutability and thread safety.

How does LocalDateTime compare to date?

LocalDateTime equals() Method If we want to only check if both date and time values are equal or not (i.e. represent the same time of the day in the local timeline), we can use equals() method. This method returns: true – given date is same as otherDate.

Can we convert LocalDate to date in Java?

Convert LocalDate To Date in JavaStep 1: First Create the LocalDate object using either now() or of() method. now() method gets the current date where as of() creates the LocalDate object with the given year, month and day. Step 2: Next, Get the timezone from operating system using ZoneId. systemDefault() method.


1 Answers

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)

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).

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

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.

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

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

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.

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.

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.

like image 121
JodaStephen Avatar answered Nov 27 '22 17:11

JodaStephen