2012-06-19 12 views
5

Voglio vedere se una volta che ho letto da un db si sovrappone con un tempo fornito da un utente.Controlla se due volte si sovrappongono

mio database si presenta così:

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

Il mio codice è simile al seguente:

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

Se digito due volte sovrapposti di proposito, non è così errore eco. Che cosa sto facendo di sbagliato?

+3

Il tuo codice è vulnerabile alle iniezioni SQL. * Per favore * leggi questo: http://stackoverflow.com/questions/601300/what-is-sql-injection e passa alle query parametrizzate. Le vecchie funzioni 'mysql_' sono presto deprecate, dovresti usare MySQLi. – Polynomial

+0

Serbatoi per l'aiuto. Ciò non ha tuttavia risolto il mio problema. – Albert

+0

@DarkRanger: puoi digitare echo $ result prima del ciclo e fammi sapere cosa ottieni? –

risposta

15

due periodi di tempo P1 e P2 sovrappone se, e solo se, almeno una di queste condizioni:

  1. P1 inizia tra l'inizio e la fine di P2 (P2.from <= P1.from <= P2.to)
  2. P2 inizia tra l'inizio e la fine di P1 (P1.from <= P2.from <= P1.to)

Ciò consentirà di rilevare periodi parzialmente sovrapposti e periodi in cui uno copre completamente l'altro. Uno dei periodi deve sempre iniziare (o terminare) all'interno dell'altro se si sovrappongono.

Così $another_meeting sarebbe definito da:

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

Si consiglia di modificare i casi limite le severe < controlla se un evento può iniziare al tempo stesso esatto come un altro finisce.

+0

Sembra funzionare perfettamente. L'ho modificato un po 'per consentire lo stesso numero di volte (sto lavorando con gli ingegneri, e specificare 14:01 invece di solo 14:00 sembra essere un grande spaccone). Baie Dankie (Grazie mille in Afrikaans) – Albert

2

stava solo facendo qualcosa di simile .... ma solo con tempi ....

$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

probabilmente sarei risolvere con qualcosa di simile:

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

Potrebbe funzionare, ma poi avrei anche bisogno di controllare se la riunione non si sovrappone completamente a un'altra. Esempio: la riunione 1 inizia. L'incontro 2 inizia, l'incontro 2 finisce, l'incontro 1 finisce. Guardando il tuo codice, non restituirà false in questo caso ... – Albert

+0

Purtroppo le tue condizioni sono errate. Cosa succede se $ start è prima di meeting_start e $ end è dopo meeting_end? Le parentesi valuteranno a 'false' e ​​la negherete in' true'! È anche un approccio piuttosto strano recuperare tutte le riunioni non conflittuali quando si vuole solo sapere se ci sono conflitti o meno. Cerca di abbinare invece le riunioni in conflitto e usa 'COUNT (*)' e 'LIMIT 1' per accelerare un po '. –

+0

Sembra che sia un po 'stanco, lo riscriverò> ___ < – nyson

0

risposta di Emil Vikström è corretto, ma c'è uno scenario necessaria per essere considerato.
Come, uno degli intervalli di tempo è un sottoinsieme di un altro intervallo di tempo.
Pertanto, supporre che P1{start_time, end_time} e P2{start_time, end_time} si sovrappongano quando una delle seguenti condizioni è vera.

  • 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

Assumendo che gli orari siano ordinati in ordine crescente. Esempio di seguito:

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

Se si considera P1 come il tempo base e si desidera controllare P2, P3, P4 contro di essa.

  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

Ecco come è possibile verificare se una qualsiasi delle due volte si sovrappone a un'altra o no.

+0

La mia risposta lo risolve già. Se P1 è un sottoinsieme completo di P2, allora la mia prima condizione è vera: P1 inizierà entro P2. –

Problemi correlati