One of the challenge you will face while using new Java 8 Date and time API, JSR-310 in existing Java application is the conversion between java.util.Date and java.time.LocalDate and other classes. Even though 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, eventhough java.util.Date says its a date its not, becuase its just a millisecond value since midnight at the start of 1970 GMT. It's equivalent to Instant class in new Java Date API and that's why you have a direct conversion method between Date and Instant in Java 8. Anyway, its 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, its really easy to convert a java.sql.Date to java.time.LocalDate in Java 8, because JDK 8 has added a convenience method toLocalDate() into this class. Since its also easy to convert between java.sql.Date and java.util.Date, we will use the same trick to convert Date to LocalDate in 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 this 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 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 starts 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 of a DateTimeFormatter instance
Solution 4 : Using ZonedDateTime
In Java 8, Instance is 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 date in local timezone, you need to get the System's default timezone to convert an Instance to ZonedDateTime.
Once you do this, you can extract date only part as LocalDate by using toLocalDate() method.
Steps :
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 approach to do the job but SQL date way seems quite easy to me.
No comments:
Post a Comment