2017-04-06 36 views
0

https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap兩個日期範圍重疊 - 1501個人缺少錯誤? [PHP]

我寫了這篇文章,以確定我錯了,或沒有人看到這裏的錯誤。

爲了確保我收集所有功能數據以顯示結果並描述我的觀點。

全部是好的,但是當我們analise日期的所有組合我覺得這是在組合中的錯誤6 & 7. MB它決不應happend但是當我們analise很多DATAS的存在地步,我們不知道和組合6將需要。

函數simulate_ranges用於檢查我們可以檢查的所有可能性,以檢查aswer是否良好。

函數stack_overflow_answers - 從主題的答案檢查結果。

結束「for」是檢查所有組合的答案。

請取消其他情況下,檢查結果並告訴我: 我是錯的或從頂部鏈接的話題有錯誤的數學案例6?

function simulate_ranges($case) { 
switch($case) { 
    case 1: 
     # A X Z B 
     $a='2017-01-01'; 
     $b='2017-01-04'; 
     $x='2017-01-02'; 
     $z='2017-01-03'; 
     $combo=array('a' => $a,'x' => $x,'z' => $z,'b' => $b); 
     $pair=array('a, b' =>$a.' - '.$b, 'x, z' => $x.' - '.$z); 
     # ----- START A ------------------------------------------------------------------------------ START B --- # 
     # -------------------------------- END X ------------------------ END Z ----------------------------------- # 
     break; 

    case 2: 
     # A X B Z 
     $a='2017-01-01'; 
     $b='2017-01-03'; 
     $x='2017-01-02'; 
     $z='2017-01-04'; 
     $combo=array('a' => $a,'x' => $x,'b' => $b,'z' => $z); 
     $pair=array('a, b' =>$a.' - '.$b, 'x, z' => $x.' - '.$z); 
     # ----- START A ------------------------------------------ START B --------------------------------------- # 
     # -------------------------------- END X ----------------------------------------------- END Z ------------ # 
     break; 

    case 3: 
     # X A Z B 
     $a='2017-01-02'; 
     $b='2017-01-04'; 
     $x='2017-01-01'; 
     $z='2017-01-03'; 
     $combo=array('x' => $x,'a' => $a,'z' => $z,'b' => $b); 
     $pair=array('a, b' =>$a.' - '.$b, 'x, z' => $x.' - '.$z); 
     # -------------------------------------- START A --------------------------------------- START B --------- # 
     # ---------- END X -------------------------------------- END Z ------------------------------------------- # 
     break; 

    case 4: 
     # X A B Z 
     $a='2017-01-02'; 
     $b='2017-01-03'; 
     $x='2017-01-01'; 
     $z='2017-01-04'; 
     $combo=array('x' => $x,'a' => $a,'b' => $b,'z' => $z); 
     $pair=array('a, b' =>$a.' - '.$b, 'x, z' => $x.' - '.$z); 
     # -------------------------------------- START A ---------------- START B -------------------------------- # 
     # ---------- END X ----------------------------------------------------------- ----------- END Z --------- # 
     break; 

    case 5: 
     # A B X Z 
     $a='2017-01-01'; 
     $b='2017-01-02'; 
     $x='2017-01-03'; 
     $z='2017-01-04'; 
     $combo=array('a' => $a,'b' => $b,'x' => $x,'z' => $z); 
     $pair=array('a, b' =>$a.' - '.$b, 'x, z' => $x.' - '.$z); 
     # --------- START A --------- --------- START B --------- # # ----------------------- ---------------------------------------- # 
     # ---------------------------------------------------------------- # # ---------- END X ----------- ----------- END Z --------- # 
     break; 

    case 6: 
     # X Z A B 
     $a='2017-01-03'; 
     $b='2017-01-04'; 
     $x='2017-01-01'; 
     $z='2017-01-02'; 
     # ---------- END X ----------- ----------- END Z --------- # # ---------------------------------------------------------------- # 
     # ----------------------- ---------------------------------------- # # --------- START A --------- --------- START B --------- # 
     $combo=array('x' => $x,'z' => $z,'a' => $a,'b' => $b); 
     $pair=array('a, b' =>$a.' - '.$b, 'x, z' => $x.' - '.$z); 
     break; 

    case 7: 
     # A B X Z 
     $a='2017-01-01'; 
     $b='2017-01-02'; 
     $x='2017-01-02'; 
     $z='2017-01-03'; 
     # --------- START A --------- --------|- START B -|---------------------------------------------- # 
     # -----------------------------------------|-- END X ---|-------------------------- END Z --------- # 
     $combo=array('a' => $a,'b' => $b,'x' => $x,'z' => $z); 
     $pair=array('a, b' =>$a.' - '.$b, 'x, z' => $x.' - '.$z); 
     break; 

case 8: 
    # X Z A B 
    $a='2017-01-01 01:00:00'; 
    $b='2017-01-02 00:00:00'; 
    $x='2017-01-01 00:00:01'; 
    $z='2017-01-01 01:00:00'; 

    # --------- END X --------- --------|- START A -|---------------------------------------------- # 
    # -----------------------------------------|-- END Z ---|-------------------------- START B --------- # 
    $combo=array('x' => $x,'a' => $a, 'z' => $z,'b' => $b); 
    $pair=array('a, b' =>$a.' - '.$b, 'x, z' => $x.' - '.$z); 
    break; 

} 

$a2=strtotime($a); 
$b2=strtotime($b); 
$x2=strtotime($x); 
$z2=strtotime($z); 

echo '<table>'; 
foreach($combo as $var => $data) { 
    $strtotime=${$var.'2'}; 
    switch($var)  { 
     case 'a': $final_var='StartA'; break; 
     case 'b': $final_var='StartB'; break; 
     case 'x': $final_var='EndA'; break; 
     case 'z': $final_var='EndB'; break; 
    } 
    echo '<tr><td style="text-align: right;"> ('.$final_var.') </td><td>&rarr; '.$data.'</td><td> ('.$strtotime.')</td></tr>'; 
} 
echo '</table>'; 

echo '<table><tr>'; 
$i=0; 
foreach($pair as $vars => $dates_ranges) { 
    switch($vars)  { 
     case 'a, b': $final_vars='StartA, StartB'; break; 
     case 'x, z': $final_vars='EndA, EndB'; break; 
    } 
    echo '<td style="text-align: right;"> ('.$dates_ranges.') </td>'; 
    if(empty($i)) { 
     echo '<td>&larr;&rarr;</td>'; 
    } 
    $i=1; 
} 
echo '</tr></table>'; 

return array('a' => $a2, 'b' => $b2, 'x' => $x2, 'z' => $z2); 
} 

