2012-01-04 2 views
6

stavo cercando di confrontare la differenza tra 2 date, ma sembra che i risultati sono piuttosto male, per esempio questo codice:PHP: Datetime :: Diff risultati confronto

$datetime1 = new DateTime('2009-10-11'); 
$datetime2 = new DateTime('2009-10-13'); 
$interval = $datetime1->diff($datetime2); 
echo $interval->format('%R%a days')."<br />"; 

$datetime1 = new DateTime('2009-10-11'); 
$datetime2 = new DateTime('2009-10-15'); 
$interval2 = $datetime1->diff($datetime2); 
echo $interval2->format('%R%a days')."<br />"; 

if($interval == $interval2){ echo "true"; }else{echo "false"; } 

restituisce true, ma soprattutto si può vedere le differenze di data non sono le stesse, infatti echo stampa +2 e +4. Qualche idea su come confrontare 2 differenze di data?

EDIT: datetime :: diff restituisce un oggetto DateInterval, in realtà non implementa operatori di confronto, https://bugs.php.net/bug.php?id=49914 userò DateInterval Vars per controllare la differenza, grazie per le risposte

+1

confronto oggetto =/= confronto valori. – hakre

risposta

7

Sembra che DateInterval non implementa internamente una funzione di confronto. Le estensioni possono definire regole di confronto personalizzate per le loro classi predefinite. Evidentemente si ricorre a un paragone allentato che gli oggetti sono della stessa classe.

This feature request fornisce una patch per aggiungere questa funzionalità, ma non sembra averla introdotta nell'origine in alcun punto.

Per ovviare a questo problema, è possibile confrontare ogni variabile membro degli oggetti stessi (anni, mesi, ecc) oppure si può lanciare ogni oggetto in un array:

if ((array) $interval == (array) $interval2) { 
    echo 'true'; 
} else { 
    echo 'false'; 
} 
0

si sta assegnando $ datetime1-> diff ($ datetime2) sia a $ intervallo e $ intervallo2, quindi hanno gli stessi identici valori

+0

Puoi vedere che sulla linea 7 ho cambiato la data;) – alex88

3

Sei solo comparing that the two objects­Docs sono dello stesso tipo (e lo stesso valore di oggetti di scena), ma non che sono identico:

if ($interval === $interval2) {echo "true";} else {echo "false";} 
       ^^^ 

Prendere nota che si sta eseguendo un confronto tra oggetti, non un confronto di valori, come con una stringa.

+0

Oh, hai ragione, grazie! – alex88

+0

Per [confronto oggetti] (http://php.net/manual/en/language.oop5.object-comparison.php), oggetti dello stesso tipo con le stesse variabili membro pubblico dovrebbero essere considerati uguali; non sono sicuro di quanto questo sia valido per le classi predefinite. – cmbuckley

+0

@cbuckley: * "Nota: le estensioni possono definire le proprie regole per il confronto degli oggetti." * - così tutto può accadere;) – hakre

0

Ricordo che esiste una funzione per confrontare le date in php come questa.

compare_dates($start_date,$end_date); 
+3

No, non c'è –

+0

Impossibile trovare quello:/ – alex88

+0

Il tuo codice è preso da http://php.net/manual/en/datetime.diff.php Nello stesso sito, troverai la sintassi di confronto_date qui http://php.net/manual/en/ref.datetime.php – Anil

0

Ho fatto il confronto tra i due DateIntervals utilizzando il seguente modo:

version_compare(join('.', (array) $dateIntervalA), join('.', (array) $dateIntervalB)); 
+2

Non vorrei abusare di una funzione che confronta i tag di versione per confrontare gli intervalli di date. – Sven

2

Ho esteso la classe php. Il metodo compare fa un confronto di valori. Usa l'ordine "naturale" delle variabili nella classe DateInterval php. Il ciclo foreach va dapprima per anni, poi per mesi, poi per giorni, ecc. Probabilmente non è una soluzione molto portabile, ma sembra funzionare bene in PHP 5.3.

/** 
* Description of DateInterval 
* 
* @author Santhos 
*/ 
class DateInterval extends \DateInterval 
{  
    /** 
    * compares two date intervals 
    * returns: 
    * 0 - when they are equal 
    * less than zero - $a is less than $b 
    * greater than zero - $a is greater than $b 
    * 
    * @param \Designeo\Utils\DateInterval $dateInterval 
    * @return int 
    */ 
    public static function compare($a, $b) 
    { 
     // check parameters 
     self::isDateInterval($a); 
     self::isDateInterval($b); 

     foreach ($a as $key => $value) {    
      // after seconds 's' comes 'invert' and other crap we do not care about 
      // and it means that the date intervals are the same 
      if ($key == 'invert') {     
       return 0; 
      } 

      // when the values are the same we can move on 
      if ($a->$key == $b->$key) { 
       continue; 
      } 

      // finally a level where we see a difference, return accordingly 
      if ($a->$key < $b->$key) { 
       return -1; 
      } else { 
       return 1; 
      } 
     } 
    } 

    private static function isDateInterval($object) 
    { 
     if (!is_a($object, 'DateInterval')) { 
      throw new \Exception('Parameter dateInterval type has to be a Dateinterval.'); 
     } 
    } 

    public function compareToAnother($dateInterval) { 
     return self::compare($this, $dateInterval); 
    } 
}