hey i have to creating booking system by php/laravel
i take work times from listings like below
08:00 to 13:00
16:00 to 21:00
i want to remove special hour from times and show as slot to user
for example i want to remove 09:30 to 11:00
and 17:00: to 18:00
from the time.
so i want to show this times to user
08:00 to 09:30
11:00 to 13:00
16:00 to 17:00
18:00 to 21:00
$maintimes = [
[
'start' => '08:00',
'end' => '13:00'
],
[
'start' => '16:00',
'end' => '21:00'
],
];
// times to remove from $startTime and $endTime
$removes => [
[
'start' => '09:30',
'end' => '11:00'
],
[
'start' => '17:00',
'end' => '18:00'
]
];
// output must be like this
$output = [
[
'start' => '08:00',
'end' => '09:30'
],
[
'start' => '11:00',
'end' => '13:00'
],
[
'start' => '16:00',
'end' => '17:00'
],
[
'start' => '18:00',
'end' => '21:00'
],
];
/*
logic:
Suppose. Working time starts from 08:00 to 13:00. Then from 13:00 to 16:00 it is rest time. And then again from the site 16:00 to 21:00 working time.
Therefore, some people take turns during the periods when it is time to work
*/
i research for this problem but i cant find any solution to fix this
CodePudding user response:
Sort the
removes
array according toend
in an ascending manner. Note that no 2 subarrays can have the sameend
value as it doesn't make sense for the splits.Create valid ranges to be dealt with to include valid start times and end times.
Previous one's end time is new ones start time and so on and so forth for the ranges to respect the gaps provided.
For splitting, if only
13:00
or16:00
falls within the range, split them, else use the range as is. If any range's start time is above16:00
, include a new range16:00-start_time
only once to accommodate the gap.
Snippet:
<?php
function getMinutes($t){
$t = explode(":", $t);
return intval($t[0]) * 60 intval($t[1]);
}
function getSplits($removes, $startTime, $endTime, $breakStart, $breakEnd){
if($startTime === $endTime) return [];
usort($removes, function($r1, $r2){
return getMinutes($r1['end']) <=> getMinutes($r2['end']);
});
$ranges = [];
foreach($removes as $r){
$ranges[] = [$startTime, $r['start']];
$startTime = $r['end'];
}
$ranges[] = [$startTime, $endTime]; // include the last range as well
$breakStartMinutes = getMinutes($breakStart);
$breakEndMinutes = getMinutes($breakEnd);
$splits = [];
foreach($ranges as $rr){
$break_split = false;
$startMinutes = getMinutes($rr[0]);
$endMinutes = getMinutes($rr[1]);
if($breakStartMinutes > $startMinutes && $breakStartMinutes < $endMinutes){
$break_split = true;
$splits[] = [$rr[0], $breakStart];
}
if($breakEndMinutes > $startMinutes && $breakEndMinutes < $endMinutes){
$break_split = true;
$breakEndMinutes = 1441; // since we need to consume this only once
$splits[] = [$breakEnd, $rr[1]];
}else if($breakEndMinutes < $startMinutes){
$splits[] = [$breakEnd, $rr[0]];
$breakEndMinutes = 1441; // since we need to consume this only once
}
if($break_split === false){
$splits[] = $rr;
}
}
return $splits;
}
print_r(getSplits($removes, '08:00', '21:00', '13:00', '16:00'));