【问题标题】:PHP Get uptime periods from array of overlapping Incidents [duplicate]PHP从重叠事件数组中获取正常运行时间[重复]
【发布时间】:2017-03-11 04:18:39
【问题描述】:

解决方案:

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

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

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

【问题讨论】:

  • 需要注意的一点:如果可能,您应该真正考虑为您的日期时间范围(包括开始,不包括结束)使用 [start, end) 格式。例如,当尝试计算出 2016-01-25 00:00:00 -> 2016-01-25 23:59:592016-01-26 00:00:00 -> 2016-01-26 23:59:59 连续时,这将使算法变得更加简单。

标签: php logic uptime


【解决方案1】:

这样的算法有四个步骤:

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

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

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

【讨论】:

    猜你喜欢
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 2021-03-05
    • 2016-10-07
    • 2016-05-27
    • 2017-10-17
    • 1970-01-01
    相关资源
    最近更新 更多