# Test 2 time ranges to see if they overlap

I am doing a project for school and had to create a function to check if 2 time ranges overlap. I searched the net a bit but failed to find a simple function to do that. I played around a bit with my code and I think I created a working one.

Note: it works for 24 hour times only & don't forget the 0 in front of AM time e.g "08:15"

If anyone has a better function to do this or finds some bugs in the code below - please post below.

$start_time1 = "10:15";$end_time1 = "12:20";

$start_time2 = "13:15";$end_time2 = "14:25";

function testRange($start_time1,$end_time1,$start_time2,$end_time2)
{
$timeCheck; if(($end_time1 < $start_time2)) {$timeCheck = true;
return $timeCheck; } else if(($start_time1 > $start_time2) && ($start_time1 > $end_time2)) {$timeCheck = true;
return $timeCheck; } else {$timeCheck = false;
return $timeCheck; } } if(testRange($start_time1,$end_time1,$start_time2,$end_time2)) { echo "Not In Range"; } else { echo "In Range"; }  • I'm not sure why you've created the $timeCheck variable. You can just write return true or return false instead of using that variable. That saves you a few lines of excess code. – s3rius Mar 31 '14 at 1:24
• Your question isn't as much asking to review the code, but more to show a better approach. Please understand that this may deter people from responding. If I reviewed your code, saying which bits you could improve, and how, I wouldn't give you a full and working example of an alternative, but I would've given you a code-review. Would you regard that as an answer to your question, too? If so, please edit and reformulate your question, if not, please consider posting this question elsewhere – Elias Van Ootegem Mar 31 '14 at 12:07

• As s3rius pointed out, you don't need the $timeCheck variable. You can just use return true; or return false;. • To parse a time use the DateTime class. You can find the supported time formats here. The constructor will throw an exception if it cannot parse the string. Consider if you want to handle the exception yourself or let the caller handle it. • What if the start time is after the end time? You can throw an exception, switch the start and end times, or not handle the error. • The meaning of the return value is not obvious based on your function name. How does it test the range? Change it to something like rangesNotOverlap or something similar so that it is apparent that true means they don't overlap. • Are time ranges open or close intervals? If one range ends at 10:00 and the other starts at 10:00, do they overlap? • Lets consider all cases: .  1 Case 01: |-----| |-----| 2 1 Case 02: |-----| |-----| 2 1 Case 03: |-----| |-----| 2 1 Case 04: |---------| |-----| 2 1 Case 05: |-----| |---------| 2 1 Case 06: |-----| |-----| 2 1 Case 07: |-----| |-----| 2 1 Case 08: |-----| |-----| 2 1 Case 09: |-----| |-----| 2 1 Case 10: | |-----| 2 1 Case 11: |-----| | 2 1 Case 12: | |-----| 2 1 Case 13: | |-----| 2 1 Case 14: |-----| | 2 1 Case 15: |-----| | 2 1 Case 16: | | 2 | | Operlap | Overlap Case | Example | Open Interval | Closed Interval --------|-------------------------|---------------|----------------- Case 01 | 09:00-11:00 09:00-11:00 | Yes | Yes Case 02 | 09:00-11:00 10:00-12:00 | Yes | Yes Case 03 | 10:00-12:00 09:00-11:00 | Yes | Yes Case 04 | 09:00-12:00 10:00-11:00 | Yes | Yes Case 05 | 10:00-11:00 09:00-12:00 | Yes | Yes Case 06 | 09:00-10:00 11:00-12:00 | No | No Case 07 | 11:00-12:00 09:00-10:00 | No | No Case 08 | 09:00-10:00 10:00-11:00 | No | Yes Case 09 | 10:00-11:00 09:00-10:00 | No | Yes Case 10 | 10:00-10:00 09:00-11:00 | Yes | Yes Case 11 | 09:00-11:00 10:00-10:00 | Yes | Yes Case 12 | 09:00-09:00 09:00-10:00 | No | Yes Case 13 | 10:00-10:00 09:00-10:00 | No | Yes Case 14 | 09:00-10:00 09:00-09:00 | No | Yes Case 15 | 09:00-10:00 10:00-10:00 | No | Yes Case 16 | 09:00-09:00 09:00-09:00 | No | Yes  Your function returns the correct result on the closed interval for all cases. • We can make your code simpler by noticing that we only have to check for two cases. The ranges don't overlap only if end1 < start2, (the same as your first if), or if end2 < start1 (which is included in your second if). The other check you do start1 > start2 is redundant, because it is always true if end2 < start1. Put it all together: function rangesNotOverlapClosed($start_time1,$end_time1,$start_time2,$end_time2) {$utc = new DateTimeZone('UTC');

$start1 = new DateTime($start_time1,$utc);$end1 = new DateTime($end_time1,$utc);
if($end1 <$start1)
throw new Exception('Range is negative.');

$start2 = new DateTime($start_time2,$utc);$end2 = new DateTime($end_time2,$utc);
if($end2 <$start2)
throw new Exception('Range is negative.');

return ($end1 <$start2) || ($end2 <$start1);
}

function rangesNotOverlapOpen($start_time1,$end_time1,$start_time2,$end_time2)
{
$utc = new DateTimeZone('UTC');$start1 = new DateTime($start_time1,$utc);
$end1 = new DateTime($end_time1,$utc); if($end1 < $start1) throw new Exception('Range is negative.');$start2 = new DateTime($start_time2,$utc);
$end2 = new DateTime($end_time2,$utc); if($end2 < $start2) throw new Exception('Range is negative.'); return ($end1 <= $start2) || ($end2 <= $start1); }  Or you can make it the easy way... ;-) function testRange($start_time1,$end_time1,$start_time2,$end_time2) { return ($start_time1 <= $end_time2 &&$start_time2 <= \$end_time1);
}


This solution assumpts, that the end time of any interval is never before the start time.