Hello guys, one of the challenges Java programmers face while using the new Java 8 Date and time API, JSR-310 in the existing Java application is the conversion between java.util.Date and java.time.LocalDate and other classes.
Even though the library has everything you would expect, it doesn’t have a direct conversion method between old Date and new LocalDate. There is a reason for it, even though java.util.Date says it’s a Date it’s not, becuase it’s just a millisecond value since midnight at the start of 1970 GMT.
It’s equivalent to the Instant class in the new Java Date API and that’s why you have a direct conversion method between Date and Instant in Java 8.
Anyway, it’s not hard to convert a java.util.Date to java.time.LocalDate in Java 8, in fact, there are multiple ways which we will explore in this tutorial.
Solution 1 – using java.sql.Date
Surprisingly, it’s really easy to convert a java.sql.Date to java.time.LocalDate in Java 8, becuase JDK 8 has added a convenience method toLocalDate() into this class.
Since it’s also easy to convert between java.sql.Date and java.util.Date, we will use the same trick to convert Date to LocalDate in the following two steps :
1) Convert java.util.Date to java.sql.Date
2) Convert java.sql.Date to java.time.LocalDate
You can even combine these two steps together as shown below :
LocalDate ld = new java.sql.Date( new java.util.Date().getTime()) .toLocalDate();
Simple and easy isn’t it?
By the way, if you have a really good understanding of Java’s old Date API then you can also use this shortcut to convert a java.util.Date to LocalDate in Java 8 :
Date d = new java.sql.Date(new java.util.Date().getTime()); LocalDate current = LocalDate.of(d.getYear() + 1900, getMonth() + 1, getDate());
Why those magic numbers? because in old Date API, years start with 1900 and month starts with 0.
Solution 2 – Using GregorianCalendar
You can also use Java’s old Calendar API to convert java.util.Date to LocalDate in Java 8 as shown below :
Date current = new Date(); GregorianCalendar gregorianCalendar = (GregorianCalendar) Calendar.getInstance(); gregorianCalendar.setTime(current); ZonedDateTime zonedDateTime = gregorianCalendar.toZonedDateTime(); zonedDateTime.toLocalDate();
Solution 3 – Using SimpleDateFormat
If you like to work with String and good at String to Date conversion, then you can follow this route. It involves multiple steps though :
1) format Date to String using SimpleDateFormat
2) Create LocalDate from formatted String
You can combine steps as shown below :
LocalDate localDate = LocalDate.parse( new SimpleDateFormat("yyyy-MM-dd").format(date) );
LocalDate.parse() method by default use ISO format, so no need for a DateTimeFormatter instance
Solution 4 : Using ZonedDateTime
In Java 8, Instance is an equivalent class for Date, hence a toInstant() method is added into java.util.Date in JDK 8. Since both Date and Instance doesn’t hold timezone information but LocalDate is the date in the local timezone, you need to get the System’s default timezone to convert an Instance to ZonedDateTime.
Once you do this, you can extract the Date only part as LocalDate by using the toLocalDate() method.
1) convert Date to java 8 Instance
2) Convert instance to ZonedDateTime object using System’s default timezone
3) Convert ZonedDateTime to LocalDate
Date input = new Date(); Instant instant = input.toInstant(); ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault()); LocalDate date = zdt.toLocalDate()
That’s all about 4 ways to convert java.util.Date to java.time.LocalDate in Java 8. You can use any of these approaches to do the job but the SQL date way seems quite easy to me.
What about you? Do let us know in the comments how do you address this common problem? Do you have any other clever and cleaner way to convert Date to LocalDate in Java?