2012-01-09 14 views
1

私は非常に奇妙な動作を見ています。PHPの日付時間を加算しないでください

<?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'));を使用して最初の2行を交換する場合には、2012年2月1日を印刷します。

2回目の変更を行う前にフォーマットを呼び出す必要がありますか?

+0

は "動作しません" 何が起こっているのはかなり曖昧な説明です。詳細を教えてください。 –

+0

投稿を編集しました:壊れたコードから2012-01-01が出力され、2012-02-01が出力されます。 – PeterB

答えて

1

DateTimeオブジェクトのコンストラクタに直接 "first"または "last"を使用すると、不変になります。これはバグのようです。

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

私は単純なテストケースにそれを絞り込まました:

<?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; 

それが与える:

[[email protected]][/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 

[[email protected]][/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であることに注意してください。

関連する問題