【问题标题】:Check if two times overlap检查两次是否重叠
【发布时间】:2012-06-21 08:22:47
【问题描述】:

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

我的数据库如下所示:

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

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

【问题讨论】:

  • 您的代码容易受到 SQL 注入的攻击。 阅读:stackoverflow.com/questions/601300/what-is-sql-injection 并切换到参数化查询。旧的 mysql_ 函数即将被弃用,您应该改用 MySQLi。
  • 坦克寻求帮助。然而,这并没有解决我的问题。
  • @DarkRanger : 你能在 while 循环之前输入 echo $result 并告诉我你得到了什么吗?

标签: php mysql time overlapping


【解决方案1】:

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

$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】:

    当且仅当至少满足以下条件之一时,两个时间段 P1 和 P2 重叠:

    1. P1 在 P2 的开头和结尾之间开始 (P2.from &lt;= P1.from &lt;= P2.to)
    2. P2 在 P1 的开头和结尾之间开始 (P1.from &lt;= P2.from &lt;= P1.to)

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

    所以$another_meeting 将被定义为:

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

    您可能希望将边界情况更改为严格的&lt; 检查一个事件是否可以在与另一事件完全相同的时间开始。

    【讨论】:

    • 这似乎工作得很好。我对其进行了一些更改以允许完全相同的时间(我正在与工程师一起工作,并且指定 14:01 而不是仅 14:00 似乎是一个主要的脑残)。 Baie Dankie(非常感谢南非荷兰语)
    【解决方案3】:

    我可能会用这样的方法解决它:

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

    【讨论】:

    • 可能有效,但我还需要检查会议是否与另一个会议完全重叠。示例:会议 1 开始。会议 2 开始,会议 2 结束,会议 1 结束。查看您的代码,在这种情况下它不会返回 false...
    • 很遗憾,您的条件是错误的。如果 $start 在 meeting_start 之前而 $end 在 meeting_end 之后会发生什么?括号将评估为false,您将其否定为true!当您真的只想知道是否存在冲突时,获取所有非冲突会议也是一种相当奇怪的方法。尝试匹配冲突的会议,并使用COUNT(*)LIMIT 1 加快速度。
    • 好像有点累了,我要重写了>___
    【解决方案4】:

    Emil Vikström 的回答是正确的,但需要考虑一种情况。
    就像,其中一个时间范围是另一个时间范围的子集。
    因此,假设以下任何一项为真时,P1{start_time, end_time}P2{start_time, end_time} 将重叠。

    • P1.start_time
    • P1.start_time
    • P2.start_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 true
    2. P1.start_time true
    3. P4.start_time true

    这是您可以检查任何时间是否与另一个时间重叠的方法。

    【讨论】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-13
      • 1970-01-01
      • 2015-11-19
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      相关资源
      最近更新 更多