我看到非常奇怪的行为,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')
行打破了我的代码;如果我用$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'));
。
在进行第二次修改之前,我需要调用格式吗?
答案 0 :(得分:1)
我已将其缩减为更简单的测试用例:
<?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
如果日期递增,则不应输出“失败”行。另外,请注意diff是0.这看起来像一个bug:)
答案 1 :(得分:1)
似乎直接在DateTime对象的构造函数中使用“first”或“last”会导致它变为不可变。这似乎是一个错误。
e.g。
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)