function checkDateOverlap($ranges) {
$res = $ranges[0];
$countRanges = count($ranges);
for ($i = 0; $i < $countRanges; $i++) {
$r1s = $res['start'];
$r1e = $res['end'];
$r2s = $ranges[$i]['start'];
$r2e = $ranges[$i]['end'];
if ($r1s >= $r2s && $r1s <= $r2e || $r1e >= $r2s && $r1e <= $r2e || $r2s >= $r1s && $r2s <= $r1e || $r2e >= $r1s && $r2e <= $r1e) {
$res = array(
'start' => $r1s > $r2s ? $r1s : $r2s,
'end' => $r1e < $r2e ? $r1e : $r2e
);
} else
return false;
}
return $res;
}
// example of returned dates that overlap
$ranges = array(
array('start' => '2014-01-01', 'end' => '2014-01-04'),
array('start' => '2014-01-05', 'end' => '2014-01-10'),
array('start' => '2014-01-04', 'end' => '2014-01-07')
);
//example of failure
$ranges2 = array(
array('start' => '2014-01-01', 'end' => '2014-01-04'),
array('start' => '2014-01-05', 'end' => '2014-01-10'),
array('start' => '2014-01-11', 'end' => '2014-01-17')
);
var_dump(checkDateOverlap($ranges));
以下是我试图检查日期范围的交叉点。在数组“ranges1”中,此示例具有重叠日期。它应该返回日期。在数组$ ranges2中,这应该作为没有相交的日期传递。
现在奇怪的是,开始和结束日期可以完全相同,所以你可以在一天内完成一个条目。我尝试了很多东西,我很难过。
我认为需要另一个for循环,但不管我没有取得成功。
这是另一回事:
<?php
//将范围传递给此方法,如果存在共同的交叉点,它将会 //返回或错误
function checkDateOverlap($ranges){
$res = $ranges[0];
$countRanges = count($ranges);
for ($i = 0; $i < count($countRanges); $i++) {
for($j = $i+1; $j < count($countRanges); $j++) {
$r1s = $res['start'];
$r1e = $res['end'];
$r2s = $ranges[$i]['start'];
$r2e = $ranges[$i]['end'];
if (($r1s >= $r2e && $r2s <= $r1e)) {
$res[] = array(
'start' => $r1s > $r2s ? $r1s : $r2s,
'end' => $r1e < $r2e ? $r1e : $r2e
);
} else
return false;
}
}
return $res;
}
// example
$ranges = array(
array('start' => '2014-01-04', 'end' => '2014-01-05'),
array('start' => '2014-01-06', 'end' => '2014-01-10'),
array('start' => '2014-01-11', 'end' => '2014-01-13')
);
echo "<pre>";
var_dump(checkDateOverlap($ranges));
echo "</pre>";
任何建议都非常感谢。
答案 0 :(得分:1)
$ranges = array(
array('start' => new DateTime('2014-01-01'), 'end' => new DateTime('2014-01-05')),
array('start' => new DateTime('2014-01-06'), 'end' => new DateTime('2014-01-06')),
array('start' => new DateTime('2014-01-07'), 'end' => new DateTime('2014-01-07')),
);
function intersects($lhs, $rhs) {
// Note that this function allows ranges that "touch",
// eg. one pair starts at the exact same time that the other ends.
// Adding less "or equal to" will allow same start date
return !($lhs['start'] > $rhs['end'] || $lhs['end'] < $rhs['start']);
}
function checkDates($ranges) {
// Comparison loop is of size n•log(n), not doing any redundant comparisons
for($i = 0; $i < sizeof($ranges); $i++) {
for($j = $i+1; $j < sizeof($ranges); $j++) {
if(intersects($ranges[$i], $ranges[$j])) {
echo "Date {$i} intersects with date {$j}\n";
}
}
}
}
checkDates($ranges);
我附上了我的工作代码示例,希望将来帮助其他人寻找相同的解决方案。这将打印相交的数组。
答案 1 :(得分:0)
如果您使用usort首先对日期进行排序,则工作变得更加容易。以下内容可以进行大量优化,但逐步完成后会更容易理解。
//The date comparison function, sort on start and then on end
function cmp($a, $b)
{
if($a['start']<$b['start']) return -1;
if($a['start']>$b['start']) return 1;
if($a['end']<$b['end']) return -1;
if($a['end']>$b['end']) return 1;
return 0; // start=start and end=end
}
$ranges = array(
array('start' => '2014-01-01', 'end' => '2014-01-04'),
array('start' => '2014-01-05', 'end' => '2014-01-10'),
array('start' => '2014-01-04', 'end' => '2014-01-07')
);
usort($ranges, 'cmp'); // Sort the dates
$output = array();
for($i=0; $i<sizeof($ranges); $i++)
{
$endindex = $i; // The index containing the proper 'end' value
for($j=$i+1; $j<sizeof($ranges); $j++)
{
if($ranges[$endindex]['start'] == $ranges[$j]['start']) // Overlap
$endindex = $j;
elseif($ranges[$endindex]['end']>=$ranges[$j]['start']) // Overlap
$endindex = $j;
}
$output[] = array('start' => $ranges[$i]['start'], 'end' => $ranges[$endindex]['end']);
// Break the rules by hard-setting $i from the for loop - it works great in this case
$i = $endindex;
}
print_r($output);
它适用于您的示例。如果您有其他必须使用的规则,希望您可以调整此代码。
答案 2 :(得分:0)
以下是一些评论:
- 您不会检查由“开始”组成的日期的有效性。并且&#39;结束&#39;
- 为什么不将日期转换为时间戳?
- &GT;比较整数值而不是字符串更容易,更快?
为什么不使用PHP DateTime和DateInterval对象?
http://php.net/manual/en/book.datetime.php