20

I have two instances of the Instant class from java.time such as this:

Instant instant1 = Instant.now();
Instant instant2 = Instant.now().plus(5, ChronoUnit.HOURS);

Now I would like to check if the two instances of Instant are actually on the same date (day, month and year match). Easy I thought, let's just use the shiny new LocalDate and the universal from static method:

LocalDate localdate1 = LocalDate.from(instant1);
LocalDate localdate2 = LocalDate.from(instant2);

if (localdate1.equals(localdate2)) {
   // All the awesome
}

Except that universal from method is not so universal and Java complains at runtime with an exception:

java.time.DateTimeException: Unable to obtain LocalDate from TemporalAccessor: 2014-11-04T18:18:12Z of type java.time.Instant

Which leaves me back at square 1.

What is the recommended/fastest way check if two instances of Instant actually have the same date (have the same day, month, and year)?

Robin
  • 8,197
  • 11
  • 45
  • 74
  • In other words, you need something that works with Java 7? What about Java 6 or Java 5? How far back do you need this to work? – markspace Jan 15 '15 at 16:13
  • This only has to work for Java 8 in my case, should have probably specified that – Robin Jan 15 '15 at 16:14
  • How about using `instant1.truncatedTo(ChronoUnit.DAYS)`? Do the same on instant2 and compare the truncated instances? – dcsohl Jan 15 '15 at 16:17
  • Just guessing here, but as you're trying to get a **Local**Date and that Instant doesn't seem to have any location or timezone information... – blalasaadri Jan 15 '15 at 16:17
  • 5
    [This answer](http://stackoverflow.com/a/21242111/451518) explains how to convert `Instant` to `LocalDate`. `LocalDate.from` doesn't work because `Instant` doesn't include timezone. – default locale Jan 15 '15 at 16:18
  • 1
    @defaultlocale: Great, this helps! Now the question remains is this the fastest way (but I'll take it for now) :) – Robin Jan 15 '15 at 16:22

1 Answers1

21

The Instant class does not work with human units of time, such as years, months, or days. If you want to perform calculations in those units, you can convert an Instant to another class, such as LocalDateTime or ZonedDateTime, by binding the Instant with a time zone. You can then access the value in the desired units.

http://docs.oracle.com/javase/tutorial/datetime/iso/instant.html

Therefore I suggest the following code:

LocalDate ld1 = LocalDateTime.ofInstant(instant1, ZoneId.systemDefault()).toLocalDate();
LocalDate ld2 = LocalDateTime.ofInstant(instant2, ZoneId.systemDefault()).toLocalDate();

if (ld1.isEqual(ld2)) {
    System.out.println("blubb");
}

Alternatively you could use

instant.atOffset(ZoneOffset.UTC).toLocalDate();
flo
  • 9,713
  • 6
  • 25
  • 41