PHP - Auto calculate time intervals in laravel - php

I have three columns in my table start_time, end_time and interval.
The start_time and end_time stores time like 22:00 and 24:00 respectively and the interval store time like 00:15:00.
What I want to do is auto calculate intervals like 22:00 - 22:15, 22:15 - 22:30 and so on till 23:45 - 24:00.
And if the interval is 00:30:00 the intervals should be 22:00 - 22:30.
I'm new to laravel and stackoverflow so sorry for any inconvenience.

You can use for loop together with strtotime.
$start= "20:00";
$end = "22:00";
$int = 15;
$int *= 60;
$start = strtotime($start);
$end = strtotime($end);
for($i = $start; $i < $end;){
$res[] = date("H:i", $i) . "-" . date("H:i", $i + $int);
$i += $int;
}
var_dump($res);
https://3v4l.org/I2lUS
EDIT; didn't notice you wanted a different output

<?php
$begin = new DateTimeImmutable('19:00');
$end = new DateTimeImmutable('24:30'); // Last 30 min will not be inclued (see output)
$interval = new DateInterval('PT30M'); // Interval 30 min
$daterange = new DatePeriod($begin, $interval ,$end);
$ranges = [];
foreach ($daterange as $key => $range) {
$ranges[$key] = $range->format('H:i');
if($key>0) {
$ranges[$key-1] .= ' - '.$range->format('H:i');
}
}
array_pop($ranges);
print_r($ranges);
Output:
Array
(
[0] => 19:00 - 19:30
[1] => 19:30 - 20:00
[2] => 20:00 - 20:30
[3] => 20:30 - 21:00
[4] => 21:00 - 21:30
[5] => 21:30 - 22:00
[6] => 22:00 - 22:30
[7] => 22:30 - 23:00
[8] => 23:00 - 23:30
[9] => 23:30 - 00:00
)

Related

PHP Create Timeslots with break hours