function result($result) { 
if($result) { 
    echo '<span style="background: green; color: white; padding: 1px 10px;">Dates match</span>'; 
} 
else { 
    echo '<span style="background: red; color: white; padding: 1px 10px;">Dates <b>NOT</b> match</span>'; 
} 
echo '<hr />'; 
} 

function stack_overflow_answers($case,$a,$b,$x,$z) { 
#StartA -> a 
#StartB -> b 
#EndA -> x 
#EndB -> z 
echo '<br />'; 
switch($case) 
{ 
    case 'Charles Bretana - first': 

     echo '<b>(StartA <= EndB) and (StartB <= EndA) and (StartA <= EndA) and (StartB <= EndB)</b><br />'; 
     if((($a <= $z) && ($b <= $x) && ($a <= $x) && ($b <= $z))) 
      result(false); 
     else 
      result(true); 
     break; 

    case 'Charles Bretana - second': 

     echo '<b>(StartA <= EndB) and (StartA <= EndA) and (StartB <= EndA) and (StartB <= EndB)</b><br />'; 
     if( ($a <= $z) && ($a <= $x) && ($b <= $x) && ($b <= $z) ) 
      result(false); 
     else 
      result(true); 
     break; 

    case 'Charles Bretana - third': 

     echo '<b>(StartA <= Min(EndA, EndB) and (StartB <= Min(EndA, EndB))</b> &rarr; Missing bracket?<br />'; 
     if( $x <= Min($x, $z) && ($b <= Min($x, $z))) 
      result(false); 
     else 
      result(true); 
     break; 

    case 'Charles Bretana - fourth': 

     echo '<b>(Max(StartA, StartB) <= Min(EndA, EndB)</b> &rarr; Missing bracket too?<br />'; 
     if( Max($a, $b) <= Min($x, $z)) 
      result(false); 
     else 
      result(true); 
     break; 

    case 'Charles Bretana - maybe all cases in once?': 

     echo '<b>(StartA <= EndB) and (StartB <= EndA) and (StartA <= EndA) and (StartB <= EndB)<br />'; 
     echo '(StartA <= EndB) and (StartA <= EndA) and (StartB <= EndA) and (StartB <= EndB)<br />'; 
     echo '(StartA <= Min(EndA, EndB) and (StartB <= Min(EndA, EndB))<br />'; 
     echo '(Max(StartA, StartB) <= Min(EndA, EndB)<br />'; 
     echo '</b><br />'; 
     if( 
       (($a <= $z) && ($b <= $x) && ($a <= $x) && ($b <= $z)) 
      || (($a <= $z) && ($a <= $x) && ($b <= $x) && ($b <= $z) ) 
      || ($x <= Min($x, $z) && ($b <= Min($x, $z))) 
      || (Max($a, $b) <= Min($x, $z)) 
     ) 
      result(false); 
     else 
      result(true); 
     break; 

    case 'Charles Bretana - using C': 

     echo '<b>(StartA > StartB? Start A: StartB) <= (EndA < EndB? EndA: EndB)</b><br />'; 
      $result=($a > $b? $a: $b) <= ($x < $z? $x: $z); 
      if($result === false) 
       result(true ); 
      else 
       result(false); 

     break; 

    case 'Ian Nelson': 

     echo '<b>(StartDate1 <= EndDate2) and (StartDate2 <= EndDate1)</b><br />'; 
     if( 
       ($a <= $z) && ($b <= $x) 

     ) 
      result(false); 
     else 
      result(true); 
     break; 

    case 'First Good Solution? Almost': 
     echo '<b>Min(StartA, StartB) >= Max(EndA, EndB) OR Max(StartA, StartB) <= Min(EndA, EndB)</b><br />'; 
     if((Min($a, $b) >= Max($x, $z)) || (Max($a, $b) <= Min($x, $z))  
       && $a !== $x 
       && $b !== $x 
       && $a !== $z 
       && $b !== $z 
      ) 
      result(false); 
     else 
      result(true); 

     break; 

    case 'JustOnUnderMillions': 
     echo '<b>Simplyfy function sort before</b><br />'; 
     $ranges = array(
        array(array($a,$b),array($x,$z)), 
      ); 
      foreach($ranges as $set){ 
        //to change the order of the ranges for testing 
        shuffle($set); 
        //now order it 
        usort($set,function($a,$b){ 
          if ($a[0] == $b[0]) { return 0; } 
          return ($a[0] < $b[0]) ? -1 : 1; 
        }); 
        //test DR2S > DR1E no overlap 
        if($set[1][0] > $set[0][1]){ 
          result(false); 
        } else { 
          result(true); 
        } 
      } 

      break; 
} 
} 

