2

I am trying to calculate the number of days between 2 localDates

I am taking inspiration from this answer: https://stackoverflow.com/a/325964 to this question Determine Whether Two Date Ranges Overlap

The trouble is, this question uses dateTime which I believe is outdated, hence the reason for using localDate.

Does anyone know of a similar way to implement the algorithm in the above answer using localDate instead.

The minus method doesn't allow subtraction of another localDate.

I have tried using

ChoronoUnit.DAYS.between(LD1, LD2.plusDays(1)) //include the final day in the count

but there are occasions when this produces a negative number so the algorithm breaks because it chooses the smallest number as the number of days overlap

  • 5
    what's an "a -ve answer"? – OH GOD SPIDERS Apr 29 '20 at 12:06
  • 1
    The code example seems to be correct. What exactly do you mean by "algorithm falls over"? Your question is a little bit unclear :-) – Tobias Apr 29 '20 at 12:07
  • I have edited the question – 3rdRockSoftware Apr 29 '20 at 12:12
  • 4
    If `ChronoUnit.DAYS.between(ld1, ld2)` returns a negative number then `ld1.isAfter(ld2)` must return true. You can easily stop getting a negative number by always making the future date be the second argument or, even more simple, just use `days = Math.abs(days)`. – Slaw Apr 29 '20 at 12:22
  • It is stated in the [javadoc](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoUnit.html#between-java.time.temporal.Temporal-java.time.temporal.Temporal-) of method `between()` in `ChronoUnit` as follows: _The result will be negative if the end is before the start._ – Abra Apr 29 '20 at 12:34
  • @Abra I have read that but the thing that confuses me is that in the algorithm here the returned answer is always positive but I can't work out what I have done wrong with my algorithm – 3rdRockSoftware Apr 29 '20 at 12:40
  • [edit] your question and post a [mcve] demonstrating how you get a negative result. – Abra Apr 29 '20 at 12:44
  • 1
    @3rdRockSoftware In the linked answer, to paraphrase, it says: *"If start and end dates can be out of order, ... use `Min()` and `Max()`"*, as in `ChoronoUnit.DAYS.between(Math.min(LD1, LD2), Math.max(LD1, LD2)) + 1`. [Slaw's comment](https://stackoverflow.com/questions/61501388/how-do-i-subtract-a-localdate-from-another-localdate#comment108792949_61501388) is a better solution: `Math.abs(ChoronoUnit.DAYS.between(LD1, LD2)) + 1` – Andreas Apr 29 '20 at 13:14
  • @Andreas I had thought of using `abs`. I'll try that and see if I can produce some sensible results – 3rdRockSoftware Apr 29 '20 at 13:30

1 Answers1

5

Andreas already gave the answer in a comment: you need to take the absolute value of the day difference first, then add 1 to make the count inclusive of both start and end date.

public static long daysBetweenInclusive(LocalDate ld1, LocalDate ld2) {
    return Math.abs(ChronoUnit.DAYS.between(ld1, ld2)) + 1;
}

Let’s try it out:

    LocalDate ld1 = LocalDate.of(2020, Month.MAY, 4);
    System.out.println(daysBetweenInclusive(ld1, LocalDate.of(2020, Month.MAY, 2)));
    System.out.println(daysBetweenInclusive(ld1, ld1));
    System.out.println(daysBetweenInclusive(ld1, LocalDate.of(2020, Month.MAY, 7)));

Output:

3
1
4
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • What does "then add 1 to make the count inclusive of both start and end date" mean? If I calculate the difference between a day and itself with your algorithm, I would expect to get 0 as the result and not 1. Would it mean I get 1 in the meaning of "1st day"? – kitekat Oct 30 '22 at 16:02
  • @kitekat Yes, exactly. The question mentioned `include the final day in the count`. So while `ChronoUnit.DAYS.between()` takes the days from Tuesday to Thursday in the same week to be 2 (Tue and Wed), the OP wanted to include Thursday in the count to get 3. So I believe the OP also wanted the count from a day to itself to be 1, namely that day. If your requirement differs, just do not add 1. – Ole V.V. Oct 30 '22 at 18:19
  • @oleV.V. Yes that is correct. If the start day is Monday and the end day is Monday, then I needed count = 1 – 3rdRockSoftware Jul 31 '23 at 11:31