Among plenty of improvements, Java 8 came with a completely new API for dates, times, instants, and durations (java.time package). However, there are thousands of projects that use the legacy java.util.Date for date and time presentation purpose. As Oracle did not provide any direct way of converting between java.time and java.util.Date class, I would like to share with you some ways of doing so.

The conversion itself is not very complicated, however, it might be a bit confusing as we are converting between java.util.Date, which stores time zone information, and java.time.LocalDateTime / java.time.LocalDate which do not store time zone details at all.

So let's crack on:

Conversion from java.util.Date to java.time.LocalDateTime

In order to perform this conversion, we will have to use java.time.Instant class which is essentially a numeric timestamp.

So the conversion will look as follows:

  1. java.util.Date will be converted to the Instant instace (Date.toInstant()) and then
  2. LocalDateTime will be created from the Instant object using LocalDateTime.ofInstant().

Note that you will need to provide a time zone during the last step of conversion. I've used system default zone in this example:

Date dateToConvert = new Date();
LocalDateTime dateTime = LocalDateTime.ofInstant(dateToConvert.toInstant(), ZoneId.systemDefault());

System.out.println(dateToConvert);
System.out.println(dateTime);

And the output is as follows:

Wed Jun 25 13:35:49 BST 2014
2014-06-25T13:35:49.980

Conversion from java.util.Date to java.time.LocalDate

That conversion is very similar to the previous one as java.time.LocalDate stores a date without a time so it will be very easy to extract it from the java.time.LocalDateTime using LocalDateTime.toLocalDate().

Date dateToConvert = new Date();
LocalDate dateOnly = LocalDateTime.ofInstant(
    dateToConvert.toInstant(), ZoneId.systemDefault()).toLocalDate();

System.out.println(dateToConvert);
System.out.println(dateOnly);

And the output is like:

Wed Jun 25 13:01:47 BST 2014
2014-06-25

Conversion from java.time.LocalDateTime to java.util.Date

This conversion, similarly to the first one, will have to happen via java.time.Instant class. So we need to convert our LocalDateTime instance into Instant (note that we will have to provide zone offset during that convertion) and then create java.util.Date using static Date.from() method.

Note that LocalDateTime was converted to java.time.ZonedDateTime (a date and time with a time-zone) first. Alternatively we could use direct conversion to Instant using toInstant method with ZoneOffset information.

Example:

LocalDateTime dateTimeToConvert = LocalDateTime.now();
Date convertToDate = Date.from(dateTimeToConvert.atZone(ZoneId.systemDefault()).toInstant());

System.out.println(dateTimeToConvert);
System.out.println(convertToDate);

And the output is like:

2014-06-25T13:41:18.012
Wed Jun 25 13:41:18 BST 2014

Conversion from java.time.LocalDate to java.util.Date

This conversion is pretty similar to the previous one with one exception: LocalDate stores a date without a time and in order to convert it to the Instant object, we will have to perform conversion to LocalDateTime object first. We can do that using method, say, LocalDate.atStartOfDay(), which will set local time to midnight.

So our code will look as follows:

LocalDate dateToConvert = LocalDate.now();
Date convertToDate =
    Date.from(dateToConvert.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());

System.out.println(dateToConvert);
System.out.println(convertToDate);

And the output is like:

2014-06-25
Wed Jun 25 00:00:00 BST 2014

Enjoy!