PHP добавление пропуска DateTime - PullRequest
1 голос
/ 09 января 2012

Я наблюдаю очень странное поведение, когда DateTime предпочитает добавлять день, но не другие.

<?php
// If you're running this after Jan 2012, use: new DateTime(date('Y-m-d', strtotime('2012-01-09')));
$month_end_date = new DateTime();
$month_end_date->modify('last day of this month');

$event_end_date = new DateTime('2012-03-15');

if ($event_end_date > $month_end_date) {
  // Using this line a day is never added on below and the date stays as 31 Jan 2012
  $event_end_date = clone $month_end_date;
  // This line allows the ->add() call to work, and gives 1 Feb 2012 as output:
  #$event_end_date = new DateTime($month_end_date->format('Y-m-d'));
}

$event_end_date->add(new DateInterval('P1D'));

// Date should now be 1st Feb
echo "Should be 1 Feb:   ". $event_end_date->format('Y-m-d');
?>

Кажется, это строка ->modify('last day of this month'), которая нарушает мой код; он напечатает 1 февраля 2012 года, если я заменю первые две строки на $month_end_date = new DateTime('2011-01-31'); или

$month_end_date = new DateTime('last day of this month'); 
$month_end_date = new DateTime($month_end_date->format(DateTime::W3C)); 

или используйте мою альтернативу $event_end_date = new DateTime($month_end_date->format('Y-m-d'));.

Имеет ли смысл, что мне нужно вызывать формат перед выполнением второй модификации?

Ответы [ 2 ]

1 голос
/ 09 января 2012

Похоже, использование «first» или «last» непосредственно в конструкторе объекта DateTime делает его неизменным. Это похоже на ошибку.

, например

date_default_timezone_set('Europe/London');
ini_set('display_errors', 1);
error_reporting(E_ALL);

$interval = new DateInterval('P1D');

$date1 = new DateTime('last day of this month');
var_dump($date1);
$date1->add($interval);
var_dump($date1);

echo "-------------------------------\n\n";

$lastDayOfMonth = date('Y-m-d H:i:s', strtotime('last day of this month'));
$date2 = new DateTime($lastDayOfMonth);
var_dump($date2);
$date2->add($interval);
var_dump($date2);

echo "-------------------------------\n\n";

$date3 = new DateTime('2012-01-31 '.date('H:i:s'));
var_dump($date3);
$date3->add($interval);
var_dump($date3);

Результат:

object(DateTime)[2]
  public 'date' => string '2012-01-31 11:40:10' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/London' (length=13)

object(DateTime)[2]
  public 'date' => string '2012-01-31 11:40:10' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/London' (length=13)

-------------------------------

object(DateTime)[3]
  public 'date' => string '2012-01-31 11:40:10' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/London' (length=13)

object(DateTime)[3]
  public 'date' => string '2012-02-01 11:40:10' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/London' (length=13)

-------------------------------

object(DateTime)[4]
  public 'date' => string '2012-01-31 11:40:10' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/London' (length=13)

object(DateTime)[4]
  public 'date' => string '2012-02-01 11:40:10' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/London' (length=13)
1 голос
/ 09 января 2012

Я сократил его до более простого теста:

<?php
date_default_timezone_set('Europe/Berlin');

$date = new DateTime('last day of this month');

$original_date = clone($date);

$date->add(new DateInterval('P1D'));

if ($date == $original_date) {
  echo 'Fail' . PHP_EOL;
}

echo 'Original: ' . $original_date->format(DateTime::W3C) . PHP_EOL;
echo 'Date:     ' . $date->format(DateTime::W3C) . PHP_EOL;
echo 'Diff:     ' . $original_date->diff($date)->format('%d %H:%i:%s') . PHP_EOL;

Это дает:

[joshua@appliance][/tmp/php]$ php -v
PHP 5.3.6 with Suhosin-Patch (cli) (built: Sep  8 2011 19:34:00) 
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies

[joshua@appliance][/tmp/php]$ php test.php 
Fail
Original: 2012-01-31T11:47:47+01:00
Date:     2012-01-31T11:47:47+01:00
Diff:     0 00:0:0

Строка 'Fail' никогда не должна выводиться, если дата увеличивается,Также обратите внимание, что разница равна 0. Это похоже на ошибку:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...