Split a block of time if appointments occur within
There are two types of time_block - free, appointment - each time_block has a start_time and end_time.
Say I have five appointment time_blocks and two free time_blocks.I need to create actual free time_blocks that fill with free time between the appointments, like so:
$appointments = array(
array(
'start_time' => 730,
'end_time' => 830),
array(
'start_time' => 830,
'end_time' => 930),
array(
'start_time' => 945,
'end_time' => 1000),
array(
'start_time' => 1045,
'end_time' =&g开发者_开发技巧t; 1100),
array(
'start_time' => 1130,
'end_time' => 1145)
);
$free_time_blocks = array(
array(
'start_time' => 900,
'end_time' => 1000),
array(
'start_time' => 1030,
'end_time' => 1200)
);
// Result should be
$actual_free_time = array(
array(
'start_time' => 930,
'end_time' => 945
),
array(
'start_time' => 1030,
'end_time' => 1045
),
array(
'start_time' => 1100,
'end_time' => 1130
),
array(
'start_time' => 1145,
'end_time' => 1200
),
)
- sort all the appointments by start time
- free slot start with previous appointment slot end time
- free slot ends with start of next appointment slot
I would suggest you to used timestamps.
Solution by OP.
Problem solved by trial and error. This is ugly, but it works with every situation I've put it through.
<?php
function getAppointmentsInRange($start_time, $end_time){
$appointments = array(
array(
'start_time' => 730,
'end_time' => 830),
array(
'start_time' => 830,
'end_time' => 930),
array(
'start_time' => 945,
'end_time' => 1000),
array(
'start_time' => 1000,
'end_time' => 1035),
array(
'start_time' => 1035,
'end_time' => 1100),
array(
'start_time' => 1105,
'end_time' => 1125),
array(
'start_time' => 1130,
'end_time' => 1230)
);
foreach($appointments as $appointment){
if($appointment['start_time'] < $end_time && $appointment['end_time'] > $start_time){
$return[] = $appointment;
}
}
return $return;
}
function setFreeTime($start_time, $end_time){
echo "Free Time. Start: $start_time, End: $end_time <br/>";
}
$free_time_blocks = array(
array(
'start_time' => 900,
'end_time' => 1000),
array(
'start_time' => 1030,
'end_time' => 1200)
);
foreach($free_time_blocks as $free_time_block){
// Get appointments with any part falling inside the range (eg. starting before but ending after the start)
$appointments = getAppointmentsInRange($free_time_block['start_time'], $free_time_block['end_time']);
$start_time = $free_time_block['start_time'];
$end_time = $free_time_block['start_time'];
$finished = false;
$i = 0;
foreach($appointments as $appointment){
echo "trying...<br/>";
$next = $i + 1;
$prev = $i - 1;
if($appointment['start_time'] <= $free_time_block['start_time']){
echo "case 1 <br/>";
// If appointment starts before ftb then start ftb at end of appointment, and end at start of next appointment or end of ftb
if($appointment['end_time'] < $free_time_block['end_time']){
$start_time = $appointment['end_time'];
}else{
$start_time = $end_time;
break;
}
if(isset($appointments[$next])){
$end_time = $appointments[$next]['start_time'];
}else{
$end_time = $free_time_block['end_time'];
}
}
elseif($appointment['start_time'] > $free_time_block['start_time']){
echo 'case 2 <br/>';
// If appointment starts during ftb then start ftb at last end time
// Start time = previous end time
if($appointment['end_time'] < $free_time_block['end_time']){
if(isset($appointments[$next])){
$end_time = $appointment['start_time'];
}else{
$end_time = $free_time_block['end_time'];
}
}elseif($start_time < $appointment['start_time']){
if(isset($appointments[$prev])){
$start_time = $appointments[$prev]['end_time'];
}
$end_time = $appointment['start_time'];
}else{
break;
}
}
elseif($appointment['start_time'] == $end_time){
echo "case 3 <br/>";
if($appointment['end_time'] < $free_time_block['end_time']){
$start_time = $appointment['start_time'];
}else{
break;
}
if(isset($appointments[$next])){
$end_time = $appointments[$next]['start_time'];
}else{
$end_time = $free_time_block['end_time'];
}
}
if($start_time != $end_time){
setFreeTime($start_time, $end_time);
$start_time = $end_time;
}
$i++;
}
echo "<hr/>";
}
精彩评论