0

私はサービス予約システムを構築しており、いくつかの予約が行われた後に「利用可能な時間帯」のリストを取得したいと考えています.

たとえば、1 日は 24 時間なので、利用可能な時間は

{"begin":"0:00","end":"23:59"}, 

すでにいくつかの予約があります。[{"begin":"9:30","end":"10:30"},{"begin":"12:30","end":"14:00"}]

利用可能な時間のリストを取得したい:[{"begin":"0:0","end":"9:30"},{"begin":"10:30",to:"12:30"},{"begin":"14:00","to":"23:59"}]

そうするためにPHPで利用できるツールはありますか? または、使用できるアルゴリズムはありますか?

更新: 「ルール」を追加することを考えているため、利用できない時間が重複している可能性があります(毎日は10から始まり、月の3日ごとにオフなど)例: [{"begin":0:00,"end":10:00},{"begin":"9:30","end":"10:30"},{"begin":"12:30","end":"14:00"}]

4

3 に答える 3

2

これは私が得たもので、重複する占有期間と範囲外の占有期間を考慮して、期間をうまく分割しています。

function getAvailable(){
    //Container of the results
    $result=[];

    //container of unprocessed period
    $toProcess=[
        "from"=>(new DateTime("2013-8-31 0:0:0")),
        "to"=>(new DateTime("2013-8-31 23:59:59"))
    ];

    //already occupied periods, should be ordered by "from" time
    $unavailable=[
        [
            "from"=>(new DateTime("2013-8-30 5:0:0")),
            "to"=>(new DateTime("2013-8-30 7:0:0"))
        ],
        [
            "from"=>(new DateTime("2013-8-31 5:0:0")),
            "to"=>(new DateTime("2013-8-31 7:0:0"))
        ],
        [
            "from"=>(new DateTime("2013-8-31 6:0:0")),
            "to"=>(new DateTime("2013-8-31 13:0:0"))
        ],
        [
            "from"=>(new DateTime("2013-9-1 20:0:0")),
            "to"=>(new DateTime("2013-9-1 21:0:0"))
        ]
    ];
    foreach($unavailable as $one){
        //divide unprocessed period with a booked period
        $res=divideTime($toProcess,$one);
        //Get an unbooked period
        if($res[0])array_push($result,$res[0]);
        //The rest is for further dividing 
        $toProcess=$res[1];
        //If there's no more periods to divide
        if(!$res[1]){
            break;
        }
    }
    //All the already occupied periods have been processed.
    //The rest is unoccupied.
    if($toProcess){
        array_push($result,$toProcess);
    }
    //Display the result
    exit(var_dump($result));
}
//Divide period $c0 by $c1
function divideTime($c0,$c1){
    //result containers
    $r0=[];
    $r1=[];

    if($c1["from"]<=$c0["from"]){
        $r0=Null;
    }else{
        $r0["from"]=$c0["from"];
        if($c1["from"]>=$c0["to"]){
            $r0["to"]=$c0["to"];
        }else{
            $r0["to"]=$c1["from"];
        }
    }
    if($c1["to"]>=$c0["to"]){
        $r1=Null;
    }else{
        if($c1["to"]<=$c0["from"]){
            $r1["from"]=$c0["from"];
        }else{
            $r1["from"]=$c1["to"];
        }
        $r1["to"]=$c0["to"];
    }
    return [$r0,$r1];
}
于 2013-09-01T11:40:31.927 に答える