2015-10-21 20 views
3

我刚问过这个问题,它被标记为已经回答,但是谁做了这些显然不明白这个问题。返回两个PHP DatePeriods之间的重叠分钟数

这个帖子被标记为重复的问题,这一点,

How to get time difference in minutes in PHP

,但他们都没有,甚至远程一样。

我两个DatePeriods不是两个日期之间的差值在寻找的重叠时间量。

“DatePeriod”由两个日期组成,我正在寻找两个DatePeriod之间的重叠量。

还有另一篇文章,我发现答案的一半我在这里的问题,

Determine Whether Two Date Ranges Overlap

和它的作品很好,但它并没有给我时间重叠量的两个日期之间范围。它只确定它们是否重叠。我需要知道它们重叠的分钟数量。所以这是我的原始问题...

我认为会有一个非常简单的方法来做到这一点,但我已经找遍了,找不到解决方案。逻辑很简单:找到给定两个DatePeriods的重叠分钟的数量。

例如,

-I有$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分钟重叠的结果。这怎么能实现?

我已经看到这样做使用两个日期时间但这不是我正在寻找。

datePeriod由两个DateTime组成,我正在寻找两个DatePeriod之间的区别。

+0

重叠需要在两个方向上计算。如果$ startDate1和$ endDate1晚于或在$ startDate2和$ endDate2之间。 –

+0

不,它没有。就像我说的,有四个步骤。 (1)计算较晚的开始日期;在此之前,重叠是不可能的。 (2)计算较早的结束日期;之后重叠是不可能的。 (3)从较早的结束日期减去较晚的开始日期。 (4)检查结果。如果它是零或更大,那就有你的答案。如果它是负面的,那么你的答案是零;这意味着第二阶段直到第一阶段结束才开始。 –

+0

我明白你的意思了。谢谢。我会试一试并提供一个关于我是否成功的更新。 –

回答

6

正如我在评论中解释的那样,有四个步骤。

  1. 计算较晚的开始日期;在此之前,重叠是不可能的。
  2. 计算较早的结束日期;之后重叠是不可能的。
  3. 从较早的结束日期减去较晚的开始日期。
  4. 检查结果。如果它是零或更大,那就有你的答案。如果它是负面的,那么你的答案是零;这意味着第二阶段直到第一阶段结束才开始。

这里是做你想要什么功能:

/** 
* 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 
+0

这工作很好。非常感谢Ed。我仍然不完全理解这个逻辑,但是我测试了很多不同的方法,并且它工作得很好。你一定是个天才。 –

+0

@LukeJames高兴它适合你,并乐意帮助! –

+0

可靠的答案 - 但你为什么不使用2个DatePeriod对象? –

2

使用@Ed科特雷尔的代码作为基础,我放在一起这个小方法基于PHP的OO日期类:

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的测试用例,这yiel ds:

$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 
+0

干得好。我个人并不确定我觉得这更容易理解,但它是一个很好的使用一些OOP。 –

+0

感谢您的补充。这是一个非常优雅的解决方案。我很高兴人们发现这个线程很有帮助。 –

相关问题