I believe that this method does it.
public static boolean overlap(LocalTime start1, LocalTime end1, LocalTime start2, LocalTime end2) {
if (start1.isAfter(end1)) { // interval 1 crosses midnight
if (start2.isAfter(end2)) { // both intervals cross midnight, so they overlap at midnight
return true;
}
// Swap the intervals so interval 1 does not cross midnight
return overlap(start2, end2, start1, end1);
}
// Now we know that interval 1 cannot cross midnight
if (start2.isAfter(end2)) { // Interval 2 crosses midnight
return start2.isBefore(end1) || end2.isAfter(start1);
} else { // None of the intervals crosses midnight
return start2.isBefore(end1) && end2.isAfter(start1);
}
}
For demonstration I am using the following utility method.
public static void demo(LocalTime start1, LocalTime end1, LocalTime start2, LocalTime end2) {
System.out.format("Does %s - %s overlap with %s - %s? %b%n",
start1, end1, start2, end2, overlap(start1, end1, start2, end2));
}
Let’s feed some data to the utility method:
demo(LocalTime.of(15, 30), LocalTime.of(15, 29), LocalTime.of(17, 0), LocalTime.of(17, 30));
demo(LocalTime.of(9, 30), LocalTime.of(10, 0), LocalTime.of(10, 0), LocalTime.of(10, 30));
demo(LocalTime.of(9, 30), LocalTime.of(10, 0), LocalTime.of(23, 0), LocalTime.of(10, 0));
demo(LocalTime.of(9, 30), LocalTime.of(10, 30), LocalTime.of(10, 0), LocalTime.of(11, 0));
demo(LocalTime.of(6, 0), LocalTime.of(18, 30), LocalTime.of(18, 0), LocalTime.of(6, 30));
demo(LocalTime.of(6, 0), LocalTime.of(18, 0), LocalTime.of(12, 0), LocalTime.of(13, 0));
demo(LocalTime.of(10, 0), LocalTime.of(10, 30), LocalTime.of(10, 30), LocalTime.of(9, 30));
demo(LocalTime.of(23, 0), LocalTime.of(23, 30), LocalTime.of(23, 0), LocalTime.of(0, 0));
demo(LocalTime.of(23, 0), LocalTime.of(1, 0), LocalTime.of(23, 30), LocalTime.of(0, 30));
demo(LocalTime.of(22, 30), LocalTime.of(1, 30), LocalTime.of(22, 0), LocalTime.of(1, 0));
demo(LocalTime.of(22, 0), LocalTime.of(1, 0), LocalTime.of(22, 30), LocalTime.of(1, 30));
Output:
Does 15:30 - 15:29 overlap with 17:00 - 17:30? true
Does 09:30 - 10:00 overlap with 10:00 - 10:30? false
Does 09:30 - 10:00 overlap with 23:00 - 10:00? true
Does 09:30 - 10:30 overlap with 10:00 - 11:00? true
Does 06:00 - 18:30 overlap with 18:00 - 06:30? true
Does 06:00 - 18:00 overlap with 12:00 - 13:00? true
Does 10:00 - 10:30 overlap with 10:30 - 09:30? false
Does 23:00 - 23:30 overlap with 23:00 - 00:00? true
Does 23:00 - 01:00 overlap with 23:30 - 00:30? true
Does 22:30 - 01:30 overlap with 22:00 - 01:00? true
Does 22:00 - 01:00 overlap with 22:30 - 01:30? true
I am using LocalTime
from java.time, the modern Java date and time API, as the obvious class for representing a time of day. The Calendar
class that you used in your code is poorly designed and long outdated and not suited for a time of day only since it necessarily includes a date, which may disturb the comparisons, said without having checked whether this is the reason that your code didn’t give the expected result.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
- In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
- In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
- On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from
org.threeten.bp
with subpackages.
Links