2016-07-19 110 views
0

我需要按照其他日期範圍拆分範圍內的日期範圍數組。php - 將日期範圍拆分爲塊

例如,我開始陣列可以是:

$items = array(
    array(
     'ID' => 2, 
     'from' => new DateTime('2016-07-01'), 
     'to' => new DateTime('2016-07-19') 
    ), 
    array(
     'ID' => 3, 
     'from' => new DateTime('2016-07-15'), 
     'to' => new DateTime('2016-07-29') 
    ), 
    array(
     'ID' => 1, 
     'from' => new DateTime('2016-01-01'), 
     'to' => new DateTime('2016-12-31') 
    ), 
    array(
     'ID' => 4, 
     'from' => new DateTime('2016-06-15'), 
     'to' => new DateTime('2016-07-07') 
    ), 
    array(
     'ID' => 5, 
     'from' => new DateTime('2016-07-05'), 
     'to' => new DateTime('2016-07-17') 
    ), 
); 

而且我預計結果與參照項的ID各個時期的數組,像這樣:

$result = array(
    array(
     'from' => new DateTime('2016-01-01'), 
     'to' => new DateTime('2016-06-14'), 
     'ids' => array(
      1 
     ) 
    ), 
    array(
     'from' => new DateTime('2016-06-15'), 
     'to' => new DateTime('2016-06-30'), 
     'ids' => array(
      1, 4 
     ) 
    ), 
    array(
     'from' => new DateTime('2016-07-01'), 
     'to' => new DateTime('2016-07-04'), 
     'ids' => array(
      1, 2, 4 
     ) 
    ), 
    array(
     'from' => new DateTime('2016-07-05'), 
     'to' => new DateTime('2016-07-07'), 
     'ids' => array(
      1, 2, 4, 5 
     ) 
    ), 
    array(
     'from' => new DateTime('2016-07-08'), 
     'to' => new DateTime('2016-07-14'), 
     'ids' => array(
      1, 2, 5 
     ) 
    ), 
    array(
     'from' => new DateTime('2016-07-15'), 
     'to' => new DateTime('2016-07-17'), 
     'ids' => array(
      1, 2, 3, 5 
     ) 
    ), 
    array(
     'from' => new DateTime('2016-07-18'), 
     'to' => new DateTime('2016-07-19'), 
     'ids' => array(
      1, 2, 3 
     ) 
    ), 
    array(
     'from' => new DateTime('2016-07-20'), 
     'to' => new DateTime('2016-07-29'), 
     'ids' => array(
      1, 3 
     ) 
    ), 
    array(
     'from' => new DateTime('2016-07-30'), 
     'to' => new DateTime('2016-12-31'), 
     'ids' => array(
      1 
     ) 
    ), 
); 

你可以幫我嗎?謝謝

更新 現在我試圖通過'從'項目和循環項目和範圍數組來命令數組。這是我的代碼:

usort($items, function($a, $b) { 
    if ($a['from'] == $b['from']) { 
     return 0; 
    } 
    if ($a['from'] < $b['from']) { 
     return -1; 
    } 
    return 1; 
}); 

$ranges = array(
    array(
     'from' => clone $items[0]['from'], 
     'to' => clone $items[0]['to'], 
     'ids' => array($items[0]['ID']) 
    ) 
); 
unset($items[0]); 
foreach($items as $item) { 
    foreach($ranges as $k => $range) { 
     if (($range['from'] <= $item['from']) || ($range['to'] > $item['to'])) { 
      if ($range['from'] <= $item['from']) { 
       $clone = $range; 
       $clone['from'] = $item['from']; 
       $clone['to'] = clone $item['to']; 
       $clone['ids'][] = $item['ID']; 

       $ranges[$k]['to'] = clone $item['from']; 
       $ranges[$k]['to']->modify('-1 day'); 
       $ranges[] = $clone; 
      } 

      if ($range['to'] > $item['to']) { 
       $clone = $range; 
       $clone['from'] = clone $item['to']; 
       $clone['from']->modify('+1 day'); 
       $clone['to'] = clone $range['to']; 
       $ranges[] = $clone; 
      } 
     } 
    } 
} 

但結果是一個數組,我需要更多的結果。感謝您的幫助。

+0

問題是什麼?你有什麼嘗試? –

回答

0

老實說,我會讓這個多步驟的過程...雖然我確信它可以一步完成,但代碼會 - 並且可能已經 - 混淆爲地獄(因爲我不'您可以在幾秒鐘內瞭解您的代碼):

我將以一次傳遞開始,我將所有日期和所有from日期和所有from日期存儲並排序。

現在你有你的間隔。第一項是from,並且必須與最小的from日期相匹配。下一個日期可能是to+1from日期。無論哪種方式,間隔從from到任何下一個是負1。下一個間隔從該值開始,直到下一個1,依此類推。

下一步,將原始間隔分類到新的間隔中。 (並且過濾掉那些不包含任何內容的間隔)。

除非性能/存儲是一個非常大的問題,否則這可能會足夠好,並且很可能被任何代碼繼承的人理解。