I made this Code to make time slots:
$duration = 60;
$cleanup = 0;
$start = "10:00";
$end = '24:00';
function timeslots($duration, $cleanup, $start, $end)
{
$start = new DateTime($start);
$end = new DateTime($end);
$interval = new DateInterval('PT' . $duration . 'M');
$cleanupinterval = new DateInterval('PT' . $cleanup . 'M');
$slots = array();
for ($intStart = $start; $intStart < $end; $intStart->add($interval)->add($cleanupinterval)) {
$endperiod = clone $intStart;
$endperiod->add($interval);
if ($endperiod > $end) {
break;
}
$slots[] = $intStart->format('H:iA') . '-' . $endperiod->format('H:iA');
}
return $slots;
}
?>
above code get results like this:
10:00 AM - 11:00 AM.
11:00 AM - 12:00 PM.
what I'm trying to do is something like this:
12:00 AM - 01:00 AM
01:00 AM - 02:00 AM
3. 10:00 AM - 11:00 AM
11:00 AM - 12:00 PM.
So I'm trying to make break time from 02:00 AM to 10:00 AM
so the day will start like:
12:00 AM To 02:00 AM and take breake hours from 02:00 AM To 10:00 AM.
Thanks in advance.
I Hope this will help You:
$duration = 60;
$cleanup = 0;
$start = "00:00";
$end = '24:00';
$break_start = '02:00'; // break start
$break_end = '10:00'; // break end
function timeslots($duration, $cleanup, $start, $end, $break_start, $break_end)
{
$start = new DateTime($start);
$end = new DateTime($end);
$break_start = new DateTime($break_start);
$break_end = new DateTime($break_end);
$interval = new DateInterval('PT' . $duration . 'M');
$cleanupinterval = new DateInterval('PT' . $cleanup . 'M');
$slots = array();
for ($intStart = $start; $intStart < $end; $intStart->add($interval)->add($cleanupinterval)) {
$endperiod = clone $intStart;
$endperiod->add($interval);
if (strtotime($break_start->format('H:i A')) < strtotime($endperiod->format('H:i A')) && strtotime($endperiod->format('H:i A')) < strtotime($break_end->format('H:i A'))) {
$endperiod = $break_start;
$slots[] = $intStart->format('H:i A') . ' - ' . $endperiod->format('H:i A');
$intStart = $break_end;
$endperiod = $break_end;
$intStart->sub($interval);
}
$slots[] = $intStart->format('H:iA') . '-' . $endperiod->format('H:iA');
}
return $slots;
}
and
$time_slots = timeslots($duration, $cleanup, $start, $end, $break_start, $break_end);
echo '<pre>';
print_r($time_slots);
echo '<pre>';
the result will be :
Array
(
[0] => 00:00 AM - 01:00 AM
[1] => 01:00 AM - 02:00 AM
[2] => 02:00 AM - 02:00 AM
[3] => 10:00 AM - 11:00 AM
[4] => 11:00 AM - 12:00 PM
[5] => 12:00 PM - 13:00 PM
[6] => 13:00 PM - 14:00 PM
[7] => 14:00 PM - 15:00 PM
[8] => 15:00 PM - 16:00 PM
[9] => 16:00 PM - 17:00 PM
[10] => 17:00 PM - 18:00 PM
[11] => 18:00 PM - 19:00 PM
[12] => 19:00 PM - 20:00 PM
[13] => 20:00 PM - 21:00 PM
[14] => 21:00 PM - 22:00 PM
[15] => 22:00 PM - 23:00 PM
[16] => 23:00 PM - 00:00 AM
)
Something like that?
function show_time_slots($start_time, $end_time, $duration, $break){
$time_slots = array();
$start_time = strtotime($start_time);
$end_time = strtotime($end_time);
$add_mins = $duration * 60;
while ($start_time <= $end_time)
{
$time_slots[] = date("H:i", $start_time);
$start_time += $add_mins;
}
$time_slots = array_diff( $time_slots, $break );
return $time_slots;
}
And
$start_time = '00:00';
$end_time = '23:00';
$duration = '60';
$break = ['03:00', '04:00', '05:00', '06:00', '07:00', '08:00', '09:00'];
$time_slots = show_time_slots($start_time, $end_time, $duration, $break);
echo '<pre>';
print_r($time_slots);
echo '</pre>';
Return
Array
(
[0] => 00:00
[1] => 01:00
[2] => 02:00
[10] => 10:00
[11] => 11:00
[12] => 12:00
[13] => 13:00
[14] => 14:00
[15] => 15:00
[16] => 16:00
[17] => 17:00
[18] => 18:00
[19] => 19:00
[20] => 20:00
[21] => 21:00
[22] => 22:00
[23] => 23:00
)
I tried to make a function that will help you to make all possible slots. the function will take the start_time and end_time and based on the duration(in minutes) it will make the slots and it will not create a slot during break time also you can add clean-up or refresh time after every slot if you want that argument will take time in minutes.
I also see that the approved answer of #Khaled Mostafa where copied by a lot of bloggers and they just copy and paste his answer in the same requirement as mine but it didn't help me in this kind of my requirement so after spending some hours I have found this solution.
function show_time_slots($start_time, $end_time, $duration, $break_start, $break_end, $cleanup = 0){
$time_slots = array();
$start_time = strtotime($start_time);
$end_time = strtotime($end_time);
$break_start = strtotime($break_start);
$break_end = strtotime($break_end);
$add_mins = ($duration + $cleanup) * 60;
while ($start_time <= $end_time)
{
$startSlotTime = date("h:i A", $start_time); // for 24 format date("H:i", $start_time);
$slotEndTime = $start_time + $add_mins;
$endSlotTime = date("h:i A", $slotEndTime); // for 24 format date("H:i", $slotEndTime);
// $sachin = strtotime($startSlotTime);
if($slotEndTime <= $end_time){
if(
($start_time > $break_start && $start_time < $break_end ) || ($slotEndTime > $break_start && $slotEndTime < $break_end )
|| ($break_start > $start_time && $break_start < $slotEndTime) || ($break_end > $start_time && $break_end < $slotEndTime)
){
$start_time = $break_end;
}else{
$time_slots[] = $startSlotTime . "-" . $endSlotTime;
$start_time += $add_mins;
}
}else{
$start_time += $add_mins;
}
}
// $time_slots = array_diff( $time_slots, $break );
return $time_slots;
}
$duration = 180; // minutes
$cleanup = 0; // minutes
$start_time = "10:00";
$end_time = '23:00';
$break_start = '16:00'; // break start
$break_end = '16:30'; // break end
$time_slots = show_time_slots($start_time, $end_time, $duration, $break_start, $break_end, $cleanup);
echo '<pre>';
print_r($time_slots);
echo '</pre>';
Out Put
Array
(
[0] => 10:00 AM-01:00 PM
[1] => 01:00 PM-04:00 PM
[2] => 04:30 PM-07:30 PM
[3] => 07:30 PM-10:30 PM
)
I am getting solution for multiple break too. pleas check my answer and tell me if anything wrong with this. no doubt I am using code of #Sachin Sarola I just changes few line as I required for multiple break slot.
function show_time_slots($start_time, $end_time, $duration, $break_arr, $cleanup = 0){
$time_slots = array();
$start_time = strtotime($start_time);
$end_time = strtotime($end_time);
$add_mins = ($duration + $cleanup) * 60;
while ($start_time <= $end_time)
{
$startSlotTime = date("h:i A", $start_time); // for 24 format date("H:i", $start_time);
$slotEndTime = $start_time + $add_mins;
$endSlotTime = date("h:i A", $slotEndTime); // for 24 format date("H:i", $slotEndTime);
if($slotEndTime <= $end_time){
$is_break = false;
$last_break_end_time = null;
foreach($break_arr as $key => $break){
$break_start = strtotime($break['break_start']);
$break_end = strtotime($break['break_end']);
if(
($start_time > $break_start && $start_time < $break_end ) || ($slotEndTime > $break_start && $slotEndTime < $break_end )
|| ($break_start > $start_time && $break_start < $slotEndTime) || ($break_end > $start_time && $break_end < $slotEndTime)
){
$is_break = true;
$last_break_end_time = $break_end;
break;
}
}
if($is_break && $last_break_end_time){
$start_time = $last_break_end_time;
}else{
$time_slots[] = $startSlotTime . "-" . $endSlotTime;
$start_time += $add_mins;
}
}else{
$start_time += $add_mins;
}
}
// $time_slots = array_diff( $time_slots, $break );
return $time_slots;
}
$duration = 180;
$cleanup = 0;
$start_time = "10:00";
$end_time = '23:00';
$break_start = '16:00'; // break start
$break_end = '16:30'; // break end
$break_arr = [
['break_start' => '16:00', 'break_end' => '16:30'],
['break_start' => '19:30', 'break_end' => '20:00']
];
$time_slots = show_time_slots($start_time, $end_time, $duration, $break_arr, $cleanup);
echo '<pre>';
print_r($time_slots);
echo '</pre>';
Out Put
Array
(
[0] => 10:00 AM-01:00 PM
[1] => 01:00 PM-04:00 PM
[2] => 04:30 PM-07:30 PM
[3] => 08:00 PM-11:00 PM
)

