Java 8 – Convert Date to LocalDate and LocalDateTime?

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

DateToJavaTime.java

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 LocalDateLocalDateTime and ZonedDateTime back to the classic java.util.Date.JavaTimeToDate.java

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.java.util.Date

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.

References

Share this post

Leave a Reply

Your email address will not be published. Required fields are marked *