时间段之间可用

时间:2016-08-28 16:23:34

标签: php datetime

问题在于我似乎无法找到一种方法来确保它不会输出'可用'到已经在$ events变量中使用的时间段。

至于输出示例,您可以看到2015-11-18 10:00:00到2015-11-18 10:30:00它声称插槽可用,但这不应该是可用的,因为有那个时段的一个事件。

以下代码的输出示例:

  

2015-11-18 09:00:00至2015-11-18 09:30:00可用

     

2015-11-18 09:30:00至2015-11-18 10:00:00可用

     

2015-11-18 10:00:00至2015-11-18 10:30:00可用

     

2015-11-18 10:30:00至2015-11-18 11:00:00

     

2015-11-18 11:00:00至2015-11-18 11:30:00

     

2015-11-18 11:30:00至2015-11-18 12:00:00

     

2015-11-18 12:00:00至2015-11-18 12:30:00

     

2015-11-18 12:30:00至2015-11-18 13:00:00可用

     

2015-11-18 13:00:00至2015-11-18 13:30:00可用

     

2015-11-18 13:30:00至2015-11-18 14:00:00可用

     

2015-11-18 14:00:00至2015-11-18 14:30:00可用

     

2015-11-18 14:30:00至2015-11-18 15:00:00

     

2015-11-18 15:00:00至2015-11-18 15:30:00

     

2015-11-18 15:30:00至2015-11-18 16:00:00可用

     

2015-11-18 16:00:00至2015-11-18 16:30:00可用

我使用http://carbon.nesbot.com/作为顶部所需的碳。

<?php
    require 'Carbon.php';
    use Carbon\Carbon;

    $schedule = [
        'start' => '2015-11-18 06:00:00',
        'end' => '2015-11-18 18:00:00',
    ];

    $start = Carbon::instance(new DateTime($schedule['start']));
    $end = Carbon::instance(new DateTime($schedule['end']));

    $minInterval = new DateInterval('PT30M');
    $reqInterval = new DateInterval('PT45M');

    $events = [
        [
            'created_at' => '2015-11-18 10:00:00',
            'updated_at' => '2015-11-18 13:00:00',
        ],
        [
            'created_at' => '2015-11-18 14:00:00',
            'updated_at' => '2015-11-18 16:00:00',
        ],
    ];

    function slotAvailable($from, $to, $events){
        foreach($events as $event){
            $eventStart = new DateTime($event['created_at']);
            $eventEnd = new DateTime($event['updated_at']);

            if(($from > $eventStart && $to < $eventEnd) || ($from < $eventEnd && $to > $eventEnd) || ($from < $eventStart && $to > $eventStart)){
                return false;
            }
        }
        return true;
    }

    foreach(new DatePeriod($start, $minInterval, $end) as $slot){
        $to = $slot->copy()->add($reqInterval);

        echo $slot->toDateTimeString() . ' to ' . $to->toDateTimeString();

        if(slotAvailable($slot, $to, $events)){
            echo ' is available';
        }
        echo '<br />';
        }
    }
?>

2 个答案:

答案 0 :(得分:0)

if中的slotAvailable条件错误:您必须在>=<=中包含间隔的开头和结尾。另外,我认为可以简化:

if ($eventStart <= $from && $eventEnd >= $to) {
    return false;
}

答案 1 :(得分:0)

好像我添加了= if语句的第一部分它修复了大部分内容,如果$ to超过$ schedule [&#39; end&#39;那么我只是在if语句中添加了一个额外的检查。 ],所以它也解决了这个问题。

最终的代码就是这个。

<?php
require 'Carbon.php';
use Carbon\Carbon;

$schedule = [
    'start' => '2015-11-18 06:00:00',
    'end' => '2015-11-18 18:00:00',
];

$start = Carbon::instance(new DateTime($schedule['start']));
$end = Carbon::instance(new DateTime($schedule['end']));

$minInterval = new DateInterval('PT30M');
$reqInterval = new DateInterval('PT45M');

$events = [
    [
        'created_at' => '2015-11-18 10:00:00',
        'updated_at' => '2015-11-18 13:00:00',
    ],
    [
        'created_at' => '2015-11-18 14:00:00',
        'updated_at' => '2015-11-18 16:00:00',
    ],
];

function slotAvailable($from, $to, $events, $workEnd){
    foreach($events as $event){
        $eventStart = new DateTime($event['created_at']);
        $eventEnd = new DateTime($event['updated_at']);

        if(($from >= $eventStart && $to <= $eventEnd) || ($from < $eventEnd && $to > $eventEnd) || ($from < $eventStart && $to > $eventStart) || ($to > $workEnd)){
            return false;
        }
    }
    return true;
}

foreach(new DatePeriod($start, $minInterval, $end) as $slot){
    $to = $slot->copy()->add($reqInterval);
    $workEnd = $schedule['end'];

    echo $slot->toDateTimeString() . ' to ' . $to->toDateTimeString();

    if(slotAvailable($slot, $to, $events, $workEnd)){
        echo ' is available';
    }
    echo '<br />';
    }
}
?>