2016-10-28 1 views
-1

ソリューション: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 
     ) 
) 

残念ながら、私のロジックゲームは、タスクを確実に効率的に完了するのに十分ではありません。実際の例では、DBに約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

答えて

0

このようなアルゴリズムの4つのステップがあります。

  1. フィルターは、レポートの日付範囲をオーバーラップしたものに事件が事件によって事件が
  2. 開始
  3. 分類は(連続したブロックにすべてのインシデントをマージO(n)操作)
  4. 統合されたインシデント間のギャップを返すことによってこれらの範囲を反転させます(O(n)操作)

ステップ1と2は、単になど、データベースクエリで処理することができます。

select start, end 
from  incidents 
where  start < :reportEnd and 
      end > :reportStart 
order by start 
関連する問題