Java 8 has a completely new API for date and time. One of the most useful classes in this API is
Date in = new Date(); LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault()); Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
(based on this question about
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);
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
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
LocalDateTime ldt = ... ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault()); Date output = Date.from(zdt.toInstant());
Note that the conversion from
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.