Need 10 intervals between two time stamps

I need 10 intervals between two time stamps. Please find the example below.
start_date: 2021-01-15 15:45:00
end_date: 2021-01-15 18:00:00
I need result like below based on count of intervals. I can change 5 interval or 7 intervals but the time need to calculate automatically based on intervals
15:45:00
16:00:00
16:15:00
16:30:00
16:45:00
17:00:00
17:15:00
17:30:00
17:45:00
18:00:00
function SplitTime($StartTime, $EndTime, $Duration="60"){
$ReturnArray = array ();// Define output
$StartTime = strtotime ($StartTime); //Get Timestamp
$EndTime = strtotime ($EndTime); //Get Timestamp
$AddMins = $Duration * 60;
while ($StartTime <= $EndTime) //Run loop
{
$ReturnArray[] = date ("G:i:s", $StartTime);
$StartTime += $AddMins; //Endtime check
}
return $ReturnArray;
}
You can use a division of the number of seconds between the 2 dates :
function SplitTime($StartTime, $EndTime, $Division = 10){
$ReturnArray = array (); // Define output
$StartTime = strtotime ($StartTime); //Get Timestamp
$EndTime = strtotime ($EndTime); //Get Timestamp
//Time diff
$diff = $EndTime - $StartTime;
// number of seconds by "step"
$num = $diff / ($Division - 1);
for ($inum = 0; $inum < $Division; $inum++)
{
$ReturnArray[] = date ("G:i:s", $StartTime + $num * $inum);
}
return $ReturnArray;
}
$dates = SplitTime("2021-01-15 15:45:00", "2021-01-15 18:00:00");
print_r($dates);
Outputs :
Array
(
[0] => 15:45:00
[1] => 16:00:00
[2] => 16:15:00
[3] => 16:30:00
[4] => 16:45:00
[5] => 17:00:00
[6] => 17:15:00
[7] => 17:30:00
[8] => 17:45:00
[9] => 18:00:00
)
See online demo

