2012-01-04 37 views
6

yo estaba tratando de comparar la diferencia entre 2 fechas, pero parece que los resultados son bastante mal, por ejemplo, este código:PHP: Fecha y hora :: Dif resultados de la comparación

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

Devuelve cierto, pero por encima de que pueda vea que las diferencias de fecha no son las mismas, de hecho, las impresiones de eco +2 y +4. ¿Alguna idea sobre cómo comparar 2 diferencias de fecha?

EDIT: la fecha y hora :: diff devuelve un objeto DateInterval, de hecho, no implementa los operadores de comparación, https://bugs.php.net/bug.php?id=49914 Voy a usar DateInterval VARs para comprobar la diferencia, gracias por las respuestas

+1

comparación de objetos =/= comparación de valores. – hakre

Respuesta

7

Parece que DateInterval no implementa una función de comparación internamente. Las extensiones pueden definir reglas de comparación personalizadas para sus clases predefinidas. Evidentemente, se vuelve a una comparación suelta de que los objetos son de la misma clase.

This feature request proporciona un parche para agregar esta funcionalidad, pero no parece haber llegado a la fuente en ningún momento.

Para solucionar este problema, puede comparar cada variable miembro de los objetos a sí mismo (año, mes, etc.) o puede emitir cada objeto a una matriz:

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

está asignando $ datetime1-> diff ($ datetime2) tanto para $ interval como $ interval2, por lo que tienen exactamente los mismos valores

+0

Puedes ver que en la línea 7 he cambiado la fecha;) – alex88

3

Usted es el único comparing that the two objects­Docs del mismo tipo (y del mismo valor de accesorios), pero no es que sean idéntico:

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

Tenga en cuenta que está haciendo una comparación de objetos, no una comparación de valores, como con una cadena.

+0

¡Oh, tienes razón, gracias! – alex88

+0

Por [comparación de objetos] (http://php.net/manual/en/language.oop5.object-comparison.php), los objetos del mismo tipo con las mismas variables de miembro público deben considerarse iguales; sin embargo, no estoy seguro de cuán confiablemente esto se aplica a las clases predefinidas. – cmbuckley

+0

@cbuckley: * "Nota: Las extensiones pueden definir reglas propias para la comparación de objetos." * - para que todo pueda suceder;) – hakre

0

Recuerdo que hay una función para comparar las fechas en php como esta.

compare_dates($start_date,$end_date); 
+3

No, no hay –

+0

No se puede encontrar que:/ – alex88

+0

Su código está tomado de http://php.net/manual/en/datetime.diff.php En el mismo sitio, encontrará la sintaxis compare_dates aquí http://php.net/manual/en/ref.datetime.php – Anil

0

Hice la comparación entre dos DateIntervals de la siguiente manera:

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

No abusaría de una función que compara etiquetas de versión para comparar intervalos de fechas. – Sven

2

He extendido la clase php. La comparación de métodos hace una comparación de valores. Utiliza el orden "natural" de las variables en la clase php DateInterval. El ciclo foreach va al principio a través de años, luego meses, luego días, etc. Probablemente no es una solución muy portátil, pero parece estar funcionando bien en 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); 
    } 
}