Search code examples
javaif-statementtimebooleanlocaldate

Getting wrong output when checking if 2 date periods overlap


I am trying to make a function which checks if 2 date periods overlap. For example:

1 July 2019 - 5th July 2019 and 2nd July 2019 - 4th July 2019 would return true as the 2 date periods overlap

1 July 2019 - 5th July 2019 and 13th July 2019 - 24th July 2019 would return false as the 2 date periods don't overlap

I get the wrong answer when I compare these 2 dates 24 March 2019 - 27 March 2019 and 27 March 2019 - 29 March 2019. I get the answer false. Though the answer should be true because I count all days inclusive.

How can I fix this?

import java.time.LocalDate;
import java.time.Month;

public class TestClass {

    public static void main(String[] args) {
        LocalDate start1 = LocalDate.of(2019, Month.MARCH, 24);
        LocalDate end1 = LocalDate.of(2019, Month.MARCH, 27);
        LocalDate start2 = LocalDate.of(2019, Month.MARCH, 27);
        LocalDate end2 = LocalDate.of(2019, Month.MARCH, 29);

        boolean ans = dateOverlaps(start1, end1, start2, end2);
        System.out.println(ans);

    }

    public static boolean dateOverlaps(LocalDate start1, LocalDate end1, LocalDate start2, LocalDate end2) {
        return start2.isBefore(end1) && end2.isAfter(start1); 
    }
}

Solution

  • You really need before or on for the first part of the condition and similarly on or after for the second part (since your start and end dates are inclusive). There isn't one method for that, but a couple of ways to put it into code. For example:

        return (start2.isBefore(end1) || start2.isEqual(end1)) 
                && (end2.isEqual(start1) || end2.isAfter(start1)); 
    

    With this change your program prints:

    true

    Personally I prefer the shorter but also a bit trickier:

        return ! (start2.isAfter(end1) || end2.isBefore(start1)); 
    

    The result is the same. I have turned the logic upside down: The periods overlap if neither period 2 comes after period 1 nor the other way around.