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

Php 如何检测两个时间段的非重叠?,php,algorithm,Php,Algorithm,我有一个用户输入表单,其中用户选择YYYY-mm-dd格式的日期,选择H:I格式的开始时间,选择H:I格式的结束时间,或者假设我有三个具有以下值的变量 $date = '2012-11-22'; $startTime = '1:00'; $endTime = '4:00'; 我现在必须将这个值与现有的值数组进行比较。我现有的数组如下所示 Array ( [0] => Array ( [id] => 1

我有一个用户输入表单,其中用户选择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';
        }
    }
}

它不工作。

因为现有数组来自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')";

看看这个。。。并根据您的要求修改它以匹配所有现有时间。。。我只为你配了一个

$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";
}
这可能对你有帮助

$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
    }
}

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

$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,以减少数据库和应用程序之间的网络开销。

我希望我没有使问题复杂化,如果您不明白,请告诉我,我会尝试以更好的方式解释。您尝试了什么/如何尝试?@PLB我尝试过拆分日期并首先比较日期。我不知道应该如何比较时间。首先,你应该使用strotime来进行简单的比较。@Jack:没有必要。这种格式在字符串形式上是可直接比较的。仍然存在问题,如果所选的starttime为1,endtime为5,并且在数据库中我有2到4个存储,那么它在逻辑上仍然应该返回true。是的,我编辑了最后一个查询,它应该可以使用该输入。然后我不介意使用mysql方式,我想我会就此提出另一个问题。谢谢jack顺便说一句:如果我在时间之前没有零会有问题吗?@Ibrahimazharmar也许MySQL可以在与DATETIME比较时处理丢失的零,但是,当您像我的回答中那样将日期作为字符串进行比较时,您需要所有的日期/时间格式都相同。我是否可以使用strotime将日期时间转换为unix时间戳,然后进行比较?“我一直在尝试这样做。@Ibrahimazharmar如果您的数据库字段是DATETIME,您应该先尝试;否则:日期'Y-m-d H:i:s',strotime$您的时髦日期。