PHPのDateTimeクラスについて

DateTimeが使いにくいのでメモ。

前提

とくに記載のない場合、PHP 5.3が対象です。

DateTimeいろいろ

現在の日時を生成する

コンストラクタを使う。

$d = new DateTime();
echo $d->format('Y-m-d H:i:s'); // -> '2013-07-12 07:21:05'
文字列から日時を生成する

コンストラクタを使う。
有効な書式はドキュメントを参照してください。
有効な年、月、日、時、分、秒の範囲はドキュメントによれば以下の通りです。
年:0000〜9999
月:00〜12
日:00〜31
時:00〜24
分:00〜59
秒:00〜59

$d = new DateTime('2013-07-12 07:07:57');
echo $d->format('Y-m-d H:i:s'); // -> '2013-07-12 07:07:57'
年、月、日から日時を生成する

setDateメソッドを使う。
有効な年、月、日の範囲はドキュメントに記載されていませんが、おそらくintの範囲です。
月が1より小さい場合、過去の日付に繰り下がります。月が12より大きい場合、未来の日付に繰り上がります。日が1より小さい場合、過去の日付に繰り下がります。日が月末日より大きい場合、未来の日付に繰り上がります。

$d = new DateTime('00:00:00');
$d->setDate(2013, 13, 32);
echo $d->format('Y-m-d H:i:s'); // -> '2014-02-01 00:00:00'
年、月、日、時、分、秒から日時を生成する

setDateメソッドsetTimeメソッドを使う。
有効な時、分、秒の範囲はドキュメントに記載されていませんが、おそらくintの範囲です。
時が0より小さい場合、過去の日時に繰り下がります。時が23より大きい場合、未来の日時に繰り上がります。分、秒が0より小さい場合、過去の日時に繰り下がります。分、秒が59より大きい場合、未来の日時に繰り上がります。

$d = new DateTime();
$d->setDate(2013, 13, 32)->setTime(27, 70, 80);
echo $d->format('Y-m-d H:i:s'); // -> '2014-02-02 04:11:20'

newキーワードについて

PHP 5.4から (new Foo)->bar() と書けるようになりました。

クラスのインスタンスを生成するときに、そのメンバーにアクセスできるようになりました (例: (new Foo)->bar())。

http://www.php.net/manual/ja/migration54.new-features.php

(注意すべきこととして、new Foo->bar() や ((new Foo))->bar() は依然として文法エラーになります(PHP 5.5現在))。

したがって、

$d = new DateTime('00:00:00');
$d->setDate(2013, 13, 32);

は、PHP 5.4から

$d = (new DateTime('00:00:00'))->setDate(2013, 13, 32);

と書けます。

mutabilityについて

DateTimeはmutableです。
そしてDateTimeの多くのメソッドに副作用があります(自分自身のインスタンスを変更します)。
例1:

$d = new DateTime('2013-07-12 00:00:00');
echo $d->format('Y-m-d H:i:s'); // -> '2013-07-12 00:00:00'
$d->setDate(2013, 13, 32);
echo $d->format('Y-m-d H:i:s'); // -> '2014-02-01 00:00:00'

例2:

function f(DateTime $d)
{
    $d->setDate(2014, 12, 31);
}

$d = new DateTime('2013-07-12 00:00:00');
echo $d->format('Y-m-d H:i:s'); // -> '2013-07-12 00:00:00'
f($d);
echo $d->format('Y-m-d H:i:s'); // -> '2014-12-31 00:00:00'

一方、PHP 5.5で追加されたDateTimeImmutableはimmutableです。

このクラスの挙動は DateTime とほぼ同じですが、 自分自身は変更せずに新しいオブジェクトを返すという点だけが異なります。

http://www.php.net/manual/ja/class.datetimeimmutable.php