Luke James Luke James - 4 months ago 21
PHP Question

Return the amount of overlapping minutes between to PHP DatePeriods

I just asked this question and it was marked as already answered but whoever did that obviously did not understand the question.

This post was marked as a duplicate question to this,


How to get time difference in minutes in PHP ,


but they are not even remotely the same.

I'm looking for the amount of overlapping time in two DatePeriods not the difference between two dates.

A "DatePeriod" consists of two dates and I'm looking for the amount of overlap between two DatePeriods.

There is another post I found that answers half of my question here,


Determine Whether Two Date Ranges Overlap


and it works great but it does not give me the amount of time overlap between the two date ranges. It only determines if they overlap or not. I need to know the amount of minutes that they overlap. So Here is my original question...

I assumed there would be a very easy way to do this but I have looked all over and can not find a solution. The logic is simple: find the amount of overlapping minutes given two DatePeriods.

For example,

-I have
$startDate1
and
$endDate1
as the first date range.

-I have
$startDate2
and
$endDate2
as the second date range.

(For demonstration sake, the format is
'Y-m-d H:i'
. )


  • Suppose
    $startDate1 = '2015-09-11 09:15'
    and
    $endDate1 = '2015-09-13 11:30'
    .

  • Suppose
    $startDate2 = '2015-09-13 10:45'
    and
    $endDate2 = '2015-09-14 12:00'
    .



I would expect a result of 45 minutes overlap. How can this be achieved?

I have seen this done using two DateTimes but that is not what I'm looking for.

A datePeriod consists of two DateTimes and I'm looking for the difference between two DatePeriods.

Answer

As I explained in the comments, there are four steps.

  1. Calculate the later start date; overlaps are impossible before that.
  2. Calculate the earlier end date; overlaps are impossible after that.
  3. Subtract the later start date from the earlier end date.
  4. Check the result. If it's zero or greater, there's your answer. If it's negative, then your answer is zero; that implies that the second period didn't start until the first one finished.

Here's a function to do what you want:

/**
 * What is the overlap, in minutes, of two time periods?
 *
 * @param $startDate1   string
 * @param $endDate1     string
 * @param $startDate2   string
 * @param $endDate2     string
 * @returns int     Overlap in minutes
 */
function overlapInMinutes($startDate1, $endDate1, $startDate2, $endDate2)
{
    // Figure out which is the later start time
    $lastStart = $startDate1 >= $startDate2 ? $startDate1 : $startDate2;
    // Convert that to an integer
    $lastStart = strtotime($lastStart);

    // Figure out which is the earlier end time
    $firstEnd = $endDate1 <= $endDate2 ? $endDate1 : $endDate2;
    // Convert that to an integer
    $firstEnd = strtotime($firstEnd);

    // Subtract the two, divide by 60 to convert seconds to minutes, and round down
    $overlap = floor( ($firstEnd - $lastStart) / 60 );

    // If the answer is greater than 0 use it.
    // If not, there is no overlap.
    return $overlap > 0 ? $overlap : 0;
}

Sample uses:

$startDate1 = '2015-09-11 09:15';
$endDate1 = '2015-09-13 11:30';
$startDate2 = '2015-09-13 10:45';
$endDate2 = '2015-09-14 12:00';

echo overlapInMinutes($startDate1, $endDate1, $startDate2, $endDate2) . "\n";
// echoes 45

$startDate1 = '2015-09-11 09:15';
$endDate1 = '2015-09-13 11:30';
$startDate2 = '2015-09-13 12:45';
$endDate2 = '2015-09-14 12:00';

echo overlapInMinutes($startDate1, $endDate1, $startDate2, $endDate2) . "\n";
// echoes 0