开发者

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
    ),
)


  1. sort all the appointments by start time
  2. free slot start with previous appointment slot end time
  3. 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/>";
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