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

时间:2016-10-28 09:37:00

标签: php logic uptime

解决方案:

我看着这个: 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循环计算正常运行时间有何想法?

有更有效/更简单的方法吗?

您是否能够完成逻辑以使正常运行时间结果按预期工作?

1 个答案:

答案 0 :(得分:0)

这样的算法有四个步骤:

  1. 将事件过滤到与报告日期范围重叠的事件
  2. 按事件开始对事件进行排序
  3. 将所有事件合并为连续的块(O(n)操作)
  4. 通过返回合并事件(O(n)操作)
  5. 之间的间隔来反转这些范围

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

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