datetime — поиск количества перекрывающихся минут в двух PHP DatePeriods

Я хочу найти количество пересекающихся минут за два DatePeriods.

Например,

  • У меня есть $ startDate1 и $ endDate1 в качестве первого диапазона дат.
  • У меня есть $ startDate2 и $ endDate2 в качестве второго диапазона дат.

(Для демонстрации, формат «Y-m-d H: i».)

  • Допустим, $ startDate1 = ‘2015-09-11 09:15’ и $ endDate1 = ‘2015-09-13 11:30’.

  • Предположим, $ startDate2 = ‘2015-09-13 10:45’ и $ endDate2 = ‘2015-09-14 12:00’.

Я ожидаю, что результат 45 минут перекрывается. Как этого достичь?

Этот вопрос был помечен как дубликат, но они не совпадают. Я ищу количество перекрытие раз в два DatePeriods не разница между двумя датами. «DatePeriod» состоит из двух дат, и я ищу сумму перекрытие (не разница) между двумя DatePeriods.

0

Решение

Вот класс DatePeriodsOverlap, которые представляют собой перекрытие двух периодов.
Это результат перекрытия DatePeriod или же исключение если нет пересечения.

Примечание. DatePeriod — это обходной объект, PT1M — длительность шага для итерации. PT1M означает один минутный интервал. подробности о DateInterval объект.

Пример использования и ответ на вопрос, как получить перекрытие в минутах:

<?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')}]");
}
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]