2012-06-19 37 views
5

Tôi muốn xem liệu một thời gian tôi đọc từ db có trùng lặp với thời gian do người dùng cung cấp hay không.Kiểm tra xem hai lần trùng lặp

cơ sở dữ liệu của tôi trông như thế này:

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

Mã của tôi trông như thế này:

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

Nếu tôi gõ hai lần chồng chéo về mục đích, nó không lỗi tiếng vang. Tôi đang làm gì sai?

+3

Mã của bạn dễ bị tiêm SQL. * Vui lòng * đọc phần này: http://stackoverflow.com/questions/601300/what-is-sql-injection và chuyển sang truy vấn được tham số hóa. Các hàm 'mysql_' cũ sẽ sớm không được dùng nữa, bạn nên sử dụng MySQLi. – Polynomial

+0

Xe tăng để được giúp đỡ. Tuy nhiên, điều đó không giải quyết được vấn đề của tôi. – Albert

+0

@DarkRanger: bạn có thể gõ echo $ kết quả trước khi vòng lặp và cho tôi biết những gì bạn nhận được? –

Trả lời

15

Hai khoảng thời gian P1 và P2 trùng lặp nếu, và chỉ nếu, ít nhất một trong những điều kiện tổ chức:

  1. P1 bắt đầu giữa bắt đầu và kết thúc P2 (P2.from <= P1.from <= P2.to)
  2. P2 bắt đầu giữa bắt đầu và kết thúc của P1 (P1.from <= P2.from <= P1.to)

Điều này sẽ bắt một phần các khoảng thời gian trùng lặp cũng như các giai đoạn mà một người hoàn toàn bao phủ các khoảng thời gian khác. Một trong các dấu chấm phải luôn bắt đầu (hoặc kết thúc) bên trong dấu chấm kia nếu chúng chồng lên nhau.

Vì vậy $another_meeting sẽ được xác định bởi:

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

Bạn có thể muốn thay đổi các trường hợp đường biên giới để nghiêm ngặt < kiểm tra nếu một sự kiện có thể bắt đầu tại cùng một thời điểm chính xác như mục đích khác.

+0

Điều này dường như hoạt động hoàn hảo. Tôi đã thay đổi nó một chút để cho phép chính xác cùng một lần (Tôi đang làm việc với các kỹ sư, và xác định 14:01 thay vì chỉ có vẻ như 14:00 là một bộ não lớn). Baie Dankie (Cảm ơn bạn rất nhiều bằng tiếng Afrikaans) – Albert

2

Là chỉ làm một cái gì đó tương tự .... nhưng chỉ với thời gian ....

$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

tôi có lẽ muốn giải quyết nó với một cái gì đó như thế này:

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

Có thể làm việc, nhưng sau đó tôi cũng sẽ cần kiểm tra xem cuộc họp có trùng lặp hoàn toàn với cuộc họp khác không. Ví dụ: Cuộc họp 1 bắt đầu. Cuộc họp 2 bắt đầu, họp 2 đầu, kết thúc 1 cuộc họp. Nhìn vào mã của bạn, nó sẽ không trả về false trong trường hợp này ... – Albert

+0

Điều kiện của bạn không may là sai. Điều gì sẽ xảy ra nếu $ bắt đầu trước khi meeting_start và $ end là sau khi meeting_end? Các dấu ngoặc đơn sẽ đánh giá thành 'false' và bạn phủ nhận nó thành' true'! Nó cũng là một cách tiếp cận khá kỳ lạ để lấy tất cả các cuộc họp không xung đột khi bạn thực sự chỉ muốn biết nếu có xung đột hay không. Thay vào đó, hãy thử so khớp các cuộc họp xung đột và sử dụng 'COUNT (*)' và 'LIMIT 1' để tăng tốc độ một chút. –

+0

Có vẻ như tôi hơi mệt, tôi sẽ viết lại nó> ___ < – nyson

0

câu trả lời Emil Vikström là đúng, nhưng có một kịch bản cần thiết để được xem xét.
Giống như, Một trong các phạm vi thời gian là tập hợp con của một phạm vi thời gian khác.
Vì vậy, giả sử rằng P1{start_time, end_time}P2{start_time, end_time} sẽ trùng lặp khi bất kỳ điều nào sau đây là đúng.

  • 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

Giả sử rằng thời gian được sắp xếp theo thứ tự tăng dần. Ví dụ dưới đây:

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

Nếu bạn xem xét P1 như thời gian cơ bản và bạn muốn kiểm tra P2, P3, P4 chống lại nó.

  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

Đây là cách bạn có thể kiểm tra xem có bất kỳ thời gian nào chồng lên nhau hay không.

+0

Câu trả lời của tôi đã giải quyết được vấn đề này. Nếu P1 là tập hợp con đầy đủ của P2, thì điều kiện đầu tiên của tôi là đúng: P1 sẽ bắt đầu trong P2. –

Các vấn đề liên quan