在两个 PHP DatePeriods 中查找重叠分钟数

Posted

技术标签:

【中文标题】在两个 PHP DatePeriods 中查找重叠分钟数【英文标题】:Finding amount of overlapping minutes in two PHP DatePeriods 【发布时间】:2016-01-21 01:15:19 【问题描述】:

我想找出两个 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”由两个日期组成,我正在寻找两个 DatePeriod 之间的重叠(不是差异)的数量。

【问题讨论】:

这个已经回答了:***.com/questions/365191/… 这不能回答我的问题。你给我的例子没有使用两个日期期间,它只使用了两个日期。一个日期期间由两个日期组成。 另外,我不是在寻找差异,而是在寻找重叠时间。 @LukeJames 当然,您可以使用链接主题中的答案来使用某些逻辑来制定自己的解决方案,例如如果 endDate1 > startDate2 然后获取它们的差异 【参考方案1】:

这里是类DatePeriodsOverlap,代表两个时期的重叠。 如果没有交集,它的结果是重叠 DatePeriodException

注意:DatePeriod 是可遍历的对象,PT1M 是迭代步骤的持续时间。 PT1M 表示一分钟的间隔。详细信息about 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')]"
    );
  

【讨论】:

你还应该为你建议的解决方案提供一个简短的解释 @yakobom 感谢您的审阅,我已详细更新了答案。

以上是关于在两个 PHP DatePeriods 中查找重叠分钟数的主要内容,如果未能解决你的问题,请参考以下文章

查找两个矩形的重叠区域(在 C# 中)

查找两个数据帧之间的重叠区域

查找两个整数范围之间的重叠区域

是否可以使用R data.table函数foverlaps来查找两个表中重叠范围的交集?

PHP计算两个时间段是否有交集(边界重叠不算)

大厂算法面试:使用移动窗口查找两个不重叠且元素和等于给定值的子数组