Here is class DatePeriodsOverlap, which represent overlap of two periods.
It's result is overlapping DatePeriod or Exception if there is no intersection.
Note: DatePeriod is traversable object, PT1M is duration of step to iterate. PT1M means one minute interval. Details about DateInterval object.
Example of usage and answer to the question, how to get overlapping in minutes:
<?php
$d1 = new DatePeriod(
new DateTime('2015-09-11 09:15:00'),
new DateInterval('PT1M'),
new DateTime('2015-09-13 11:30:00')
);
$d2 = new DatePeriod(
new DateTime('2015-09-13 10:45:00'),
new DateInterval('PT1M'),
new DateTime('2015-09-14 12:00:00')
);
$overlapPeriod = (new DatePeriodsOverlap(
$d1,
$d2,
new DateInterval('PT1M')) // PT1M - 1 minute interval,
// P1D - 1 day interval
)->overlap();
$minutes = iterator_count($overlapPeriod); // 45 minutes
// interval in minutes without iterating
$overlapPeriod->getEndDate()
->diff($overlapPeriod->getStartDate())
->i; // is interval in minutes (H:i:s)
/**
* Overlap of two periods
*/
class DatePeriodsOverlap {
private $d1;
private $d2;
private $di; // DateInterval, default is 1 day
/**
* @param DatePeriod $d1 first period
* @param DatePeriod $d2 second period
* @param DateInterval $di interval measurement
*/
public function __construct(
DatePeriod $d1,
DatePeriod $d2,
DateInterval $di = null)
{
$this->d1 = $d1;
$this->d2 = $d2;
$this->di = $di ?? new DateInterval('P1D');
}
/**
* Returns new overlapping period
*
* @throws Exception if not overlapped
* @return DatePeriod
*/
public function overlap() : DatePeriod
{
$startOne = $this->d1->getStartDate();
$endOne = $this->d1->getEndDate();
$startTwo = $this->d2->getStartDate();
$endTwo = $this->d2->getEndDate();
//If the dates overlap
if ($startOne < $endTwo && $endOne > $startTwo)
{
return new DatePeriod(
max($startTwo,$startOne),
$this->di,
min($endOne,$endTwo)
);
}
throw new Exception(
"No overlap " .
"[{$this->d1->getStartDate()->format('Y-m-d H:i:s')}-{$this->d1->getEndDate()->format('Y-m-d H:i:s')}] and " .
"[{$this->d2->getStartDate()->format('Y-m-d H:i:s')}-{$this->d2->getEndDate()->format('Y-m-d H:i:s')}]"
);
}
}