2012-06-19 45 views
5

我想查看从db读取的时间是否与用户提供的时间重叠。检查两次是否重叠

我的数据库看起来是这样的:

----------------------------------------------- 
|organiser|meeting_start|meeting_end|boardroom| 
----------------------------------------------- 
| John Doe| 1340193600 | 1340195400| big  | 
----------------------------------------------- 

我的代码如下所示:

date_default_timezone_set('Africa/Johannesburg'); 
$from = strtotime($_GET['meeting_date'] . ' ' . $_GET['meeting_start']); 
$to = strtotime($_GET['meeting_date'] . ' ' . $_GET['meeting_end']); 
$another_meeting = false; 
$meeting_date = strtotime($_GET['meeting_date']); 
$meeting_next = $meeting_date + 86400; 

$result = mysql_query("SELECT meeting_start, meeting_end FROM admin_boardroom_booking WHERE boardroom = '" . $_GET['boardroom'] . "' AND meeting_start >= '" . $meeting_date . "' AND meeting_end < '" . $meeting_next . "'")or die(mysql_error()); 
while($row = mysql_fetch_array($result)) { 
    $from_compare = $row['meeting_start']; 
    $to_compare = $row['meeting_end']; 

    $intersect = min($to, $to_compare) - max($from, $from_compare); 
    if ($intersect < 0) 
     $intersect = 0; 

    $overlap = $intersect/3600; 
    if ($overlap <= 0) { 
     $another_meeting = true; 
     break; 
    } 
} 

if ($another_meeting) 
    echo 'ERROR'; 

如果键入的目的两个重叠的时候,它没有回音错误。我究竟做错了什么?

+3

您的代码容易受到SQL注入的影响。 *请*阅读此:http://stackoverflow.com/questions/601300/what-is-sql-injection并切换到参数化查询。旧的'mysql_'函数即将被弃用,你应该使用MySQLi来代替。 – Polynomial

+0

坦克的帮助。但这并没有解决我的问题。 – Albert

+0

@DarkRanger:你可以在while循环之前输入echo $ result并让我知道你得到了什么? –

回答

15

两个时间段,如果P1和P2重叠,且仅当这些条件中的至少一个成立:

  1. P1 P2的开始和结束之间开始(P2.from <= P1.from <= P2.to
  2. P2 P1的开始和结束之间开始(P1.from <= P2.from <= P1.to

这将捕捉部分重叠的时期以及一个完全覆盖另一个的时期。其中一个时间段必须始终在另一个时间内开始(或结束),如果它们重叠的话。

$another_meeting = ($from >= $from_compare && $from <= $to_compare) || 
        ($from_compare >= $from && $from_compare <= $to); 

您可能要到边界情况更改为严格<检查,如果一个事件不可能精确地在同一时间另一端开始:

所以$another_meeting会被定义。

+0

这似乎是完美的工作。我已经改变了一点,允许完全相同的时间(我与工程师合作,并且指定14:01而不是14:00)似乎是一个主要的缺陷。 Baie Dankie(非常感谢你在南非荷兰语中) – Albert

2

只是在做类似的事情....但只是时间....

$startTime = strtotime("7:00"); 
$endTime = strtotime("10:30"); 

$chkStartTime = strtotime("10:00"); 
$chkEndTime = strtotime("12:10"); 

if($chkStartTime > $startTime && $chkEndTime < $endTime) 
{ 
    // Check time is in between start and end time 
    echo "1 Time is in between start and end time"; 
} 
elseif(($chkStartTime > $startTime && $chkStartTime < $endTime) || ($chkEndTime > $startTime && $chkEndTime < $endTime)) 
{ 
    // Check start or end time is in between start and end time 
    echo "2 ChK start or end Time is in between start and end time"; 
} 
elseif($chkStartTime==$startTime || $chkEndTime==$endTime) 
{ 
    // Check start or end time is at the border of start and end time 
    echo "3 ChK start or end Time is at the border of start and end time"; 
} 
elseif($startTime > $chkStartTime && $endTime < $chkEndTime) 
{ 
    // start and end time is in between the check start and end time. 
    echo "4 start and end Time is overlapping chk start and end time"; 
} 
1

我可能会用这样的解决这个问题:

function avaliable($start, $end) { 
    // checks if there's a meeting between start or end 
    $q = "SELECT * FROM admin_boardroom_booking " 
    . "WHERE NOT (meeting_start BETWEEN '$end' AND '$start' " 
    . "OR meeting_end BETWEEN '$end' AND '$start')"; 
    $result = mysql_query($q); 

    // returns true on no conflicts and false elseway 
    return mysql_num_rows($result) === 0; 
} 
+0

可能会工作,但是我还需要检查会议是否完全不与另一个会议重叠。例如:会议1开始。会议2开始,会议2结束,会议1结束。看看你的代码,它不会在这种情况下返回false ... – Albert

+0

您的条件不幸错误。如果$ start在meeting_start之前,$ end在meeting_end之后会发生什么?圆括号将评估为“假”,而你将其否定为“真”!当您真的只想知道是否存在冲突时,获取所有非冲突会议也是一种相当奇怪的方法。尝试匹配冲突的会议,并使用“COUNT(*)”和“LIMIT 1”来加快会议速度。 –

+0

看起来我有点累,我要重写> ___ < – nyson

0

周华健Vikström的答案是正确的,但需要考虑的一个场景。
像,其中一个时间范围是另一个时间范围的子集。
因此,假设P1{start_time, end_time}P2{start_time, end_time}将在以下任何一种情况下发生重叠。

  • P1.start_time < = P2.start_time < = P1.end_time
  • P1.start_time < = P2.end_time < = P1.end_time
  • P2.start_time < = P1.start_time < = P1 .end_time < = P2.end_time

假设时间按升序排序。下面的示例:

|-----------------------------------| 
| Start time | End time | Name | 
|-----------------------------------| 
| 10:00  | 14:00 | P1 | 
|-----------------------------------| 
| 12:00  | 16:00 | P2 | 
|-----------------------------------| 
| 08:00  | 12:00 | P3 | 
|-----------------------------------| 
| 07:00  | 16:00 | P4 | 
|-----------------------------------| 

如果你认为P1为基准时间,你要检查P2,P3,P4反对。

  1. P1.start_time < = P2。START_TIME < = P1.end_time true
  2. P1.start_time < = P3.end_time < = P1.end_time true
  3. P4.start_time < = P1.start_time < = P1.end_time < = P4.end_time true

这是如何检查是否有任何时间重叠另一个或没有。

+0

我的答案已经解决了这个问题。如果P1是P2的完整子集,那么我的第一个条件成立:P1将在P2内开始。 –