4

Have a pretty simple question here, but would need some logical expertise to solve this. So, I have an API that returns start and end time, for a given time slot in a 24 hour int format such that : start hour would be 4 and start minute would be 30 and end hour would be 5 and end minute would be 30. Please note that the slots returned are in 30 minute increments, such that a given hour would be from 1 to 24, and given minute would be either 30 or 0.

So now I have a set of ranges, such that each range represents a slot that's been taken and I need to identify whether any given time from the API overlaps or falls within one of these slots. (these slots would have hours from 1 to 24 but minutes could differ, could be anything from 0 to 59).

For this my logic so far is:

for (int i = 0; i < ranges.size(); i++) {

    int rangeStartHour = ranges.get(i).getStartTime().getHour();
    int rangeEndHour = ranges.get(i).getEndTime().getHour();
    int rangeStartMinute = ranges.get(i).getStartTime().getMinute();
    int rangeEndMinute = ranges.get(i).getStartTime().getMinute();

    if ((rangeStartHour == 0 && rangeEndHour == 24
            && rangeStartMinute == 0 && rangeEndMinute == 0)) {
        isAvailable = false;
    } else {
        isAvailable = true;
    }
}

I am missing an if in between where I need to identify whether the given time range falls in between or is equal to any of the taken slots to avoid overlap. Any ideas what would be the best way to go about this? I would love to have a very simple and compact solution that always works for this scenario. Open to all suggestions, worth a try! Happy to share more details if need be to clarify this further Thanks in advance!

alexrnov
  • 2,346
  • 3
  • 18
  • 34

1 Answers1

4

Say you have a time (hour, minute), a range start time (startHour, startMinute), and a range end time (endHour, endMinute).

To check if the time is within range, lower inclusive, upper exclusive, it is easier if you check whether the time is outside:

if (hour < startHour) {
    // outside
} else if (hour == startHour && minute < startMinute) {
    // outside
} else if (hour > endHour) {
    // outside
} else if (hour == endHour && minute >= endMinute) {
    // outside
} else {
    // inside
}
// combined
if (hour < startHour || hour > endHour ||
        (hour == startHour && minute < startMinute) ||
        (hour == endHour && minute >= endMinute)) {
    // outside
} else {
    // inside
}
// reversed
if (hour >= startHour && hour <= endHour &&
        (hour != startHour || minute >= startMinute) &&
        (hour != endHour || minute < endMinute)) {
    // inside
} else {
    // outside
}

However, with some prep work, it is far easier to combine the hour/minute values into a single minuteOfDay value:

// Prep work
int minuteOfDay = hour * 60 + minute;
int startMinuteOfDay = startHour * 60 + startMinute;
int endMinuteOfDay = endHour * 60 + endMinute;

// Test
if (minuteOfDay >= startMinuteOfDay && minuteOfDay < endMinuteOfDay) {
    // inside
} else {
    // outside
}

It would be even better if you used the ThreeTen Android Backport library:

// Store values as LocalTime instead of hour/minute pairs
LocalTime time = LocalTime.of​(hour, minute);
LocalTime startTime = LocalTime.of​(startHour, startMinute);
LocalTime endTime = LocalTime.of​(endHour, endMinute);

// Test
if (minuteOfDay.compareTo​(startMinuteOfDay) >= 0 && minuteOfDay.compareTo​(endMinuteOfDay) < 0) {
    // inside
} else {
    // outside
}
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • That looks great! thanks for your response. Just a small twist in the question, how do I determine if a slot, with a start hour and minute and end hour and minute, say 5:30 to 6:30 is within,overlapping or outside a set of slots, say the slots taken are (1:00 to 3:00, 4:23 to 5:38, 8:44 to 14:50) –  Apr 12 '20 at 01:01
  • @AngelaHeely See [What's the most efficient way to test two integer ranges for overlap?](https://stackoverflow.com/q/3269434/5221149) – Andreas Apr 12 '20 at 01:10
  • I am not exactly sure if that answers my question, basically what I am looking for is for any given slot (consisting of start hour and minute and end hour and end minute ) given as int's,I want to check whether this slot falls within a given set of slots or overlaps with some. Is there a way you can modify the logic you mentioned in solution #2 to achieve that? That seems to be the best way I can handle it in my code and more feasible for my usecase. thank you :) –  Apr 12 '20 at 01:25
  • This answer shows how to compare two times (hour/minute pairs). The link shows how to check if two ranges overlap, which uses comparison and you just learned how to do that. To "check whether this slot falls within a given **set** of slots or overlaps with some", you **iterate the set** and check each for overlap. Now all *you* need to do, is combine the three: "compare", "overlap check", and "falls within set check". – Andreas Apr 12 '20 at 01:29
  • tthank you for your answer! i have it working now :) –  Apr 12 '20 at 13:51