for($i=1; $i <= 8; $i++) { 
$case='Charles Bretana - first'; 
// $case='Charles Bretana - second'; 
// $case='Charles Bretana - third'; 
// $case='Charles Bretana - fourth'; 
// $case='Charles Bretana - maybe all cases in once?'; 
// $case='Charles Bretana - using C'; 
// $case='Ian Nelson'; 
// $case='First Good Solution? Almost'; 
// $case='JustOnUnderMillions'; 


if($i === 1) { echo '<hr />Case <span style="color: blue;">'.$case.'</span><hr />'; } 
echo 'Combination <span style="color: red;">'.$i.'</span><br />'; 
$temp=simulate_ranges($i); 
$a = $temp['a']; 
$b = $temp['b']; 
$x = $temp['x']; 
$z = $temp['z']; 
stack_overflow_answers($case,$a,$b,$x,$z); 
} 

感謝@JustOnUnderMillions快速響應!

已更新 - 2017.04.06 13:20 - 添加了8個日期範圍和@JustOnUnderMillions計算。他的情況在所有情況下都表現良好。

當我們把那些迄今爲止只有範圍@JustOnUnderMillions計算好

# https://stackoverflow.com/questions/43250973/two-dates-range-overlap-1501-people-missing-bug-php 
$time_min='2017-01-01 01:00:00'; 
$time_max='2017-01-02 00:00:00'; 
$time_checked_min='2017-01-01 00:00:01'; 
$time_checked_max='2017-01-01 01:00:00'; 

var_dump(checkRangeBetweenRange($time_min, $time_max, $time_checked_min, $time_checked_max)); 

