代码之家  ›  专栏  ›  技术社区  ›  Askerman

在PHP中找出两个日期范围重叠的天数

  •  -1
  • Askerman  · 技术社区  · 6 年前

    我有两个任意的日期范围,例如:

    2019-01-01 - 2019-01-10
    and
    2019-01-06 - 2019-01-20
    

    如何在PHP中找到这些日期范围重叠的天数?(在上面的例子中是5天)

    2 回复  |  直到 6 年前
        1
  •  1
  •   Nick SamSmith1986    6 年前

    这是一个使用 DateTime DateInterval

    $range1 = '2019-01-01 - 2019-01-10';
    $range2 = '2019-01-06 - 2019-01-20';
    list($start, $end) = explode(' - ', $range1);
    $start1 = new DateTime($start);
    $end1 = new DateTime($end);
    list($start, $end) = explode(' - ', $range2);
    $start2 = new DateTime($start);
    $end2 = new DateTime($end);
    if ($end1 > $start1) {
        $overlap = $end1->diff(min($start2, $end2));
    }
    else {
        $overlap = $start1->diff(min($start2, $end2));
    }
    echo "overlap is " . ($overlap->format('%a') + 1) . " days";
    

    输出

    overlap is 5 days
    

    Demo on 3v4l.org

    更新

    function range_overlap($range1, $range2) {
        list($start, $end) = explode(' - ', $range1);
        $start = new DateTime($start);
        $end =  new DateTime($end);
        $start1 = min($start, $end);
        $end1 = max($start, $end);
        list($start, $end) = explode(' - ', $range2);
        $start = new DateTime($start);
        $end =  new DateTime($end);
        $start2 = min($start, $end);
        $end2 = max($start, $end);
        // check for special cases
        if ($start1 >= $start2 && $end1 <= $end2) {
            // range1 completely contained inside range2
            $overlap = $start1->diff($end1);
        }
        elseif ($start2 >= $start1 && $end2 <= $end1) {
            // range2 completely contained inside range1
            $overlap = $start2->diff($end2);
        }
        elseif ($end2 > $end1) {
            // range1 ends first
            $overlap = $start2->diff($end1);
        }
        else {
            // range2 ends first
            $overlap = $start1->diff($end2);
        }
        // if overlap is < 0 then there is no overlap
        $overlap_days = $overlap->invert ? 0 : ($overlap->format('%a') + 1);
        echo "overlap is $overlap_days days\n";
    }
    

    可以这样称呼:

    range_overlap('2019-01-01 - 2019-01-10', '2019-01-06 - 2019-01-20'); // 5 days
    range_overlap('2019-01-01 - 2019-03-20', '2019-05-06 - 2019-04-20'); // no overlap
    range_overlap('2019-01-10 - 2019-05-20', '2019-01-01 - 2019-05-20'); // 131 days
    range_overlap('2019-01-06 - 2019-01-20', '2019-01-10 - 2019-01-01'); // 5 days
    range_overlap('2019-01-30 - 2019-01-10', '2019-01-12 - 2019-01-15'); // 4 days
    range_overlap('2019-02-01 - 2019-03-20', '2019-01-10 - 2019-02-28'); // 28 days
    

    Demo on 3v4l.org

        2
  •  1
  •   MorganFreeFarm Nevermind23    6 年前

    <?php
    
    $date1 = strtotime('2019-01-01');
    $date2 = strtotime('2019-01-10');
    
    $date3 = strtotime('2019-01-06');
    $date4 = strtotime('2019-01-20');
    
    $dateDiff1 = $date2 - $date1;
    $dateDiff2 = $date4 - $date3;
    
    $finalDiff = $dateDiff2 - $dateDiff1;
    
    echo round($finalDiff / (60 * 60 * 24));
    

    返回:

    有关的详细信息 strtotime()

    注意: 只有在第二次约会总是比第一次约会大的情况下,它才会起作用。你的问题不清楚。

    推荐文章