包括最后一个日期在内的两个日期之间相隔 20 天

Periods of 20 days between two dates including the last one

我需要以 20 天为间隔遍历两个日期之间的天数,包括最后一个日期。例如,在日期 2019/01/01 和 2019/01/27 之间应该 return 以下范围:

2019-01-01  =>  2019-01-20
2019-01-21  =>  2019-02-09
2019-02-10  =>  2019-02-27

我试过这个代码:

$start = new DateTime('2019-01-01');
$end = new DateTime('2019-02-27');
$interval = new DateInterval('P20D');
$period = new DatePeriod($start, $interval, $end, DatePeriod::EXCLUDE_START_DATE);

$from = $start->format('Y-m-d');
foreach ($period as $day) {
    $to = $day->format('Y-m-d');

    echo $from . '  =>  ' . $to . '<br>';

    $from = $day->modify('+1 day')->format('Y-m-d');
}

输出:

2019-01-01  =>  2019-01-21
2019-01-22  =>  2019-02-10

这段代码有两个问题,不包括上一期(不再包含20天)和提前一天。我该如何解决这些问题?

这可能更简单,只需将 $start 值增加 $interval 直到它大于 $end 值。请注意,间隔需要 19 天才能构成 20 天(包括开始和结束)期间。

$start = new DateTime('2019-01-01');
$end = new DateTime('2019-02-27');
$interval = new DateInterval('P19D');
while ($start < $end) {
    echo $start->format('Y-m-d') . ' => ';
    $start->add($interval);
    echo min($start, $end)->format('Y-m-d') . "\n";
    $start->add(new DateInterval('P1D'));
}

输出:

2019-01-01 => 2019-01-20 
2019-01-21 => 2019-02-09
2019-02-10 => 2019-02-27

Demo on 3v4l.org

更新

这是一个也跳过周末的代码版本:

$start = new DateTime('2019-01-01');
$end = new DateTime('2019-02-27');
$interval = new DateInterval('P1D');
$days = 19;
while ($start < $end) {
    echo $start->format('Y-m-d') . ' => ';
    for ($i = 0; $i < $days; ) {
        $start->add($interval);
        $day_of_week = $start->format('N');
        if ($day_of_week == 6 || $day_of_week == 7) continue;
        $i++;
    }
    echo min($start, $end)->format('Y-m-d') . "\n";
    $start->add($interval);
}

Demo on 3v4l.org