function checkRangeBetweenRange($time_min, $time_max, $time_checked_min, $time_checked_max, $convert_date=true){ 
    # convert date time 
    if($convert_date) { 
     $time_min=strtotime($time_min); 
     $time_max=strtotime($time_max); 
     $time_checked_min=strtotime($time_checked_min); 
     $time_checked_max=strtotime($time_checked_max); 
    } 

    # https://stackoverflow.com/questions/43250973/two-dates-range-overlap-1501-people-missing-bug-php 
    $ranges = array(
       array(array($time_min,$time_max),array($time_checked_min,$time_checked_max)), 
     ); 
     foreach($ranges as $set){ 
       //to change the order of the ranges for testing 
       shuffle($set); 
       //now order it 
       usort($set,function($a,$b){ 
         if ($a[0] == $b[0]) { return 0; } 
         return ($a[0] < $b[0]) ? -1 : 1; 
       }); 
       //test DR2S > DR1E no overlap 
       if($set[1][0] > $set[0][1]){ 
         return false; 
       } else { 
         return true; 
       } 
     } 


} 
+0

function'color()'missing – JustOnUnderMillions

+0

你是對的我忘了把它改成html。此外,我在新的案例7中增加了一個新案例和另一個修復程序,以適應我們的功能。 – Lesenus

+0

我無法理解您的問題和結果,但說您找到高回答的答案是正確的,在此問題中,您嘗試查找如果有錯誤呢?如果你有一個關於錯誤的「解決方案」的簡短介紹,你的輸入是什麼以及輸出是什麼(錯誤的),這將有助於我(至少)。這可以在3行中完成。另外,你可以添加一個不是原來的答案?因爲沒有任何內容表明某種問題 – Nanne

回答

1

我只有一個Note複雜性應用於:

它是所有關於檢查daterangedaterange,所以所有的東西稱爲EndA StartA EndB是有線的。

我會先檢查女巫的日期是否在範圍內。然後在使用前對其進行分類,因此不需要Charles Bretana - maybe all cases in once?

只需在訂購dateranges之前仔細檢查它們。 如果你已經這樣做了,一張支票就會說明它們是否重疊。

DR =日期範圍,1 =起步比較早比2,S =啓動,E =結束

DR2S> DR1E =無重疊(在這裏我們不做>=

$ranges = array(
    //only non overlap 
    array(array('2017-01-01','2017-01-02'),array('2017-01-03','2017-01-04')), 
    //rest overlapping 
    array(array('2017-01-01','2017-01-02'),array('2017-01-02','2017-01-04')), 
    array(array('2017-01-01','2017-01-02'),array('2017-01-01','2017-01-04')), 
    array(array('2017-01-01','2017-01-03'),array('2017-01-03','2017-01-04')), 
); 
foreach($ranges as $set){ 
    //to change the order of the ranges for testing 
    shuffle($set); 
    //now order it 
    usort($set,function($a,$b){ 
     if ($a[0] == $b[0]) { return 0; } 
     return ($a[0] < $b[0]) ? -1 : 1; 
    }); 
    //show 
    print implode(' - ',$set[0]).' vs '.implode(' - ',$set[1]); 
    //test DR2S > DR1E no overlap 
    if($set[1][0] > $set[0][1]){ 
     print ' NO OVERLAP<br>'; 
    } else { 
     print ' OVERLAP<br>'; 
    } 
} 

結果

2017年1月1日 - 2017年1月2日VS 2017年1月3日 - 2017年1月4日沒有重疊

2017-01-01 - 2017-01-02 vs 2017-01-02 - 2017-01-04 OVERLAP

2017-01-01 - 2017-01-04 vs 2017-01-01 - 2017- 01-02 OVERLAP

2017年1月1日 - 2017年1月3日VS 2017年1月3日 - 2017年1月4日OVERLAP

希望這簡化了話題一點點。

+0

感謝JustOnUnderMillions你的案例非常棒,證明整個9歲的話題都被淹沒了,沒有人看到。並感謝您的解決方案。現在我知道我可以用日常範圍重疊的功能來優化我的工作! – Lesenus

+1

@Lesenus總是很好幫助:-) – JustOnUnderMillions

+0

現在我知道你的解決方案是最好的。我的計算失敗: $ time_min ='2017-01-01 01:00:00'; $ time_max ='2017-01-02 00:00:00'; $ time_checked_min ='2017-01-01 00:00:01'; $ time_checked_max ='2017-01-01 01:00:00'; – Lesenus