はじめに
Laravelには、日付や時刻を扱う処理を簡単にしてくれるCarbonという便利なライブラリが標準で備わっています。
このCarbonを使う上でハマりがちな落とし穴があるので、その例を示して確認していきます。
想定読者
PHP/Laravel初学者
開発環境・前提
開発環境
- OS:Windows11 22H2
- PHP 8.2.0
- Laravel 9.44.0
前提
- ローカルにLaravel開発環境があること。
(準備)
作成済みのLaravelプロジェクトのルートディレクトリまでコマンドラインで移動し、コマンドphp artisan tinker
でTinkerを起動。
※Tinker:Laravelに標準搭載されている対話型の実行環境
Tinkerでの確認手順
①まずは以下の通りに、各内容を一つずつ順番に入力していきます(「>」の後ろの内容)。
> use Carbon\Carbon;
> $now = Carbon::now();
下の画像のように変数$now
に現在の日時が代入されます。
②次に以下のように入力すると、画像のように先程$now
に代入した日時から5時間経過した日時が、変数$afterFiveHours
に代入されます。
> $afterFiveHours = $now->addHours(5);
③この後、$now
から7時間後の日時を変数$afterSevenHours
に代入します。
> $afterSevenHours = $now->addHours(7);
おかしいですね…
この例では$now
には2023-03-08 16:23:12
という日時が代入されているので、その7時間後だと16時+7時間で23時になるはずです。
ではどうして想定通りの日時にならないのでしょうか?
…
ズバリ、②の過程で元の$now
の日時が16時から21時に上書きされてしまったからです!
これにより、③の過程で16時だと思って使用した$now
が実は21時であり、そこから7時間後の4時になったのです。
しかし感覚的には$now
を16時の状態で保持したまま、最終結果は23時にしたいところです。
それでは一体どうすれば良いのか?
…
次のようにすれば、一瞬で解決できます!
> use Carbon\CarbonImmutable;
> $now = CarbonImmutable::now();
> $afterFiveHours = $now->addHours(5);
> $afterSevenHours = $now->addHours(7);
先程はuse Carbon\Carbon;
としていたところをuse Carbon\CarbonImmutable;
に変更しています。
これで元の$now
の日時が変わることなく、5時間後および7時間後の日時を正しく求めることができます。
Carbon
の代わりにCarbonImmutable
を使うだけで良いので、簡単ですね!
(ちなみにimmutableは「不変の」という意味なので、まさに文字通りです!)
おわりに
Carbonを使っているとハマりがちのポイントなのでご注意ください!
複数人で開発する際は、日時の扱いについて事前に共通認識を持っているとスムーズに進められると思います。
本記事が少しでも読者の皆様の参考になれば幸いです。
それでは良き開発ライフを!!
参考情報
- Tinkerについて
Tinker(REPL)の項を参照
- Carbonについて
- Laravel Daily様のYouTubeでの解説動画
英語での解説ですが、動画を見ているだけで内容を把握できるぐらい分かりやすいです。
本記事はこの動画の内容と同じことを行っています。