メモ帳

読むな

Carbon の diffInDays() は時間まで見ている

みんな大好きCarbonで対象日が今日の何日後かを知りたいときに, 想定していた挙動と違っていたのでメモ

対象日が本日の何日後かを知りたい

2021-11-15が本日(2021-11-14)の何日後かを知りたいとき

>>> now()->diffInDays(Carbon\Carbon::parse('2021-11-15'))
=> 0

期待値は1だったけど, 0が返ってきた

実装を見てみる

Carbon\Traits\Difference を見てみると, 継承元の DateTime クラスの diff() を見に行ってたので DateTime での挙動も確認してみる

>>> (int) (new DateTime())->diff(new DateTime('2021-11-15'))->format('%r%a')
=> 0

(※ intへのcastとformat()はCarbon準拠)

(当たり前なんだけど)同じく0が返ってくる

現在時刻の時間を指定してみる

>>> now()->setTime(0, 0)->diffInDays(Carbon\Carbon::parse('2021-11-15'))
=> 1
>>> (int) (new DateTime())->setTime(0, 0)->diff(new DateTime('2021-11-15'))->format('%r%a')
=> 1

期待値の1が返ってきた。

対応策

現在時刻と対象日時の日付だけを考慮してdiffを取りたいときは現在日時刻の時間もセットしよう!

感想

DateTime クラス関してはdiffっていう命名からしてまっとうな挙動だと思うんだけど, Carbon のdiffInDays命名ややこしすぎ
日時を指定されても日数のdiff返せや(横暴)
ちなみに自分は Laravel 触るまでCarbonの存在知らなかったマンです。

※実際のコードにはImmutableクラス使おうね


github.com