https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap
我写这篇文章是为了确定我错了,或者没有人在这里看到这个错误。
为了确保我收集函数中的所有数据以显示结果并描述我的观点。
一切都很好,但是当我们分析所有日期组合时,我认为组合6和组合中存在一个错误。 7.它应该永远不会发生,但是当我们对大量数据进行分析时,有一点我们不知道,并且需要组合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>→ '.$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>←→</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> → 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> → 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 :(得分:1)
我只使用Note
复杂度:
所有关于daterange
对daterange
的检查,所以所有称为EndA StartA EndB
的内容都是有线的。
我首先会检查女巫日期是否在范围之前。然后在使用之前对其进行排序,因此不需要Charles Bretana - maybe all cases in once?
。
在详细检查之前,只需订购dateranges
即可。
如果你这样做了,一次检查会说明它们是否重叠。
DR = DateRange,1 =早于2开始,S =开始,E =结束
DR2S&gt; 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-01-01 - 2017-01-02 vs 2017-01-03 - 2017-01-04 NO OVERLAP
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-01-01 - 2017-01-03 vs 2017-01-03 - 2017-01-04 OVERLAP
希望这会稍微简化一下这个话题。