Convert times into interval array

If I have the following variables:
$starttime = '09:00'; // Start time
$endtime = '21:00'; // End time
$interval = '30'; // In minutes
What would be the best way to generate the following array?
[
"09:00" => "09:30",
"09:30" => "10:00",
"10:00" => "10:30",
"10:30" => "11:00",
...
"20:00" => "20:30",
"20:30" => "21:00"
]
There are some similar topics that show how to array time intervals but none of them have been able to show my specific issue.
Using DateTime class with DateInterval you can achieve what you need.
DateTime - https://www.php.net/manual/pt_BR/class.datetime.php
DateInterval - https://www.php.net/manual/pt_BR/class.dateinterval.php
<?php
$startTime = DateTime::createFromFormat("H:i", "09:00");
$endTime = DateTime::createFromFormat("H:i", "22:00");
$interval = DateInterval::createFromDateString("30 minutes");
$result = [];
while ($startTime <= $endTime) {
$result[$startTime->format('H:i')] = $startTime->add($interval)->format('H:i');
}
echo print_r($result, true);
You can add 30 min to by this command :
$time=date("H:i", strtotime('+30 minutes', $time));
For your problem can set a while loop(for check condition).
Then set and array and set index to :
date("H:i", strtotime('+'.$interval.' minutes', $time));`
And set value to :
date("H:i", strtotime('+'.(2*$interval).'minutes', $time));
Then update $time.
You should just be able to use a 'while' loop to increment a timestamp until $endtime is reached. Here's a working example:
$starttime = '09:00'; // Start time
$endtime = '21:00'; // End time
$interval = '30'; // In minutes
$result = [];
$last = strtotime($starttime);
$endtimestamp = strtotime($endtime);
while ($last < $endtimestamp) {
$next = strtotime("+{$interval} minutes", $last);
$result[date('H:i', $last)] = date('H:i', $next);
$last = $next;
}
var_dump($result);
Can be done using DateTime and DateInterval
<?php
date_default_timezone_set('UTC');
// define start/end
$begin = DateTime::createFromFormat('H:i', '09:00');
$end = DateTime::createFromFormat('H:i', '21:00');
// define the interval
$interval = new DateInterval('PT30M');
$interval->invert = 1;
// get date range
$daterange = new DatePeriod($begin, $interval, $end);
// loop and build your array
$range = [];
foreach ($daterange as $date){
$range[$date->format("H:i")] = $date->sub($interval)->format("H:i");
}
print_r($range);
Result:
Array
(
[09:00] => 09:30
[09:30] => 10:00
[10:00] => 10:30
[10:30] => 11:00
[11:00] => 11:30
[11:30] => 12:00
[12:00] => 12:30
[12:30] => 13:00
[13:00] => 13:30
[13:30] => 14:00
[14:00] => 14:30
[14:30] => 15:00
[15:00] => 15:30
[15:30] => 16:00
[16:00] => 16:30
[16:30] => 17:00
[17:00] => 17:30
[17:30] => 18:00
[18:00] => 18:30
[18:30] => 19:00
[19:00] => 19:30
[19:30] => 20:00
[20:00] => 20:30
[20:30] => 21:00
)
https://3v4l.org/FqViY

Php get hours difference ranges from midnight fails

Am trying to get hours from midnight from the current time
that is suppose now it's 02:34 then I expect to get
02:34 - 02:00,
01:00 - 02:00,
00:00 - 01:00
as an array
so I have tried
function getFromMidnight(){
$durations = [];
$currentTime = strtotime("now");
$iStartOfHour = $currentTime - ($currentTime % 3600);
$midnight = strtotime('today midnight');
$hours = floor(($iStartOfHour - $midnight)/3600);
array_push($durations,["from"=>$currentTime, "to"=>$iStartOfHour]);
if(floor(($iStartOfHour - $midnight)/3600) > 0){
for ($val = 1;$val <= $hours;$val++){
$newval = $val +=1;
array_push($durations, ["from"=>strtotime('- '.$val.' hours',$iStartOfHour),"to"=>strtotime('- '.$newval.' hours',$iStartOfHour)]);
}
}
return $durations;
}
For the first array has the correct durations e.g. from the above example 02:34-02:00 but the next arrays are messed up giving me wrong values with constant timestamps eg: 01:00 - 01:00
I suspect its my for loop with an error, what could be wrong?
I would not use that code, instead of working things out just use DateInterval inverted and work backwards. Then sub() the hour in the loop to get the offset.
<?php
date_default_timezone_set('UTC');
$begin = new DateTime('today midnight');
$end = new DateTime();
$interval = new DateInterval('PT60M');
$interval->invert = 1;
$daterange = new DatePeriod($begin, $interval, $end);
$range = [];
foreach ($daterange as $date){
$range[] = [
'from' => $date->format("H:i"),
'to' => $date->sub($interval)->format("H:i")
];
}
print_r($range);
https://3v4l.org/BMSbI
Result:
Array
(
[0] => Array
(
[from] => 00:00
[to] => 01:00
)
[1] => Array
(
[from] => 01:00
[to] => 02:00
)
[2] => Array
(
[from] => 02:00
[to] => 03:00
)
[3] => Array
(
[from] => 03:00
[to] => 04:00
)
)

Monthly recur with PHP

I have a two dates. start date and end date. Using those dates i have to find recur dates.
example:
(1) start date = 2014-01-01
end date = 2014-05-01
expected output:
2014-01-01
2014-02-01
2014-03-01
2014-04-01
2014-05-01
(2) start date = 2014-01-31
end date = 2014-05-01
expected output:
2014-01-31
2014-02-28
2014-03-31
2014-04-30
means do not skip month, if month is skip in that case use last day of month. how to achive this thing?
I am using following code but i added 1 month in date so it skip the month:
$start = strtotime($start_date);
$end = strtotime($end_date);
$total_dates = array();
for($i=$start; $i<=$end;)
{
$date = date('Y-m-d',$start);
if($i>$start)
{
$next_date = date('Y-m-d',strtotime($date . "+1 month"));
$start = strtotime($next_date);
}
else
{
$next_date = date('Y-m-d',$start);
}
$total_dates[] = $next_date;
$date1 = new DateTime($date);
$newdate = date('Y-m-d',strtotime($date . "+1 month"));
$date2 = new DateTime($newdate);
$diff = $date2->diff($date1)->format("%a");
/* Find diff between two dates */
$i = (($i*1)+(86400*$diff)); //seconds in 1month
}
print_r($total_dates);
so in short:
start date = 2014-01-01
end date = 2014-05-01
expected output:
2014-01-31
2014-02-28
2014-03-31
2014-04-30
current output:
2014-01-31
2015-03-03
2015-04-03
check this
$start_date = '2015-01-31';
$end_date = '2016-06-01';
$start_date=date('Y-m-1', strtotime($start_date));
$diff = abs(strtotime($end_date) - strtotime($start_date));
$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
if($years>0){$loop=$years*12+$months;}else{$loop=$months;}
for($i=1; $i<=$loop+1;$i++)
{
$total_dates[] =$a= date('Y-m-t', strtotime($start_date));
$start_date = date('Y-m-d',strtotime($start_date . "+1 month"));
}
print_r($total_dates);
//output Array ( [0] => 2015-01-31 [1] => 2015-02-28 [2] => 2015-03-31 [3] => 2015-04-30 [4] => 2015-05-31 [5] => 2015-06-30 [6] => 2015-07-31 [7] => 2015-08-31 [8] => 2015-09-30 [9] => 2015-10-31 [10] => 2015-11-30 [11] => 2015-12-31 [12] => 2016-01-31 [13] => 2016-02-29 [14] => 2016-03-31 [15] => 2016-04-30 [16] => 2016-05-31 [17] => 2016-06-30 )
Try this...
<?php
$start_date = "2014-01-01";
$end_date = "2014-05-01";
$d = date_parse_from_format("Y-m-d", $start_date);
$start= $d["month"];
$d1 = date_parse_from_format("Y-m-d", $end_date);
$end= $d1["month"];
$array=array();
$array[]=date('Y-m-t', strtotime($start_date));
for($i=$start;$i<$end;$i++)
{
$str=explode("-",$start_date);
$mon=$str[1]+$i;
$newdate=$str[0]."-".$mon."-".$str[2];
$array[]=date('Y-m-t', strtotime($newdate));
}
print_r($array);
output:
2014-01-31
2014-02-28
2014-03-31
2014-04-30
2014-05-31
Use PHP date/time functions with relative interval formats:
http://php.net/manual/en/datetime.formats.relative.php
You can provide intervals like "last day of next month" or "last sat of July 2008", adding/subtracting this interval from the referenced date.

Categories