Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test if a range intersects another range of numbers

I have 2 range of numbers:

  • $startTime to $endTime
  • $offerStartTime to $offerEndTime

Each of the above variables are integers.

I want to see if the range offerStartTime to offerEndTime falls in the range startTime and endTime.

For example, if the startTime and endTime range was: 10 to 20, then the following example ranges would return true:

  • offerStartTime: 5, offerEndTime: 11
  • offerStartTime: 5, offerEndTime: 100
  • offerStartTime: 10, offerEndTime: 15
  • offerStartTime: 10, offerEndTime: 100
  • offerStartTime: 12, offerEndTime: 15
  • offerStartTime: 19, offerEndTime: 100

The following would return false:

  • offerStartTime: 1, offerEndTime: 3
  • offerStartTime: 90, offerEndTime: 100
  • offerStartTime: 1, offerEndTime: 10
  • offerStartTime: 20, offerEndTime: 100

How can I do this? Would ideally like answers in PHP, but pseudo code would be fine.

like image 632
Yahya Uddin Avatar asked Apr 25 '17 16:04

Yahya Uddin


People also ask

How do you know if two ranges overlap?

1) Sort all intervals in increasing order of start time. This step takes O(nLogn) time. 2) In the sorted array, if start time of an interval is less than end of previous interval, then there is an overlap.

What is range overlap?

The level to which pay ranges in adjacent grades in a category overlap. Pay Range.

How do you calculate overlapping time intervals in Excel?

data RESULTS; set EVENTS; OVERLAP = min(A2,B2) - max(A1,B1) + 1; if OVERLAP<0 then OVERLAP = 0; run; We can also zero out the negative values of variable x using max(0, x) expression that results in the following formula for the date ranges overlap calculation: Overlap = max(0, min(A2, B2) - max(A1, B1) + 1).


3 Answers

If you are just checking whether any part of the offer overlaps any part of the range, it's simple.

if ($offerStartTime < $endTime && $offerEndTime > $startTime)  {
    echo 'The ranges overlap';
}

Here's a picture representing all the possibilities of overlap and non-overlap to visualize why this works.

enter image description here

Based on your inputs and expected false outputs, I used < and >. If you wanted to also include ranges that intersected at a point, you would need to use <= and >= instead.

like image 187
Don't Panic Avatar answered Oct 24 '22 06:10

Don't Panic


//$startTime to $endTime
//$offerStartTime to $offerEndTime
//you can compare php times by using normal comparators so this is just a logic problem. here's the solution.


//ok let's start by making sure that neither offered time is within the range because if it is we KNOW it's already good so

if(($offerStartTime < $endTime && offerStartTime > $startTime) || ($offerEndTime < $endTime && offerEndTime > $startTime)){
      return true;
 }
 //so it's not easily already within the range so we have to test if the lower one is under the starting one but the other is above. ie.
elseif(($offerStartTime < $startTime) && ($offerEndTime > $startTime)){
     return true; 
}
//so the only other acceptable possibility is that the offered start time is lower than the endtime and the offered end time is higher ie
elseif(($offerStartTime < $endTime) && ($offerEndTime > $endTime)){
      return true;
}
//so we've exhausted all other valid possibilities it must be false
else{
      return false;
}
like image 42
Zachary Heaton Avatar answered Oct 24 '22 05:10

Zachary Heaton


You can use range and array_intersect, i.e.:

function time_intersect($startTime, $endTime, $offerStartTime, $offerEndTime)
{
    $start_to_end = range($startTime, $endTime, 1);
    $offer_start_end = range($offerStartTime, $offerEndTime, 1);
    if (!empty(array_intersect($start_to_end, $offer_start_end)))
    {
      # time overlaps
      return true;
    }
}

Explanation:

With range we create 2 arrays containing numbers based on the 4 variables (start, end), then we use array_intersect to check if the 2 arrays have numbers in common, if the output is not empty, we know the numbers (time) overlap.

like image 21
Pedro Lobito Avatar answered Oct 24 '22 04:10

Pedro Lobito