概要
自分はミュータブルとイミュータブルの違いも分かっていませんでした。
そんな私がDateTimeクラスでハマったことがあったので、これを機会に理解していきます。
特徴
PHP: DateTime - Manual
DateTimeクラスはミュータブルらしいです。
ミュータブルとは
オブジェクトで、作成後も状態を変えることができる。
PHP: DateTimeImmutable - Manual
DateTimeImmutableクラスはイミュータブルらしいです。
イミュータブル
オブジェクトで、作成後は状態を変えることができない。
ふむふむ…。
イミュータブル - Wikipediaによると、ミュータブルとイミュータブルの違いは、オブジェクト作成後にその状態を変えられるかどうかが違いのようです。
これがどのように影響していくるか、次の章で確認してきます。
動作検証
まずは特定の日付でそれぞれのオブジェクトを作成し、14日前の日付に変更します。
$date = new DateTime('2018-04-25');
echo 'DateTime : ';
echo $date->modify('-14 day')->format('Y-m-d H:i:s') . PHP_EOL;
$dateImmu = new DateTimeImmutable('2018-04-25');
echo 'DateTimeImmutable : ';
echo $dateImmu->modify('-14 day')->format('Y-m-d H:i:s') . PHP_EOL;
DateTime : 2018-04-11 00:00:00
DateTimeImmutable : 2018-04-11 00:00:00
このときはどちらも同じ結果となります。
これだけの処理ならミュータブルなDateTimeクラスでも不都合はありません。
では、特定の日付を起点に、14日前の日付と30日前の日付を生成してみましょう。
$date = new DateTime('2018-04-25');
echo 'DateTime : ';
echo $date->modify('-14 day')->format('Y-m-d H:i:s') . PHP_EOL;
echo $date->modify('-30 day')->format('Y-m-d H:i:s') . PHP_EOL;
$dateImmu = new DateTimeImmutable('2018-04-25');
echo 'DateTimeImmutable : ';
echo $dateImmu->modify('-14 day')->format('Y-m-d H:i:s') . PHP_EOL;
echo $dateImmu->modify('-30 day')->format('Y-m-d H:i:s') . PHP_EOL;
DateTime : 2018-04-11 10:35:19
2018-03-12 10:35:19
DateTimeImmutable : 2018-04-11 10:35:19
2018-03-26 10:35:19
どちらも2018-04-25を起点にしていますが、実行結果が変わりましたね。
2018-04-25の30日前は2018-03-26なので、DateTimeImmutableクラスが正しい結果となります。
DateTimeクラスはミュータブルなため、14日前の日付を生成した際に、ベースの日付が変わってしまい、14日前の日付から30日前の日付を生成してしまっています。
DateTimeImmutableクラスはイミュータブルなため、14日前の日付を生成した際にも、ベースの日付が変わらず、ベースの日付から30日前の日付を生成しています。
以上のことから、
DateTimeクラス → 日付計算を行うときに注意が必要
DateTimeImmutableクラス → 日付計算もいい感じにしてくれる
と言えるかなと思います。
最後に
DateTimeクラスとDateTimeImmutableクラスでは、オブジェクト作成後の動きが違い、そのため特定の操作を行うときに挙動が変わることがわかりました。
自分は、DateTimeクラスで上記の動きにハマったことがあり、今回の調べてみました。
日々のちょっとした疑問も調べてみると良いことがあるなと思いました。
以上、最後まで読んで頂きありがとうございました。