php - Create H:i value in Carbon from gmdate()

527

Found an issue in a Laravel app with the UK clocks going forward. Everywhere in the app we use Carbon and have Europe/London set as the timezone but found one location that uses gmdate().

The method loops through a range and creates an array of available timeslots in the Hours:Minutes format:

foreach ( range( $lower, $upper, $step ) as $increment ) {
    $increment = gmdate( 'H:i', $increment );
    list( $hour, $minutes ) = explode( ':', $increment );
    $times[] = Carbon::createFromFormat('YmdHi', $day->format('Y') . $day->format('m') . $day->format('d') . $hour . $minutes);
}

I can't quite figure out how gmdate is creating that value from the increments which look along the lines of:

46800  
48600  
50400  
52200  
54000  
55800  
59400 

Is it possible to do the same as the gmdate() method but with Carbon instead?

Thanks!

307

Answer

Solution:

You're passing a unix timestamp togmdate and asking for the date to be returned from that timestamp inH:i format. Unix time is...

[...] a system for describing a point in time, defined as the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970, minus the number of leap seconds that have taken place since then.

So46800 is 1pm on 1970-01-01 which inH:i format is13:00.

Your current code is generating a range of timestamps between$lower timestamp and$upper timestamp incrementing by$step, e.g:

$lower = 0; // The epoch, 1970-01-01 00:00:00
$upper = 3600; // An hour of seconds later, 1970-01-01 01:00:00
$step = 60; // Increment by one minute (60 seconds)

$timestamps = range($lower, $upper, $step);

$timestamps is now an array containing the timestamps of each minute between1970-01-01 00:00:00 and1970-01-01 01:00:00. Then your code is iterating through each of these timestamps and adding the timestamp to an array of$times in the formatYmdHi — theYmdHi format for the time at which I am writing this comment is201803261300.

Carbon has native methods for incrementing time (addSeconds,addMinutes,addHours etc.) so instead of doing all this work to modify and generate times, you can use those methods instead.

You haven't included an example of how you're using the code so I'm going to guess for this example at:

I want every 5 minutes between 2018-03-26 13:00 and 2018-03-26 14:00

Pass in an instance of Carbon, the minutes per slot and the number of slots:

function generateTimeSlots(Carbon $time, integer $minutesPerSlot, integer $numberOfSlots) {
    $slots = range(0, $numberOfSlots);

    foreach ($slots as $k => $slot) {
        $slots[$k] = $time->addMinutes($minutesPerSlot)->format('YmdHi');
    }

    return $slots;
}


$slots = generateTimeSlots(Carbon::now(), 5, 12);

An alternative implementation would be to pass in a start time and an end time, e.g:

function generateTimeslots(Carbon $start, Carbon $finish, integer $minutesPerSlot) {
    $slots = [];

    while ($start <= $finish) {
        $slots[] = $start->addMinutes($minutesPerSlot)->format('YmdHi');
    }

    return $slots;
}


$slots = generateTimeslots(Carbon::now(), Carbon::now()->addHour(), 5);

My preference would be to return an array of Carbon instances (instead of an array ofYmdHi format date strings) but maybe you needYmdHi format timestamps elsewhere in the system.


Although I can't see the rest of your code, I'm guessing also that you could probably just do something like this -- my answers above give a better idea of how you'd approach the problem:

// $day appears to be a Carbon date instance defined elsewhere that represents the first time on the day on which the slots are to be generated

foreach ( range( $lower, $upper, $step ) as $increment ) {
    $times[] = $day->addSeconds($step)->format('YmdHi');
}

People are also looking for solutions to the problem: conditional statements - isset condition not working in php

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.