How to Convert java.util.Date to java.time.LocalDate in Java 8 - Examples Tutorial

Hello guys, once you move to Java 8, you will often find yourself working between old and new Date and Time API, as not all the library and system you interact will be using Java 8. One of the common tasks which arise from this situation is converting old Date to new LocalDate and that's what you will learn in this tutorial. There seems 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 code.

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 like "15-12-2016", which means when you convert Date to LocalDate then time-related information will be lost and when you covert LocalDate to Date, they will be zero. 

In other words,  to convert java.util.Date to java.time.LocalDate, you need to ignore the 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.

Btw, these are just tip of the iceberg of massive new and improved DateTime API of Java 8. If you are interested to learn and master this very useful topic, I suggest you join The Complete Java MasterClass course on Udemy. One of the most up-to-date and affordable course to learn Java better, it was recently updated to cover Java 11 and we see a newer version after Java 12 release.




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.


1. Using Instant and ZonedDateTime

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 like toInstant() to convert java.util.Date to java.time.Instant Object.

Here is the code:

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


Once you converted old Date to Instant class, you can convert it into ZonedDateTime by using the default timezone of System.

Why we have used 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 returns you just Date. So it's a three-step process but very easy once you understand basic concepts of java.time API. You can further see the Java 8 New Features In Simple Way to learn more about this class and API.

How to convert java.util.Date to java.time.LocalDate in Java 8 - Examples Tutorial


2. Using Millisecond

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.

Anyway, here is the code to convert old Date to new LocalDate using millisecond. 

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



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.

I want to learn more about the relationship between new and old date and time API, you can further in What's New in Java 8 course on Pluralsight.  It has nicely explained the connection between old and new Date Time API.



Btw, you would need a Pluralsight membership to access this course which cost around $29 per month but give access to more than 5000+ online courses on Pluralsight to learn any latest technology.

Even if you don't have a membership, you can still access this course by taking advantage of their 10-day free pass which provides 200 minutes of watch time to access any course.




3. Using java.sql.Date (Best way)

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.

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


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 like "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



4. Using Individual Fields

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 like getYear()getMonth(), and getDate() are deprecated and can be removed in the future version without notice.
LocalDate d = LocalDate.of(now.getYear() + 1900, 
                           now.getMonth() + 1, 
                           now.getDate()); 

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.


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 the 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 an equivalent class in a 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 checking the following resources to learn more about Java 8 features.

Further Learning
The Complete Java MasterClass
Java SE 8 New Features
From Collections to Streams in Java 8 Using Lambda Expressions
Java Documentation of LocalDate

Other Java 8 articles you may like
  • How to parse String to LocalDateTime in Java 8? (tutorial)
  • 10 Example of Stream API in Java 8 (see here)
  • 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)
  • 10 Example of Lambda Expression in Java 8 (see here)
  • 10 Example of forEach() method in Java 8 (example)
  • 10 Example of converting a List to Map in Java 8 (example)
  • How to convert java.util.Date to java.time.LocalDateTime in Java 8? (tutorial)
  • Difference between map() and flatMap() in Java 8? (answer)
  • How to use Stream.flatMap in Java 8(example)
  • How to use Stream.map() in Java 8 (example)
  • 5 Free Courses to learn Java 8 and 9 (courses)
  • How to convert String to LocalDateTime in Java 8? (tutorial)
Thanks for reading this article so far. If you liked this article then please share with your friends and colleagues. If you have any questions or feedback then please drop a note.


P.S.: If you just want to learn more about new features in Java 8 then please see the course What's New in Java 8. It explains all the important features of Java 8 e.g. lambda expressions, streams, functional interfaces, Optional, new Date Time API and other miscellaneous changes.

No comments:

Post a Comment