2012-06-19 9 views
5

Quiero ver si una hora que leo desde un archivo db se solapa con una hora proporcionada por un usuario.Comprueba si se superponen dos veces

Mi base de datos es el siguiente:

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

Mi código es el siguiente:

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

Si escribo dos veces superpuestas a propósito, no lo hace de error eco. ¿Qué estoy haciendo mal?

+3

Su código es vulnerable a las inyecciones de SQL. * * Lea esto: http://stackoverflow.com/questions/601300/what-is-sql-injection y cambie a consultas con parámetros. Las viejas funciones de 'mysql_' están a punto de desaparecer, debería usar MySQLi en su lugar. – Polynomial

+0

Tanques para la ayuda. Sin embargo, eso no resolvió mi problema. – Albert

+0

@DarkRanger: ¿puedes escribir echo $ result antes del ciclo while y decirme qué obtienes? –

Respuesta

15

dos períodos de tiempo P1 y P2 se superpone si, y sólo si, al menos una de estas condiciones se cumplen:

  1. P1 comienza entre el inicio y el final de P2 (P2.from <= P1.from <= P2.to)
  2. P2 comienza entre el inicio y el final de P1 (P1.from <= P2.from <= P1.to)

Esto atrapará períodos parcialmente superpuestos, así como períodos en los que uno cubre completamente al otro. Uno de los períodos siempre debe comenzar (o finalizar) dentro del otro si se superponen.

Así $another_meeting se definiría por:

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

Es posible que desee cambiar los casos límites estrictos a < comprueba si un evento puede comenzar en el mismo momento exacto en que termina la otra.

+0

Esto parece estar funcionando perfectamente. Lo he cambiado un poco para permitir los mismos tiempos exactos (estoy trabajando con ingenieros, y especificar 14:01 en lugar de solo 14:00 parece ser una gran falla cerebral). Baie Dankie (Muchas gracias en afrikaans) – Albert

2

sólo estaba haciendo algo similar .... pero sólo con tiempos ....

$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

probablemente me solucionarlo con algo como esto:

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

Podría funcionar, pero también necesitaría verificar si la reunión no se superpone por completo a otra. Ejemplo: la reunión 1 comienza. La reunión 2 comienza, la reunión 2 finaliza, la reunión 1 finaliza. En cuanto a su código, no devolverá falso en este caso ... – Albert

+0

Desafortunadamente sus condiciones son incorrectas. ¿Qué sucede si $ start está antes de meeting_start y $ end está después de meeting_end? ¡Los paréntesis evaluarán a 'falso' y tú lo negarás a' verdadero'! También es un enfoque bastante extraño buscar todas las reuniones no conflictivas cuando realmente solo quieres saber si hay conflictos o no. Intente hacer coincidir las reuniones en conflicto en su lugar y use 'COUNT (*)' y 'LIMIT 1' para acelerarlo un poco. –

+0

Parece que estoy un poco cansado, voy a reescribirlo> ___ < – nyson

0

respuesta de Emil Vikström es correcta, pero no es un escenario necesario para ser considerado.
Me gusta, Uno de los rangos de tiempo es un subconjunto de otro rango de tiempo.
Por lo tanto, suponga que P1{start_time, end_time} y P2{start_time, end_time} se superpondrán cuando cualquiera de los siguientes es verdadero.

  • 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

Suponiendo que los tiempos se ordenan en orden ascendente. Ejemplo a continuación:

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

Si se tiene en cuenta el tiempo P1 como base y desea comprobar P2, P3, P4 contra ella.

  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

Así es como puede verificar si alguna parte del tiempo se superpone a la otra o no.

+0

Mi respuesta ya lo resuelve. Si P1 es un subconjunto completo de P2, entonces mi primera condición es verdadera: P1 comenzará dentro de P2. –

Cuestiones relacionadas