php - DateInterval в течение полуночной проблемы

Я хочу создать временные интервалы с DateInterval и у меня есть проблема, когда я выбираю конечный период в полночь (00:00).

Все генерируется, если мой конечный период до "23:59".

Вот мой код с входными переменными:

$duration = 30; // duration interval<br>
$start    = '22:00'; // start period<br>
$end      = '02:00'; // end period<br>

function generateTimeSlots($duration, $start, $end) {
    $start         = new DateTime($start);
    $end           = new DateTime($end);
    $interval      = new DateInterval("PT" . $duration . "M");
    $periods = array(); 

    for ($intStart = $start; $intStart < $end; $intStart->add($interval)) {
        $endPeriod = clone $intStart;
        $endPeriod->add($interval); 
        if ($endPeriod > $end) {
            $endPeriod = $end;
        }
        $periods[] = $intStart->format('H:i A');
    }

    return $periods;
}


$duration = 30;
$start    = '22:00'; // 10:00 PM
$end      = '02:00'; // 02:00 AM

print_r( generateTimeSlots($duration, $start, $end) );

Ожидаемый результат:
22:00 вечера
22:30 вечера
23:00
23:30
00:00 вечера
00:30 вечера
01:00 вечера
01:30 вечера
14:00

Не генерирует никаких временных интервалов, если мой конечный период закончился 23:59,

Кто-нибудь знает, в чем должна быть проблема?

2 ответа

Решение

Вам также нужно будет включить информацию о дне в $start а также $end параметры. Если они не упоминаются, DateTime автоматически выберет текущий день, что в вашем примере означает, что ваша дата начала 2018-01-19 22:00:00 и ваша дата окончания 2018-01-19 02:00:00, Так как ваша конечная дата позже вашей конечной даты, ваш for цикл просто никогда не повторяется.


Чтобы обойти это, вы можете либо указать всю дату и время, либо использовать собственное распознавание даты в PHP. Я лично склоняюсь к использованию полных дат, так как считаю, что это делает код более устойчивым, не интерпретируя понятные человеку строки.

// using complete dates
$startDateTime = new DateTime('2018-01-19 22:00:00');
$endDateTime = new DateTime('2018-01-20 02:00:00');

// using human readable strings    
$startDateTime = new DateTime('today 22pm');
$endDateTime = new DateTime('tomorrow 2am');

Сохраняйте это простым и используйте функцию strtotime(). Таким образом, вы имеете дело только с одним целым числом. Тогда на вашей стороне обзора вы можете скрыть все, что вам нужно.

function generateTimeSlots($duration, $start, $end) {

    $periods = array(); 

    for ($intStart = $start; $intStart <= $end; $intStart += $duration) {
        // $endPeriod = clone $intStart;
        // $endPeriod = $end; 
        // if ($endPeriod > $end) {
        //     $endPeriod = $end;
        // }
        $periods[] = date('H:i A', $intStart);
    }

    return $periods;
}


$duration = 1800; #1800 seconds (30 minutes)
$start    = strtotime('Today 22:00'); // 10:00 PM Today
$end      = strtotime('Tomorrow 02:00'); // 02:00 AM Tomorrow

print_r( generateTimeSlots($duration, $start, $end) );
Другие вопросы по тегам