Convert Date to LocalDate or LocalDateTime and Back

1. Overview

Starting with Java 8, we have a new Date API – java.time.

However, sometimes we still need to perform conversions between the new and the old APIs, and work with date representations from both.

Further reading:

Migrating to the New Java 8 Date Time API

A quick and practical guide on transitioning to Java 8’s new DateTime API.

Read more

Introduction to the Java 8 Date/Time API

In this article we will take a look at the new Java 8 APIs for Date and Time and how much easier it is to construct and manipulate dates and times.

Read more

2. Converting java.util.Date to java.time.LocalDate

Let’s start with converting the old date representation to the new one.

Here, we can take advantage of a new toInstant() method which was added to java.util.Date in Java 8.

When we’re converting an Instant object, it’s required to use a ZoneId, because _ _Instant objects are timezone-agnostic – just points on the timeline.

The atZone(ZoneId zone) API from Instant object returns a ZonedDateTime so we just need to extract LocalDate from it using the toLocalDate() method.

In our first example here, we’re using the default system ZoneId:

public LocalDate convertToLocalDateViaInstant(Date dateToConvert) {
    return dateToConvert.toInstant()
      .atZone(ZoneId.systemDefault())
      .toLocalDate();
}

A similar solution to the above one, but with a different way of creating an Instant object – using the ofEpochMilli() method:

public LocalDate convertToLocalDateViaMilisecond(Date dateToConvert) {
    return Instant.ofEpochMilli(dateToConvert.getTime())
      .atZone(ZoneId.systemDefault())
      .toLocalDate();
}

Before we move on, let’s also have a quick look at the old java.sql.Date class and how that can be converted to a LocalDate as well.

Starting with Java 8, we can find an additional toLocalDate() method on java.sql.Date – which also gives us an easy way of converting it to java.time.LocalDate.

In this case, we don’t need to worry about the timezone:

public LocalDate convertToLocalDateViaSqlDate(Date dateToConvert) {
    return new java.sql.Date(dateToConvert.getTime()).toLocalDate();
}

Very similarly, we can convert old Date object into a LocalDateTime object as well – let’s have a look at that next.

3. Converting java.util.Date to java.time.LocalDateTime

To get a LocalDateTime instance – we can similarly use an intermediary ZonedDateTime, and then using the toLocalDateTime() API.

Just like before, we can use two possible solutions of getting an Instant object from java.util.Date:

public LocalDateTime convertToLocalDateTimeViaInstant(Date dateToConvert) {
    return dateToConvert.toInstant()
      .atZone(ZoneId.systemDefault())
      .toLocalDateTime();
}

public LocalDateTime convertToLocalDateTimeViaMilisecond(Date dateToConvert) {
    return Instant.ofEpochMilli(dateToConvert.getTime())
      .atZone(ZoneId.systemDefault())
      .toLocalDateTime();
}

And, starting with Java 8, we can also use java.sql.Timestamp to obtain a LocalDateTime:

ocalDateTime convertToLocalDateTimeViaSqlTimestamp(Date dateToConvert) {
    return new java.sql.Timestamp(
      dateToConvert.getTime()).toLocalDateTime();
}

4. Convert java.time.LocalDate to java.util.Date

Now that we have a good understanding of how to convert form the old data representation to the new one, let’s have a look at converting in the other direction.

We’ll discuss two possible ways of converting LocalDate to Date.

In the first one, we use a new valueOf(LocalDate date) method provided in java.sql.Date object which takes LocalDate as a parameter:

public Date convertToDateViaSqlDate(LocalDate dateToConvert) {
    return java.sql.Date.valueOf(dateToConvert);
}

As we can see, it is effortless and intuitive. It uses local time zone for conversion (all is done under the hood, no need to worry).

In another, Java 8 example, we use an Instant object which we pass to the from(Instant instant) method of java.util.Date object:

public Date convertToDateViaInstant(LocalDate dateToConvert) {
    return java.util.Date.from(dateToConvert.atStartOfDay()
      .atZone(ZoneId.systemDefault())
      .toInstant());
}

You’ll notice we make use of an Instant object here, and that we also need to care about time zones when doing this conversion.

Next, let’s use a very similar solutions to convert a LocalDateTime to a Date object.

5. Convert java.time.LocalDateTime to java.util.Date

The easiest way of getting a java.util.Date from LocalDateTime is to use an extension to the java.sql.Timestamp – available with Java 8:

public Date convertToDateViaSqlTimestamp(LocalDateTime dateToConvert) {
    return java.sql.Timestamp.valueOf(dateToConvert);
}

But of course, an alternative solution is using an Instant object – which we obtain from ZonedDateTime:

Date convertToDateViaInstant(LocalDateTime dateToConvert) {
    return java.util.Date
      .from(dateToConvert.atZone(ZoneId.systemDefault())
      .toInstant());
}

6. Java 9 Additions

In Java 9, there’re new methods available which simplify conversion between java.util.Date and java.time.LocalDate or java.time.LocalDateTime.

LocalDate.ofInstant(Instant instant, ZoneId zone) and LocalDateTime.ofInstant(Instant instant, ZoneId zone) provide handy shortcuts:

public LocalDate convertToLocalDate(Date dateToConvert) {
    return LocalDate.ofInstant(
      dateToConvert.toInstant(), ZoneId.systemDefault());
}

public LocalDateTime convertToLocalDateTime(Date dateToConvert) {
    return LocalDateTime.ofInstant(
      dateToConvert.toInstant(), ZoneId.systemDefault());
}

7. Conclusion

In this tutorial, we covered possible ways of converting old java.util.Date into new java.time.LocalDate and java.time.LocalDateTime and another way around.

The full implementation of this article is available over on Github.

Leave a Reply

Your email address will not be published.