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.
As I explained in the comments, there are four steps.
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
Using @Ed Cottrell's code as a basis, i put together this little method based on PHP's OO Date classes:
class DatePeriodHelper extends DatePeriod {
/**
* What is the overlap, in minutes, of two time periods?
* Based on a stackoverflow answer by Ed Cottrell - Thanks Ed :)
* http://stackoverflow.com/questions/33270716/return-the-amount-of-overlapping-minutes-between-to-php-dateperiods
*
* @param DatePeriod $period The DatePeriod to compare $this to.
* @return DateInterval A DateInterval object expressing the overlap or (if negative) the distance between the DateRanges
*/
public function overlapsWithPeriod(DatePeriod $period) {
// Figure out which is the later start time
$lastStart = $this->getStartDate() >= $period->getStartDate() ? $this->getStartDate() : $period->getStartDate();
// Figure out which is the earlier end time
$firstEnd = $this->getEndDate() <= $period->getEndDate() ? $this->getEndDate() : $period->getEndDate();
// return a DateInterval object that expresses the difference between our 2 dates
return $lastStart->diff($firstEnd);
}
}
Using Ed's test cases this yields:
$interval = new DateInterval('P1M');
$startDate1 = new DateTime('2015-09-11 09:15');
$endDate1 = new DateTime('2015-09-13 11:30');
$startDate2 = new DateTime('2015-09-13 10:45');
$endDate2 = new DateTime('2015-09-14 12:00');
$interval = new DateInterval('P1M');
$period1 = new DatePeriodHelper($startDate1, $interval, $endDate1);
$period2 = new DatePeriodHelper($startDate2, $interval, $endDate2);
$overlap = $period1->overlapsWithPeriod($period2);
echo $overlap->format('%r%h:%i:%s');
// echoes: 0:45:0
$startDate2 = new DateTime('2015-09-13 12:45');
$endDate2 = new DateTime('2015-09-14 12:00');
$period2 = new DatePeriodHelper($startDate2, $interval, $endDate2);
$overlap = $period1->overlapsWithPeriod($period2);
echo $overlap->format('%r%h:%i:%s');
// echoes -1:15:0
If you have $start1, $end1, $start2, $end2
as Unix-Timestamps (e. g. created with strtotime()
) you can simply type:
$overlap = max(min($end1, $end2) - max($start1, $start2), 0);
The result is in seconds. It is trivial to convert it to hours/days etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With