0

I have been stuck on checking overlapping times. My calendar implementation allows for cyclic or wrap-around time (so having start time after the End time is possible)

For example: startTime = 3:30PM, EndTime = 3:29PM, TimeDuration = 23 hours and 59 minutes

Some of the answers I found online work when the End Time comes strictly after the start time. How can I fix this? I am using this StackOverflow solution but it's not fully working: Determine Whether Two Date Ranges Overlap

In this picture, The two time ranges overlap, but my implantation doesn’t correctly identify it: overlapping times

Here is the debugging output, it should return True but it's not: debug output

leo
  • 113
  • 3
  • 11
  • If you only need the time then millis from midnight should solve it, what API are you using for working with dates? – cutiko Apr 08 '21 at 15:01
  • Split your durations that cross the midnight boundary into two durations and check each of them. – Tenfour04 Apr 08 '21 at 15:01
  • @cutiko I was working with java.sql.date and had issues with it. I am using GregorianCalendar currently – leo Apr 08 '21 at 16:35
  • Similar: [How to check if time period is overlapping another time period irrespective of AM/PM](https://stackoverflow.com/questions/60131155/how-to-check-if-time-period-is-overlapping-another-time-period-irrespective-of-a). You may be able to adapt the latter half of my answer there. – Ole V.V. Apr 08 '21 at 16:53
  • 1
    Could you paste, at best all the information from your debugger, if that isn’t possible than at least your code *as text* into your question, please? – Ole V.V. Apr 08 '21 at 17:52
  • 1
    This is answerable as-is, but would benefit greatly from the code not being an image. – Ryan M Apr 08 '21 at 23:23

2 Answers2

0

If you consider time alone, your set of intervals can fall within a 48 hours domain: The extreme would be 11:59:59PM to 11:59:58PM interval that would end at 23:59:58 the next day.

Essentially, that would map to 00:00 hrs to 48:00 hrs. The first thing I would do is convert AM/PM to military time. Add a check if the difference between end and start is negative, if so, I would add 24 hours to end time.

You are now left with finding the overlap.

Tarik
  • 10,810
  • 2
  • 26
  • 40
0

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

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Thank you so much Ole. Also thank you for suggesting LocalTime, it works really well. This Time issue was killing me for a long time, I didn't ask on StackOverflow all this time because people downvote me a lot of times for asking questions, so I was really surprised to get lots of extensive answers. Thanks again!! – leo Apr 09 '21 at 03:32