2012-01-04 19 views
6

starałem się porównać do różnicy między 2 dat, ale wydaje się, że wyniki są bardzo złe, na przykład ten kod:PHP: Datetime :: Diff wyniki porównania

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

Zwraca true, ale przede można zobacz różnice w datach nie są takie same, w rzeczywistości wydruki echa +2 i +4. Masz pomysł, jak porównać 2 różnice między datami?

EDIT: DateTime :: diff zwraca dateinterval obiekt, w rzeczywistości nie implementuje operatory porównania, https://bugs.php.net/bug.php?id=49914 użyję dateinterval vars sprawdzić różnicę, dzięki za odpowiedzi

+1

porównanie obiektów =/= porównanie wartości. – hakre

Odpowiedz

7

Wygląda na to, że narzędzie DateInterval nie implementuje funkcji porównania wewnętrznie. Rozszerzenia mogą definiować niestandardowe reguły porównania dla ich predefiniowanych klas. Widać wyraźnie, że obiekty są tej samej klasy.

This feature request dostarcza łatkę do dodania tej funkcji, ale w żadnym momencie nie trafiła ona do źródła.

Aby obejść ten problem, można porównać każdą zmienną składową swoich obiektów samodzielnie (rok, miesiąc itd) lub można oddać każdy obiekt do tablicy:

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

przypisywanych $ datetime1-> diff ($ datetime2) do przedziału $ i $ interval2, więc mają dokładnie takie same wartości

+0

Widać, że na linii 7 zmieniłem datę;) – alex88

3

Jesteś tylko comparing that the two objects­Docs są tego samego typu (i tej samej wartości rekwizytów), ale nie są one takie same identyczne:

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

Zauważ, że robisz porównanie obiektów, a nie porównywanie wartości, jak w przypadku ciągu.

+0

Och, masz rację, dziękuję! – alex88

+0

Na [porównanie obiektów] (http://php.net/manual/en/language.oop5.object-comparison.php), obiekty tego samego typu z tymi samymi publicznymi zmiennymi składowymi należy uznać za równe; nie wiem jednak, jak niezawodnie dotyczy to predefiniowanych klas. – cmbuckley

+0

@ cbuckley: * "Uwaga: Rozszerzenia mogą definiować własne reguły porównywania ich obiektów." * - więc wszystko może się zdarzyć;) – hakre

0

Pamiętam, że istnieje funkcja porównywania dat w php w ten sposób.

compare_dates($start_date,$end_date); 
+3

Nie, nie ma –

+0

Nie można znaleźć:/ – alex88

+0

Twój kod pochodzi z http://php.net/manual/en/datetime.diff.php W tej samej witrynie znajdziesz tutaj składnię compare_dates http://php.net/manual/en/ref.datetime.php – Anil

0

zrobiłem porównanie dwóch DataIntervals w następujący sposób:

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

Nie nadużywałbym funkcji, która porównuje tagi wersji do porównywania interwałów dat. – Sven

2

Rozszerzyłem klasy php. Metoda compare dokonuje porównania wartości. Używa "naturalnej" kolejności zmiennych w php DateInterval class. Cykl foreach następuje najpierw przez lata, potem miesiące, potem dni itd. Prawdopodobnie nie jest to rozwiązanie bardzo przenośne, ale wygląda na to, że działa dobrze w 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); 
    } 
}