phpdatetimedateintervaltimeslots

php - DateInterval over midnight issue


I want to generate time slots with DateInterval and i have an issue when i select end period over midnight(00:00).

Everything generates if my end period is till "23:59".

Here is my code with input variables:

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

Expected output:
22:00 PM
22:30 PM
23:00 PM
23:30 PM
00:00 PM
00:30 PM
01:00 PM
01:30 PM
02:00 PM

Is not generating any time slots if my end period is over 23:59.

Anyone knows what should be the issue?


Solution

  • You'll need to also include the information about the day in the $start and $end parameters. If they are not mentionned, DateTime will automatically select the current day, which in your example means that your start date is 2018-01-19 22:00:00 and your end date is 2018-01-19 02:00:00. Since your end date is after your end date, your for loop is simply never iterated.


    To get around this you can either specify the entire date and time, or to use PHP's native date recognition. I personally lean towards using complete dates as I find it tends to make the code more robust by not having to interpret human readable strings.

    // 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');