Best way to convert java.util.Date to java.time.LocalDate in Java 8 - Examples

There seem to be a couple of ways to convert a java.util.Date to java.time.LocalDate in Java 8, but which one is the best way? We'll figure it out in this article, but first, let's explore these different ways to convert a java.util.Date object to LocalDate in Java 8. Btw, even though both Date and LocalDate is used to represent dates in Java they are not quite same, they don't contain even similar information. For example, the old Date class contains both date and time components but LocalDate is a just date, it doesn't have any time part in it e.g. "15-12-2016".

In order to convert java.util.Date to java.time.LocalDate, you need to ignore time part. Another key difference between Date and LocalDate is the time zone. The old date doesn't have timezone associated with it but when you print it will print in system's default time zone. Similarly, the LocalDate is also the date of local timezone i.e. it will give you the date of the machine where Java is running.



3 Ways to convert java.util.Date to java.time.LocalDate in Java 8

Here are some of the common ways to convert a java.util.Date to java.time.LocalDate class in Java 8. These approaches demonstrate different techniques of conversion and you can choose whichever you want to and depend on what suits best to your situation, but we'll analyze pros and cons of each approach and conclude which is the best and easiest way to convert old Date to new LocalDate in Java 8.


// via - Instant and ZonedDateTime

Date now = new Date();
LocalDate current = now.toInstant()
                       .atZone(ZoneId.systemDefault())
                       .toLocalDate();

This approach is simple and straightforward. Since Date represents both date and time, but without timezone, it is equivalent to new java.time.Instant class, which is nothing but a point in time scale. The Java designer provides to/from methods e.g. toInstant() to convert java.util.Date to java.time.Instant.

Once you converted old Date to Instant class, you can convert it into ZonedDateTime by using the default timezone of System. Why we use default timezone, given LocalDate doesn't store timezone information? Well, because the date can change when timezone changes and LocalDate is the date in the local timezone, hence we use ZoneId.systemDefault() to convert Instant to ZonedDateTime.

The final, toLocalDate() method strips off time and timezone related information and return you just Date. So it's a three step process but very easy once you understand basic concepts of java.time API.



// via - millisecond

Date current = LocalDate.from(Instant.ofEpochMilli(new java.util.Date().getTime())
                        .atZone(ZoneId.systemDefault()));

If you have done some JDBC and date time-related coding prior to Java 8 then you might know that the easiest way to convert from java.util.Date to java.sql.Date was by using the getTime() method, as discussed here. It returns the number of millisecond from Epoch, which can then used to create java.sql.Date.

We can use the same technique to convert java.util.Date to java.time.LocalDate in Java 8. This example is quite similar to the previous example where we first get an Instant, then timeZone information for calculating LocalDate.

If want to learn more about the relation between new and old date and time API, you can further read Java SE 8 for Really Impatient By Cay S. Horstmann. He has nicely explained the connection between old and new Date Time API.



// via - java.sql.Date (Best way)

LocalDate ld = new java.sql.Date( new java.util.Date().getTime() ).toLocalDate();

This is my favorite and certainly the best and easiest way to convert a java.util.Date to java.time.LocalDate in Java8. It's quite similar to the way we convert util date to SQL date. You get the number of millisecond from Epoch by calling getTime() to create a java.sql.Date and then just call the toLocalDate() method which is conveniently added by Java API designers for easy conversion from java.sql.Date to java.time.LocalDate.

Now, some of you might be having doubt that why not such method is added into a java.util.Date and why they have added it instead on java.sql.Date? Well, you can answer this question by yourself if you know the difference between java.util.Date and java.sql.Date class.

The java.util.Date object is not really a date e.g. "21-12-2016", instead it contains both date and time e.g. "21-12-2016:06:04", while later just contain the date, which is what LocalDate represent in new java.time API, hence a toLocalDate() method in java.sql.Date makes perfect sense. You can further read Java SE 8 for Really Impatient By Cay S. Horstmann to learn more about Java 8 Date and Time API and how to convert classes from old Date and Calendar API to new Date and Time API.

Best way to convert java.util.Date to java.time.LocalDate in Java 8


// via - individual fields

LocalDate d = LocalDate.of(now.getYear() + 1900, now.getMonth() + 1, now.getDate()); 

Though some Java developer might like this solution because it seems quite easy, just extract date, month and year from java.util.Date and create a LocalDate out of it, it's one of the worst ways to convert java.util.Date to java.time.LocalDate in Java 8. Why? because all three methods e.g. getYear(), getMonth(), and getDate() are deprecated and can be removed in future version without notice.

It's also tricky to understand the code e.g. why you adding 1900 on the year and doing plus 1 on month? It's because of java.util.Date return year from 1900 and the first month is zero in old Date API but 1 in new Date API.

3 ways to convert java.util.Date to java.time.LocalDate in Java 8


That's all about 3 ways to convert java.util.Date to java.time.LocalDate in Java 8. Actually, we have seen four ways to do the job but the second one is very similar to first one, hence you can think of the same way. Bottom line is to remember that Date is not equal to LocalDate, instead, it's equivalent class in new date and time API is Instant, hence you have the toInstant() conversion method defined in Date class.

The closest class of LocalDate in old Date and Calendar API is the java.sql.Date because similar to java.time.LocalDate this class also just contain date value, no time fractions. This is why you have a toLocalDate() method defined in this class. So, next time, you retrieve date from the database using JDBC, you can directly convert it to LocalDate as well. This is also the best way to convert java.util.Date to java.time.LocalDate in Java 8 in my opinion.

Btw, this is just the tip of the iceberg from Java 8. If you want to learn more about new features, particularly JSR 310 or new Date and Time API, I suggest reading Java 8 in Action. This book covers all features in good details.

Other Java 8 articles you may like
  • How to parse String to LocalDateTime in Java 8? (tutorial)
  • How to convert java.util.Date to java.time.LocalDateTime in Java 8? (tutorial)
  • How to convert String to LocalDateTime in Java 8? (tutorial)
  • How to calculate the difference between two dates in Java? (example)
  • How to join multiple String by a comma in Java 8? (tutorial)
  • 5 books to learn Java 8 and Functional Programming (books)


Reference
LocalDate Java 8 API


No comments:

Post a Comment