2017-04-06 4 views
0

https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlapDeux dates de chevauchement de gamme - 1501 personnes manquant bug? [PHP]

J'ai écrit cet article pour être sûr que je me trompe ou que personne n'a vu le bug ici. Pour être sûr que je rassemble toutes les données dans les fonctions pour montrer les résultats et décrire mon point.

Tout était bon, mais quand nous ANÁLISE toutes les combinaisons de dates, je pense qu'il ya un bug en combinaison 6 & 7. Mb il ne devrait jamais happend mais quand nous ANÁLISE beaucoup de données il y a point où nous ne savons pas et la combinaison 6 sera nécessaire.

La fonction simulate_ranges consiste à vérifier toutes les possibilités que nous pouvons vérifier pour vérifier si l'installation est bonne ou non.

Fonction stack_overflow_answers - réponses du sujet pour vérifier les résultats. Terminer "pour" est de vérifier toutes les réponses avec toutes les combinaisons. S'il vous plaît décommettre les autres cas pour vérifier les résultats et dites moi: Est-ce que je me trompe ou le sujet à partir du lien supérieur ont des mathématiques mal à cas 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); 
} 

Merci pour @JustOnUnderMillions pour une réponse rapide et efficace!

MISE À JOUR - 2017.04.06 13:20 - plage de dates ajoutée au cas 8 et calcul de @JustOnUnderMillions. Son cas fonctionne bien dans tous les cas.

Lorsque nous avons mis les plages de dates ne @JustOnUnderMillions calcul est bon

Je
# 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

fonction 'color()' est manquant – JustOnUnderMillions

+0

Vous avez raison j'ai oublié de le changer en html. J'ai aussi ajouté un nouveau cas et une autre correction à notre fonction dans le nouveau cas 7 – Lesenus

+0

J'ai de la difficulté à comprendre votre question et votre résultat, mais est-il correct de dire que vous avez trouvé une réponse élevée, et dans cette question vous essayez de trouver s'il y a un bug? Cela aiderait (moi au moins) très bien si vous aviez une brève intro avec ce que la mauvaise «solution» était, ce que votre entrée est, et ce que la sortie (mauvaise) était. Cela pourrait être fait en 3 lignes. Aussi, pouvez-vous ajouter un non à cette réponse originale? parce que rien n'indique une sorte de problème – Nanne

Répondre

1

seulement Note à la complexité utilisée:

Il est tout vérifier sur une daterange contre daterange, de sorte que tous les trucs appelé EndA StartA EndB est câblé.

Je voudrais d'abord vérifier la date de sorcière est plus tôt dans la gamme. Et puis trier avant de l'utiliser, de sorte que le Charles Bretana - maybe all cases in once? n'est pas nécessaire.

Il suffit de commander le dateranges avant de les vérifier en détail. Si vous avez fait cela, une seule vérification indiquera si elles se chevauchent ou non.

DR = DateRange, 1 = début plus précoce de 2, S = départ, E = Fin

DR2S> DR1E = Pas Overlap (ici nous ne faisons pas >=)

$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>'; 
    } 
} 

Résultats:

2017-01-01 - 02/01/2017 vs 03/01/2017 - 04/01/2017 NO OVERLAP

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

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

2017-01-01 - 03/01/2017 vs 03/01/2017 - 04/01/2017 OVERLAP

Espérons que cela simplifie le sujet un peu.

+0

Merci JustOnUnderMillions votre cas est génial et prouvé que tout sujet de neuf ans est buggé et personne ne l'a vu. Et merci pour cette excellente solution. Maintenant, je sais que je peux conticue mon travail avec une bonne fonction de chevauchement de dates! – Lesenus

+1

@Lesenus Toujours agréable d'aider :-) – JustOnUnderMillions

+0

Maintenant, je sais que votre solution est la meilleure. Mes calculs échouent dans ce cas: $ 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