我刚刚问了这个问题并且已经标记为已经回答了,但是那个做了那个的人显然不明白这个问题。
这篇文章被标记为重复的问题,
但它们甚至不是一样的。
我在两个 DatePeriods 中寻找重叠时间的数量,而不是两个日期之间的差异。
“DatePeriod”由两个日期组成,我正在寻找两个DatePeriod之间的重叠量。
我发现还有另一篇文章回答了我的问题的一半,
并且效果很好,但它没有给出两个日期范围之间重叠的时间量。它只确定它们是否重叠。我需要知道它们重叠的分钟数。所以这是我原来的问题......
我认为有一种非常简单的方法可以做到这一点,但我已经看了一遍,无法找到解决方案。逻辑很简单:找到给定两个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分钟重叠的结果。如何实现这一目标?
我已经看到使用两个DateTimes完成了,但这不是我正在寻找的。 p>
datePeriod由两个DateTime组成,我正在寻找两个DatePeriod之间的区别。
答案 0 :(得分:7)
正如我在评论中所解释的那样,有四个步骤。
这是一个能够做你想做的事情的功能:
/**
* 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;
}
样本使用:
$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
答案 1 :(得分:2)
使用@Ed Cottrell的代码作为基础,我将基于PHP的OO Date类的这个小方法放在一起:
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);
}
}
使用Ed的测试用例,可以得到:
$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
答案 2 :(得分:0)
如果您将$start1, $end1, $start2, $end2
作为Unix时间戳记(例如,用strtotime()
创建),则只需键入:
$overlap = max(min($end1, $end2) - max($start1, $start2), 0);
结果以秒为单位。将其转换为小时/天等很简单。
答案 3 :(得分:0)
我为我的网站写了类似的东西。这是代码。它不像其他答案那么紧凑,但是希望它是相当可读的。
// Input should be UNIX timestamps
function get_minutes_of_overlap($date1_start_time, $date1_end_time, $date2_start_time, $date2_end_time) {
if ( $date1_end_time == $date2_end_time ) {
if ( $date1_start_time > $date2_start_time ) {
$date1_ends_later = TRUE;
} else {
$date1_ends_later = FALSE;
}
} elseif ( $date1_end_time > $date2_end_time ) {
$date1_ends_later = TRUE;
} else {
$date1_ends_later = FALSE;
}
if ( $date1_ends_later ) {
$minutes_of_overlap = ($date2_end_time - $date1_start_time) / 60;
} else {
$minutes_of_overlap = ($date1_end_time - $date2_start_time) / 60;
}
return $minutes_of_overlap;
}