检查两次是否重叠

时间:2012-06-19 09:51:32

标签: php mysql time overlapping

我想看看我从数据库读取的时间是否与用户提供的时间重叠。

我的数据库如下所示:

-----------------------------------------------
|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';

如果我故意键入两个重叠时间,则不会回显错误。我做错了什么?

5 个答案:

答案 0 :(得分:23)

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

  1. P1从P2的开始和结束(P2.from <= P1.from <= P2.to
  2. 开始
  3. P2在P1的开始和结束之间开始(P1.from <= P2.from <= P1.to
  4. 这将捕获部分重叠的时期以及完全覆盖另一个的时期。如果它们重叠,其中一个时期必须始终在另一个时段内开始(或结束)。

    所以$another_meeting将定义为:

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

    如果一个事件可以在与另一个事件完全相同的时间开始,您可能希望将边界情况更改为严格<检查。

答案 1 :(得分: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";
}

答案 2 :(得分: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;
}

答案 3 :(得分:0)

EmilVikström的回答是正确的,但有一个场景需要考虑。
比如,其中一个时间范围是另一个时间范围的子集。
因此,假设P1{start_time, end_time}P2{start_time, end_time}在以下任何一个为真时重叠。

  • P1.start_time&lt; = P2.start_time&lt; = P1.end_time
  • P1.start_time&lt; = P2.end_time&lt; = P1.end_time
  • P2.start_time&lt; = P1.start_time&lt; = P1.end_time&lt; = 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&lt; = P2.start_time&lt; = P1.end_time true
  2. P1.start_time&lt; = P3.end_time&lt; = P1.end_time true
  3. P4.start_time&lt; = P1.start_time&lt; = P1.end_time&lt; = P4.end_time true
  4. 这是你可以检查是否有任何时间与另一个重叠的方式。

答案 4 :(得分:0)

如果$ to总是晚于$ from,我们可以使用更短的解决方案

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