Java 8 – Convert Date to LocalDate and LocalDateTime
Here is the code to convert java.util.Date
to java.time.LocalDate
.
Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
// different way of create instant object
LocalDate localDate = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
Convert java.util.Date
to java.time.LocalDateTime
.
Date date = new Date();
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
Convert java.util.Date
to java.time.ZonedDateTime
.
Date date = new Date();
ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());
For java.sql.Date
, we can convert it directly.
java.sql.Date sqlDate = java.sql.Date.valueOf("2020-02-05");
LocalDate localDate2 = sqlDate.toLocalDate();
1. Date -> java.time.LocalDate
The java.util.Date
has no concept of time zone, and only represents the number of seconds passed since the Unix epoch time – 1970-01-01T00:00:00Z (midnight at the start of January 1, 1970 GMT/UTC)
Note
The new Java 8 java.time.Instant
is the equivalent class to the classic java.util.Date
The idea of the date conversion is to convert to an instant with a time zone.
Date -> Instant + System default time zone = LocalDate
Date -> Instant + System default time zone = LocalDateTime
Date -> Instant + System default time zone = ZonedDateTime
package com.mkyong.java8;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
public class DateToJavaTime {
public static void main(String[] args) {
//Asia/Kuala_Lumpur +8
ZoneId defaultZoneId = ZoneId.systemDefault();
System.out.println("System Default TimeZone : " + defaultZoneId);
//toString() append +8 automatically.
Date date = new Date();
System.out.println("date : " + date);
//1. Convert Date -> Instant
Instant instant = date.toInstant();
System.out.println("instant : " + instant); //Zone : UTC+0
//2. Instant + system default time zone + toLocalDate() = LocalDate
LocalDate localDate = instant.atZone(defaultZoneId).toLocalDate();
System.out.println("localDate : " + localDate);
//3. Instant + system default time zone + toLocalDateTime() = LocalDateTime
LocalDateTime localDateTime = instant.atZone(defaultZoneId).toLocalDateTime();
System.out.println("localDateTime : " + localDateTime);
//4. Instant + system default time zone = ZonedDateTime
ZonedDateTime zonedDateTime = instant.atZone(defaultZoneId);
System.out.println("zonedDateTime : " + zonedDateTime);
}
}
Output
System Default TimeZone : Asia/Kuala_Lumpur
date : Fri Aug 19 21:46:31 MYT 2016
instant : 2016-08-19T13:46:31.981Z
localDate : 2016-08-19
localDateTime : 2016-08-19T21:46:31.981
zonedDateTime : 2016-08-19T21:46:31.981+08:00[Asia/Kuala_Lumpur]
2. java.time.LocalDate -> Date
This example shows you how to convert LocalDate
, LocalDateTime
and ZonedDateTime
back to the classic java.util.Date
.
package com.mkyong.java8;
import java.time.*;
import java.util.Date;
public class JavaTimeToDate {
public static void main(String[] args) {
//Asia/Kuala_Lumpur +8
ZoneId defaultZoneId = ZoneId.systemDefault();
System.out.println("System Default TimeZone : " + defaultZoneId);
LocalDate localDate = LocalDate.of(2016, 8, 19);
Date date = Date.from(localDate.atStartOfDay(defaultZoneId).toInstant());
System.out.println("\n1. LocalDate -> Date");
System.out.println("localDate : " + localDate);
System.out.println("date : " + date);
LocalDateTime localDateTime = LocalDateTime.of(2016,8,19,21,46,31);
Date date2 = Date.from(localDateTime.atZone(defaultZoneId).toInstant());
System.out.println("\n2. LocalDateTime -> Date");
System.out.println("localDateTime : " + localDateTime);
System.out.println("date2 : " + date2);
ZonedDateTime zonedDateTime = localDateTime.atZone(defaultZoneId);
Date date3 = Date.from(zonedDateTime.toInstant());
System.out.println("\n3. ZonedDateTime -> Date");
System.out.println("zonedDateTime : " + zonedDateTime);
System.out.println("date3 : " + date3);
}
}
Output
System Default TimeZone : Asia/Kuala_Lumpur
1. LocalDate -> Date
localDate : 2016-08-19
date : Fri Aug 19 00:00:00 MYT 2016
2. LocalDateTime -> Date
localDateTime : 2016-08-19T21:46:31
date2 : Fri Aug 19 21:46:31 MYT 2016
3. ZonedDateTime -> Date
zonedDateTime : 2016-08-19T21:46:31+08:00[Asia/Kuala_Lumpur]
date3 : Fri Aug 19 21:46:31 MYT 2016
FAQs
Question : If Date has no concept of time zone, why the time zone will be displayed if we print out the Date object? For example :
//Fri Aug 19 11:52:06 MYT 2016
System.out.println(new Date()); //MYT = my system default time zone
Answer : Check the java.uti.Date.toString()
source code, if you print out the Date object, the system default time zone will be appended and display together.
public String toString() {
//...omitted...
TimeZone zi = date.getZone();
if (zi != null) {
sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
} else {
sb.append("GMT");
}
sb.append(' ').append(date.getYear()); // yyyy
return sb.toString();
}
Note
This behavior is a design flaw since JDK1.1; it makes a lot of confusion. Again, the java.util.Date
doesn’t store any time zone info, but if you print it out, the system default time zone will be displayed together.
Hi MKyong, nice article, but if you implement this in a system which might pass you a java.sql.Date and you try Date.toInstant(), then even java.util.Date will blow up with an UnsupportedOperationException.
I use: new java.sql.Date(src.getTime()).toLocalDate();
Thanks, article is updated with
java.sql.Date
conversion.