Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
16
Help us understand the problem. What is going on with this article?
@juve_534

DateTimeクラスとDateTimeImmutableクラスの違いを理解する

More than 3 years have passed since last update.

概要

自分はミュータブルとイミュータブルの違いも分かっていませんでした。
そんな私が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クラスで上記の動きにハマったことがあり、今回の調べてみました。
日々のちょっとした疑問も調べてみると良いことがあるなと思いました。

以上、最後まで読んで頂きありがとうございました。

16
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
juve_534
駆け出しから5年ほど保守ばかりやっていたPHPer٩( 'ω' )و 今は新規開発でLaravelやAWSと戯れている。 マイノリティになってドヤりたいので、GoよりScalaとかElixirとかHackをやりたい
dmmcom
総合エンタテイメントサイト「DMM.com」を運営。会員数は2,900万人を突破。動画配信、FX、英会話、ゲーム、太陽光発電、3Dプリンタなど40以上のサービスを展開。沖縄での水族館事業参入、ベルギーでのサッカークラブ経営など、様々な事業を手掛ける。また2018年より若手起業家の支援を強化、「DMM VENTURES」による出資や、M&Aなどを積極的に展開している。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
16
Help us understand the problem. What is going on with this article?