2017-04-06 1 views
0

https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap두 개의 날짜 범위가 겹칩니다. 1501 명이 버그가 누락 되었습니까? [PHP]

나는이 게시물을 작성하여 틀렸거나 아무도이 버그를 여기에서 보지 못했습니다.

결과에 나와 내 요점을 설명하기 위해 모든 데이터를 수집해야합니다.

모두 좋았지 만 모든 날짜 조합을 분석 할 때 버그가 있다고 생각하면 조합은 6 &입니다 .Mb는 결코 발생해서는 안되지만 많은 데이터를 분석 할 때 모르는 부분이 있습니다. 조합 6이 필요합니다.

기능 simulate_ranges는 aswer가 양호한 지 여부를 확인할 수있는 모든 가능성을 확인하는 것입니다.

function 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!

UPDATED - 2017.04.06 13:20 - 사례 8 날짜 범위와 @JustOnUnderMillions 계산이 추가되었습니다. 그의 경우는 모든 경우에 잘 작동합니다.

그것은 모두에 대한 daterangedaterange에 대해을 확인, 그래서 모든 물건 :

우리가 그 날짜를 넣어

# 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()'가 없습니다. – JustOnUnderMillions

+0

당신은 맞습니다. html로 바꾸는 것을 잊었습니다. 또한 새로운 케이스와 새로운 케이스 7에 새로운 함수를 추가했습니다. – Lesenus

+0

질문과 결과를 이해하는 데 어려움을 겪고 있지만 높은 upvoted 답변을 찾았다 고 말하는 것이 옳습니다.이 질문에서 버그가 있으면 밖으로 나가십시오. 당신이 잘못된 '해결책'이 무엇인지, 당신의 의견이 무엇인지, 그리고 (잘못된) 결과가 무엇인지에 대해 짧은 소개를한다면 그것은 도움이 될 것입니다. 그것은 3 라인에서 할 수 있습니다. 또한, 원래 답변을 추가 할 수 있습니까? 아무 것도 문제가 있음을 알 수 없으므로 – Nanne

답변

1

난 단지 사용의 복잡성에 Note이 @JustOnUnderMillions 좋은 계산에만 범위 EndA StartA EndB이 연결됩니다.

먼저 마녀 날짜가 범위 내에서 먼저 체크 할 것입니다. 그리고 그것을 사용하기 전에 그것을 정렬, 그래서 Charles Bretana - maybe all cases in once? 필요하지 않습니다.

세부 사항을 확인하기 전에 dateranges을 주문하십시오. 이 작업을 수행 한 경우, 하나의 단일 검사는 겹치지 않았는지 여부를 나타냅니다.

DR = DATERANGE, 2에 비해 1 = 이전 시작, 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월 3일 대 2017년 1월 2일 - 2017년 1월 4일 NO OVERLAP

,536,913,632 10

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일 대 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