我如何检测两个时间段的非重叠?

时间:2012-11-22 12:12:07

标签: php algorithm

我有一个用户输入表单,用户在(YYYY-mm-dd)格式中选择日期,以(H:i)和结束时间以(H:i)格式开始时间,或假设我有三个变量具有以下值。

$date      = '2012-11-22';
$startTime = '1:00';
$endTime   = '4:00';

我现在必须将这些值与现有的值数组进行比较。我现有的数组看起来像这样。

Array
(
    [0] => Array
        (
            [id] => 1
            [start_datetime] => 2012-11-22 02:30:00
            [end_datetime] => 2012-11-22 05:00:00
        )

    [1] => Array
        (
            [id] => 2
            [start_datetime] => 2012-11-22 00:00:00
            [end_datetime] => 2012-11-22 02:30:00
        )

    [2] => Array
        (
            [id] => 3
            [start_datetime] => 2012-11-22 05:00:00
            [end_datetime] => 2012-11-22 08:00:00
        )

    [3] => Array
        (
            [id] => 4
            [start_datetime] => 2012-11-22 08:00:00
            [end_datetime] => 2012-11-22 11:00:00
        )

    [4] => Array
        (
            [id] => 5
            [start_datetime] => 2012-11-22 11:00:00
            [end_datetime] => 2012-11-22 17:00:00
        )

)

我必须检查所选的用户输入 [date,startTime和endTime] 是否已在给定的时隙数组中预订了任何插槽。从我看到的解决方案是首先拆分和匹配日期,如果它与日期匹配,那么时间需要相应地匹配。我很困惑如何使用它。我希望从你们那里得到一些简单的解决方案:)

谢谢。

更新 我试着这样做。

$arenaSurfaceBooking = array(
    array(
        'id' => 1,
        'start_datetime' => '2012-11-22 02:30:00',
        'end_datetime' => '2012-11-22 05:00:00',
    ),
    array(
        'id' => 2,
        'start_datetime' => '2012-11-22 00:00:00',
        'end_datetime' => '2012-11-22 02:30:00',
    ),
    array(
        'id' => 3,
        'start_datetime' => '2012-11-22 05:00:00',
        'end_datetime' => '2012-11-22 08:00:00',
    ),
    array(
        'id' => 4,
        'start_datetime' => '2012-11-22 08:00:00',
        'end_datetime' => '2012-11-22 11:00:00',
    ),
    array(
        'id' => 5,
        'start_datetime' => '2012-11-22 11:00:00',
        'end_datetime' => '2012-11-22 17:00:00',
    )
);

foreach($arenaSurfaceBooking as $booking) {
    $bookedDateTimestamp = strtotime(date('Y-m-d', strtotime($booking['start_datetime'])));
    $inputDateTimestamp  = strtotime($context['date']);
    $bookedStartTime     = strtotime(date('H:i', strtotime($booking['start_datetime'])));
    $bookedEndTime       = strtotime(date('H:i', strtotime($booking['end_datetime'])));
    $userStartTime       = strtotime(date('H:i', strtotime($context['start_datetime'])));
    $userEndTime         = strtotime(date('H:i', strtotime($context['end_datetime'])));
    if( $bookedDateTimestamp == $inputDateTimestamp) {
        if( $userEndTime <= $bookedStartTime || $userStartTime >= $bookedEndTime) {
            echo 'i am booked';
        }
    }
}

它不起作用。

4 个答案:

答案 0 :(得分:3)

假设用户日期/时间的格式如下:

$date      = '2012-11-22';
$startTime = '01:00'; // note the extra '0' in front
$endTime   = '04:00';

$userStartTime = "$date $startTime";
$userEndTime = "$date $endTime";

以这种方式查找重叠:

$overlaps = 0;
foreach ($block as $block) {
    if ($userStartTime < $block['end_datetime'] && $userEndTime > $block['start_datetime']) {
        ++$overlaps;
    }
}

// if $overlaps > 0 -> there's a booking in the way

这基本上采取了这样的非重叠条件:

$userEndTime <= $block['start_datetime'] || $userStartTime >= $block['end_datetime']

简单地交换条件。

这也很容易写入SQL,以减少数据库和应用程序之间的网络开销。

答案 1 :(得分:1)

由于现有数组来自SQL查询:

$date      = '2012-11-22';
$startTime = '1:00'; 
$endTime   = '4:00';

if(strlen($startTime==4)){$startTime="0".$startTime;}
if(strlen($endTime==4)){$endTime="0".$startTime;}

$query="SELECT id FROM table WHERE start_datetime='$date $startTime:00' OR end_datetime='$date $endtimeTime:00'";

如果查询返回了某些内容,则返回的id会将其预订!

如果您想知道任何数据库信息是否与两个日期时间匹配,只需将OR替换为AND

如果您想知道用户时间段是否在数据库的任何条目之间:

$query="SELECT id FROM table WHERE (start_datetime>='$date $startTime:00' AND start_datetime<='$date $endTime:00') OR (end_datetime<='$date $starttimeTime:00' AND end_datetime>='$date $endtimeTime:00') OR (start_datetime<='$date $startTime:00' AND end_datetime>='$date $starttimeTime:00')";

答案 2 :(得分:1)

检查出来......并根据您的要求进行修改以匹配所有现有时间...我只为您匹配一个......

$date = '2012-11-22';
$startTime = '2:30';
$endTime = '4:00';

$existing[] = 
        array
        (
            'id' => 1,
            'start_datetime' => '2012-11-22 02:30:00',
            'end_datetime' => '2012-11-22 05:00:00'
        );

$UserStartTime = strtotime($date." ".$startTime);
$UserEndTime = strtotime($date." ".$endTime);

$ExistingStartTime = strtotime($existing[0]['start_datetime']);
$ExistingEndTime = strtotime($existing[0]['end_datetime']);

if($UserStartTime >= $ExistingStartTime && $UserEndTime <= $ExistingEndTime)
{
    echo "BOOKED";
}
else
{
    echo "NOT BOOKED";
}

答案 3 :(得分:0)

这可能对您有所帮助

$date = '2012-11-22';
$startTime= '1:00:00'; // padded two zero
$endTime = '4:00:00'; // padded two zero

$start_datetime = $date. " ".(strlen(intval(substr($startTime,0,2))) > 1 ? $startTime : "0".$startTime);

$end_datetime = $date. " ".(strlen(intval(substr($endTime,0,2))) > 1? $endTime : "0".$endTime);
for($i = 0;$i<count($your_array);$i++)
{
    if($your_array[$i]['start_datetime'] == $start_datetime)
    {
        // Start date Found
    }
    if($your_array[$i]['end_datetime'] == $end_datetime)
    {
        // Start end Found
    }
}