PHP重叠事件的阵列获取的正常运行时间

问题描述:

解决方案:PHP重叠事件的阵列获取的正常运行时间

我看了看这个: Merging overlapping ranges in PHP arrays?

,并解决了我在这个例子中的问题: https://3v4l.org/XCtlT

非工作代码例如这里: https://3v4l.org/sStTT

从本质上讲,我有重叠的停机事件,看起来像这样的数组:

$incidents = [ 
    ['start' => '2016-01-05 00:00:00', 'end' => '2016-01-10 23:59:59'], 
    ['start' => '2016-01-07 00:00:00', 'end' => '2016-01-15 23:59:59'], // overlapping 
    ['start' => '2016-01-12 00:00:00', 'end' => '2016-01-13 23:59:59'], // overlapping 
    ['start' => '2016-01-20 00:00:00', 'end' => '2016-01-25 23:59:59'], 
    ['start' => '2016-01-23 00:00:00', 'end' => '2016-01-24 23:59:59'] // overlapping 
]; 

而且从事故阵列我期望得到下面的结果作为一个正常运行阵列。

Array 
(
    [0] => Array 
     (
      [start] => 2016-01-01 00:00:00 
      [end] => 2016-01-05 00:00:00 
     ) 

    [1] => Array 
     (
      [start] => 2016-01-15 23:59:59 
      [end] => 2016-01-20 00:00:00 
     ) 

    [2] => Array 
     (
      [start] => 2016-01-25 23:59:59 
      [end] => 2016-01-31 23:59:59 
     ) 
) 

不幸的是,我的逻辑游戏不够好,足以完成可靠而高效的任务。在我的例子中,我有大约250万行数据库中的事件。

你对使用2 for循环来计算正常运行时间的想法?

是否有更有效的/更简单的方法来做到这一点?

您能够完成逻辑,正常运行时间的结果如预期运行?

+0

要注意的一点:如果可能的话,你真的应该考虑使用[开始,结束)格式的日期时间范围内(含开始,独家结束)。当试图解决'2016-01-25 00:00:00 - > 2016-01-25 23:59:59'与'2016-01-26 00:00:'连续时,它会使算法变得更简单。 00 - > 2016-01-26 23:59:59'。 – Phylogenesis

有四个步骤,以这样的算法:

  1. 筛选事件那些重叠的报告日期范围
  2. 排序事件的事件开始
  3. 全部合并事件为连续的块( O(n)操作)
  4. 通过返回合并事件之间的间隔来反转这些范围(O(n)操作)

步骤1和2可以在数据库中查询被简单处理,如:

select start, end 
from  incidents 
where  start < :reportEnd and 
      end > :reportStart 
order by start