3

So I'm trying to get a specific number with my code. Right now I have:

Instant Today = 2018-07-17T13:45:00Z
Instant Expiration1 = 2018-07-18T11:00:00Z
long daysTilExp = Today.until(Expiration, Chronounit.DAYS)

The problem is that because this isn't exactly 24 hours apart it ends up returning daysTilExp = 0 but I want daysTilExp = 1 I'm trying to get that actual days apart the two Instants are so then even If I change the value of Expiration like so:

Instant Expiration1 = 2018-07-18T06:00:00Z

and now daysTilExp = 2. I looked at some other answers on StackOverflow but it doesn't look like people are using Instant and they aren't wanting the difference the same way

TOTOROCATBUS
  • 172
  • 1
  • 2
  • 17
  • 1
    Are you sure that your second example results in `2`? – Dominik Sandjaja Jul 17 '18 at 18:54
  • @DominikSandjaja No I want the result to be `2` It would return a `1` as the real answer – TOTOROCATBUS Jul 17 '18 at 19:04
  • Please, post the code which compiles. You cant parse `2018-07-17T13:45:00Z` directly to `Instant`, it's not even the String, how is it supposed to work? Use the camelCase with the lower-cased first letter as a variable name. Isn't `Chronounit` supposed to be `ChronoUnit`? – Nikolas Charalambidis Jul 17 '18 at 19:22
  • Please explain how the interval from 1:45 PM on Tuesday to 6 AM the following day constitutes two days. It’s not even one full day. Did you mean to write `2018-07-19`? – VGR Jul 17 '18 at 21:00
  • You need to choose a time zone for that. It is never the same calendar date everywhere on Earth. – Ole V.V. Jul 18 '18 at 10:37

4 Answers4

4

LocalDate will remove the time part and LocalDate objects comparison will yield the expected result:

LocalDateTime  today = LocalDateTime.parse("2018-07-17T13:45:00");
LocalDateTime  expiration = LocalDateTime.parse("2018-07-18T11:00:00");
LocalDate todayDate = today.toLocalDate();
LocalDate expirationDate = expiration.toLocalDate();
long days = todayDate.until(expirationDate, ChronoUnit.DAYS);
System.out.println(days);
Pavel Molchanov
  • 2,299
  • 1
  • 19
  • 24
4

The best way is using DAYS.between() method from java.time.temporal.ChronoUnit. But this way works only for Java 8+ versions. Example:

Date start = new Date();
Date end = new Date(start.getTime() + 10_000);
long daysCount = DAYS.between(start.toInstant(), end.toInstant());
gnupinguin
  • 81
  • 4
  • 1
    Very good suggestion for Java 8+ Also for difference in SECONDS (or other units) between Instants java.time.Instant ! Example: ChronoUnit.SECONDS.between( t0 ,Instant.now()); Minor thing: in your code should read "end.toInstant()" (not toInstance() ) – Diego1974 Oct 06 '21 at 13:55
2
    ZoneId zone = ZoneId.of("America/Chicago");

    Instant today = Instant.parse("2018-07-18T17:15:00Z");
    Instant expiration1 = Instant.parse("2018-07-19T05:00:00Z");

    ZonedDateTime todayInZone = today.atZone(zone);
    ZonedDateTime expirationInZone = expiration1.atZone(zone);
    long daysTilExp = todayInZone.toLocalDate().until(expirationInZone, ChronoUnit.DAYS);
    System.out.format("From %s to %s is %d day/s.%n", 
                      todayInZone, expirationInZone, daysTilExp);

From 2018-07-18T12:15-05:00[America/Chicago] to 2018-07-19T00:00-05:00[America/Chicago] is 1 day/s.

So from July 18 to 19 is 1 day. If you wanted both inclusive in the count, just add 1.

Since it is never the same date everywhere on Earth, counting days is different in different time zones. Try changing the time zone and keeping the same instants:

    ZoneId zone = ZoneId.of("Asia/Tokyo");

This changes the output to

From 2018-07-19T02:15+09:00[Asia/Tokyo] to 2018-07-19T14:00+09:00[Asia/Tokyo] is 0 day/s.

As you can read from the output, this is because it is now already July 19 in Japan, so it os counting from July 19 to 19 and getting 0.

So you need to choose in which time zone you want your count.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

Try this:

long daysTilExp = (long) Math.ceil(now.until(goodTo, ChronoUnit.HOURS) / 24.0);
RodolfoTVA
  • 77
  • 9