How to convert from Instant to LocalDate

Java 8Localdatejava.time.instantJava Time

Java 8 Problem Overview


I have an Instant coming from a source that should, according to the specs, be a LocalDate, but don't see any methods in the LocalDate class to convert the Instant to a LocalDate.

What is the best way to do this?

Java 8 Solutions


Solution 1 - Java 8

Java 9+

LocalDate.ofInstant(...) arrived in Java 9.

Instant instant = Instant.parse("2020-01-23T00:00:00Z");
ZoneId zone = ZoneId.of("America/Edmonton");
LocalDate date = LocalDate.ofInstant(instant, zone);

See code run live at IdeOne.com.

Notice the date is 22nd rather than 23rd as that time zone uses an offset several hours before UTC.

> 2020-01-22

Java 8

If you are using Java 8, then you could use ZonedDateTime's toLocalDate() method:

yourInstant.atZone(yourZoneId).toLocalDate()

Solution 2 - Java 8

Other answers provided the mechanics for the transformation, but I wanted to add some background on the meaning of such transformation which hopefully helps explain why it works the way it works.


LocalDate and Instant seem similar – they both hold date(/time) information without the time zone information. However, they have quite a different meaning.

Instant represents a point in time unambiguously. The representation does not explicitly contain any time zone, but implicitly it refers to the UTC time line.

LocalDateTime (and LocalDate) is ambiguous, because it represents a point in the local timeline, which implicitly refers to the local time zone.

So, in order to correctly transform an Instant into a LocalDateTime (conceptually – some of these steps are bundled together into a single operation in the implementation) you need to:

  1. convert the Instant into a ZonedDateTime by applying the UTC time zone info
  2. change the time zone from UTC to the local time zone (which implies applying the relevant time zone offset) which gives you another ZonedDateTime (with different time zone)
  3. convert the ZonedDateTime into a LocalDateTime which makes the time zone implicit (local) by removing the time zone info.

Finally, you can drop the time-part of LocalDateTime and end up with the LocalDate.

Solution 3 - Java 8

If using java 8 you can do the following

Instant instantOfNow = Instant.now();
LocalDate localDate 
    = LocalDateTime.ofInstant(instantOfNow, ZoneOffset.UTC).toLocalDate();

Solution 4 - Java 8

You need to ask yourself at what zone offset you want to transform it to most probably and when you know the answer to that:

LocalDate.ofInstant(yourInstant, yourZoneOffSet)

EDIT

just realized that this is only possible since java-9, for a pre-java9 see the other answer

Solution 5 - Java 8

Complete running example, Java 8 compatible:

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

class Scratch {

  public static void main(String[] args) {
    Instant now = Instant.now();
    LocalDateTime ldt = now.atZone(ZoneId.systemDefault()).toLocalDateTime();
    System.out.println(ldt);
  }
}

Solution 6 - Java 8

 Instant instant = Instant.now();   
 LocalDate localDate = LocalDate.ofInstant(instant, ZoneOffset.UTC);

the above code worked for me.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJL GradleyView Question on Stackoverflow
Solution 1 - Java 8Rob CView Answer on Stackoverflow
Solution 2 - Java 8Krzysiek PrzygudzkiView Answer on Stackoverflow
Solution 3 - Java 8Robbo_UKView Answer on Stackoverflow
Solution 4 - Java 8EugeneView Answer on Stackoverflow
Solution 5 - Java 8t0r0XView Answer on Stackoverflow
Solution 6 - Java 8Awais YousafView Answer on Stackoverflow