Friday, September 3, 2021

How to Convert java.util.Date to LocalDate in Java 8 - Example 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 libraries and systems you interact with 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 are used to represent dates in Java they are not quite the same, they don't contain even similar information.

For example, the old Date class contains both date and time components but LocalDate is 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 convert 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 a timezone associated with it but when you print it will print in the system's default time zone. Similarly, the LocalDate is also the date of the local timezone i.e. it will give you the date of the machine where Java is running.

Btw, these are just the tip of the iceberg of the 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 courses 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 your situation, but we'll analyze the 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 the Date represents both date and time, but without a 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 the old Date to the Instant class, you can convert it into ZonedDateTime by using the default timezone of the System.

Why we have used the default timezone, given LocalDate doesn't store timezone information? Well, because the date can change when the 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 the 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 milliseconds from Epoch, which can then be used to create java.sql.Date.

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

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 the new and old Date and time API, you can further in the What's New in Java 8 course on Pluralsight.  It has nicely explained the connection between old and new Date-Time API.








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 the util date to the SQL date.

You get the number of milliseconds 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 a doubt that why not such a 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 developers 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 are 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.

The 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 contains date value, no time fractions. This is why you have a toLocalDate() method defined in this class.

So, next time, you retrieve the 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 the new Date and Time API, I suggest checking the following resources to learn more about Java 8 features.


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)
  • My favorite free courses to learn Java in-depth (courses)
  • How to calculate the difference between two dates in Java? (example)
  • 10 Courses to learn Java for Beginners (courses)
  • How to join multiple String by a comma in Java 8? (tutorial)
  • 7 Best courses to learn Data Structure and Algorithms (courses)
  • 5 books to learn Java 8 and Functional Programming (books)
  • 10 Example of Lambda Expression in Java 8 (see here)
  • Top 5 Courses to learn Functional Programming in Java (courses)
  • 10 Example of forEach() method in Java 8 (example)
  • 10 Example of converting a List to Map in Java 8 (example)
  • 5 courses to learn Lambads and Stream in Java (courses)
  • 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 it 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 these best Java 8 online courses. 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

Feel free to comment, ask questions if you have any doubt.