2012-01-04 2 views
6

я пытался сравнить разницу между 2 датами, но это, кажется, результаты довольно неправильно, например, этот код:PHP: Datetime :: Diff результаты сравнения

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

Возвращает истинное, но выше вы можете см. различия в дате, не совпадают, на самом деле эхо-печать +2 и +4. Любая идея в том, как сравнивать 2 разницы даты?

EDIT: DateTime :: дифф возвращает DateInterval объект, на самом деле он не выполняет операторы сравнения, https://bugs.php.net/bug.php?id=49914 я буду использовать DateInterval ВАР, чтобы проверить разницу, спасибо за ответы

+1

сравнение предметов =/= сравнение значений. – hakre

ответ

7

Похоже, что DateInterval не реализует функцию сравнения внутри. Расширениям разрешено определять собственные правила сравнения для своих предопределенных классов. Очевидно, он возвращается к свободному сравнению, что объекты одного класса.

This feature request содержит патч для добавления этой функции, но, похоже, он не попал в источник в какой-либо точке.

Чтобы обойти эту проблему, вы можете сравнить каждую переменную-член ваших объектов самостоятельно (лет, месяцев и т.д.), или вы можете привести каждый объект в массив:

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

Вы назначаете $ datetime1-> diff ($ datetime2) как до $ interval, так и $ interval2, поэтому они имеют одинаковые значения

+0

Вы можете видеть, что в строке 7 я изменил дату;) – alex88

3

Вы только comparing that the two objects­Docs имеют один и тот же тип (и то же значение реквизита), но не то, чтобы они были идентичные:

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

Обратите внимание, что вы выполняете сравнение объектов, а не сравнение значений, как со строкой.

+0

О, вы правы, спасибо! – alex88

+0

В сравнении [сравнение объектов] (http://php.net/manual/en/language.oop5.object-comparison.php) объекты одного и того же типа с одинаковыми переменными-членами должны считаться равными; не уверен, насколько надежно это относится к предопределенным классам. – cmbuckley

+0

@cbuckley: * «Примечание: расширения могут определять собственные правила для сравнения их объектов». * - так что все может случиться;) – hakre

0

Помню, что существует функция сравнения дат в php, подобных этому.

compare_dates($start_date,$end_date); 
+3

Нет, нет –

+0

Не можете найти что:/ – alex88

+0

Ваш код взято из http://php.net/manual/en/datetime.diff.php На этом же сайте вы найдете синтаксис compare_dates здесь http://php.net/manual/en/ref.datetime.php – Anil

0

Я сделал сравнение между двумя DateIntervals, используя следующий способ:

+2

Я бы не злоупотреблял функцией, которая сравнивает теги версии для сравнения интервалов дат. – Sven

2

Я расширил класс php. Сравнение методов делает сравнение значений. Он использует «естественный» порядок переменных в классе php DateInterval. Цикл foreach проходит сначала через годы, потом месяцы, затем дни и т. Д. Это, вероятно, не очень портативное решение, но, похоже, оно работает отлично в 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); 
    } 
} 
Смежные вопросы