2017-08-24 220 views
0

希望你做得很好!排除日期/時間範圍與重疊的日期/時間範圍

我有點卡住這個,我所做的只有在沒有重疊的情況下才能工作,無論如何我都不確定這是正確的方法。

所以我當前的實現是合併所有時間(start_time和end_time作爲該數組中的不同條目),對它們進行排序並刪除重複項(如果有的話)。

然後我循環進入該列表並檢查它們是否在$ times範圍內而不在限制範圍內。

所有通過這些條件的人都被添加到另一個列表中。然後,最後,我將循環訪問該列表'一次2項',並構建最終的時間範圍數組。

代碼:https://3v4l.org/2elDs(Laravel,使用收集和碳,所以不會出現運行)

樣品沒有日期/時間重疊:

$times = [ 
     [ 
      'start_time' => '2017-06-26 00:00:00', 
      'end_time' => '2017-06-26 05:00:00', 
     ], 
     [ 
      'start_time' => '2017-06-26 13:00:00', 
      'end_time' => '2017-06-26 18:00:00', 
     ] 
    ]; 

$timesToExclude= [ 
     [ 
      'start_time' => '2017-06-26 04:00:00', 
      'end_time' => '2017-06-26 04:30:00', 
     ], 
     [ 
      'start_time' => '2017-06-26 07:00:00', 
      'end_time' => '2017-06-26 10:00:00', 
     ], 
     [ 
      'start_time' => '2017-06-26 15:00:00', 
      'end_time' => '2017-06-26 16:00:00', 
     ] 
    ]; 

結果:

$result = [ 
     [ 
      "start_time" => "2017-06-26 00:00:00", 
      "end_time" => "2017-06-26 04:00:00" 
     ], [ 
      "start_time" => "2017-06-26 04:30:00", 
      "end_time" => "2017-06-26 05:00:00" 
     ], 
     [ 
      "start_time" => "2017-06-26 13:00:00", 
      "end_time" => "2017-06-26 15:00:00" 
     ], 
     [ 
      "start_time" => "2017-06-26 16:00:00", 
      "end_time" => "2017-06-26 18:00:00" 
     ] 
    ] 

帶日期/時間重疊的樣本

$times = [ 
     [ 
      'start_time' => '2017-06-26 00:00:00', 
      'end_time' => '2017-06-26 10:00:00', 
     ], 
     [ 
      'start_time' => '2017-06-26 05:00:00', 
      'end_time' => '2017-06-26 20:00:00', 
     ] 
    ]; 

    $timesToExclude= [ 
     [ 
      'start_time' => '2017-06-26 04:00:00', 
      'end_time' => '2017-06-26 04:30:00', 
     ], 
     [ 
      'start_time' => '2017-06-26 07:00:00', 
      'end_time' => '2017-06-26 09:00:00', 
     ], 
     [ 
      'start_time' => '2017-06-26 15:00:00', 
      'end_time' => '2017-06-26 16:00:00', 
     ] 
    ]; 

應該產生於:

$result = [ 
     [ 
      "start_time" => "2017-06-26 00:00:00", 
      "end_time" => "2017-06-26 04:00:00" 
     ], [ 
      "start_time" => "2017-06-26 04:30:00", 
      "end_time" => "2017-06-26 05:00:00" 
     ], 
     [ 
      "start_time" => "2017-06-26 05:00:00", 
      "end_time" => "2017-06-26 07:00:00" 
     ], 
     [ 
      "start_time" => "2017-06-26 09:00:00", 
      "end_time" => "2017-06-26 10:00:00" 
     ], 
     [ 
      "start_time" => "2017-06-26 10:00:00", 
      "end_time" => "2017-06-26 15:00:00" 
     ], 
     [ 
      "start_time" => "2017-06-26 16:00:00", 
      "end_time" => "2017-06-26 20:00:00" 
     ] 
    ] 

任何人都知道正確的算法中/僞來處理呢?

+0

你的例子對我沒有意義。我只看了第一個。輸入5個數組,輸出4.我可以理解你提到的重複。但時代正在轉移。爲什麼? 00-05變成00-04。 04-04:30我搬走了,也改變了。我不明白你需要以不同的方式驗證或解釋你的輸入/輸出。 – Andreas

+0

@Andreas $ times是我最初的次數列表,$ timesToExclude是我需要從最初列表中排除的次數,只是將該變量重命名,是否有意義? – David

+0

我明白你的意思了。讓我想一會兒。 – Andreas

回答

0

創建配對{time; flag}的常用列表,其中標記爲time_start, time_end, restriction_start or restriction_end

按時間排序此列表。如果綁定使用標誌作爲輔助鍵(例如,restr_start應該在time_end之後)。

$Active=0,通過排序列表$Exclude=0

走。

當滿足time_start,的$Active增量值{1}

當滿足time_end,的$Active減量值{2}

當滿足restriction_start,增量值​​{3}

當您遇到restriction_end時,遞減值爲​​{4}

Op烯在下一情況下,輸出時間間隔:
{1}:$Active變爲1,$Exclude = 0
{4}:$Exclude becomes 0$Active是非零在下一情況下

關閉輸出間隔:
{2} $Active變爲0,$Exclude = 0
{3}和$Exclude becomes 1$Active非零

例如:(不知道對於複合物的條件確切PHP語法)

case $TimeStart: 
      $active = $active + 1; 
      if ($active=1) and ($exclude=0) 
       $range['start_time'] = $mergedTime['time']; 
      break; 
.... 
    case $RestrictionEnd: 
      $exclude = $exclude - 1; 
      if ($exclude=0) and ($active > 0) 
       $range['start_time'] = $mergedTime['time']; 
      break; 
+0

嗨@MBo,不確定我得到(正值+1,負值-1),你能解釋嗎? – David

+0

好吧,認爲我得到了絕對的東西,但不是最後一部分'當$ Active變爲正值時開始輸出間隔,並以其他方式結束(0或負值)' – David

+0

也許你可以看看? https://3v4l.org/oEbRk – David