检查日期范围(开始和结束日期)是否有重叠 [英] Check date ranges (start and end date) for overlap

查看:128
本文介绍了检查日期范围(开始和结束日期)是否有重叠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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中,这应该作为没有相交的日期通过.

The following is what I was attempting to check intersection of date ranges. In the array "ranges1" this example has overlapping dates. It should return the dates. In array $ranges2, this should pass as no intersecting dates.

现在很奇怪的是,开始日期和结束日期可以完全相同,因此您可以输入一天的时间.我尝试了很多事情,但感到很困惑.

Now the weird thing is the start and end date can be the exact same, so you could make an entry for just a single day. I've tried many things, and I'm stumped.

我认为还需要另一个for循环,但是不管我没有获得成功.

I believe there needs to be another for loop, but regardless I am not getting success.

这是我的另一项尝试:

<?php

///将范围传递给此方法,如果存在常见的相交,它将 //返回或为假

// pass your ranges to this method and if there is a common intersecion it will // return it or false

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>";  

任何建议,我们将不胜感激.

Any advice greatly appreciated.

推荐答案

$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);

我已附上我的工作代码示例,希望将来可以帮助其他人寻找相同的解决方案.这将打印相交的数组.

I've attached my working code sample to hopefully help someone else in the future looking for the same solution. This will print the arrays that intersect.

这篇关于检查日期范围(开始和结束日期)是否有重叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