🕰️

Laravel 11 の Carbon 3 のやや注意な変更点

2024/04/09に公開

前書き

Laravel 11 では、今までの Carbon 2 ではなく Carbon 3 が入ってきます。Laravel 11 のアップグレードガイドには、Carbon 3 への変更点へのリンクも張ってあります。

この記事では、幾つかある Carbon 3 の変更点で、特に要注意(かも知れない)変更点を見て行きます。なお、タイトルに Laravel とは付きますが、ほぼ Carbon の話です。

本題

という事で、Carbon 3 への変更点のリンクにもある

Changed diffIn* methods to return float and relative diff ($absolute = false by default) #2119

(日本語訳)
diffIn*メソッドがfloatと相対差分を返すように変更 (デフォルトでは$absolute = false) #2119

の一文を見て行きたいと思います。さりげない一文ですが、

  • 一流プログラマ → 全てを悟る。
  • 二流プログラマ → 「ふ~ん…」と、何となく分かったつもりになれる。
  • 見習いプログラマ → サッパリ分からない。

と言った所でしょうか。私は真ん中辺りです。😅

diffIn 系メソッドは、int 型では無く、float 型を返す。

これは分かり易いですね。

Carbon 2 の場合

use Carbon\Carbon;

$first = new Carbon('2020-04-07');
$second = new Carbon('2020-04-10');
dump($first->diffInDays($second)); // 3 ← int

Carbon 3 の場合

use Carbon\Carbon;

$first = new Carbon('2020-04-07');
$second = new Carbon('2020-04-10');
dump($first->diffInDays($second)); // 3.0 ← float

という事です。今まで、そのまま === 3 とかで条件分岐していたのは、今後は通用しなくなりますね。適宜、(int) で型変換とかしてね、との事。

Carbon 3

dump((int) $first->diffInDays($second)); // 3
    ↑ ここ

diffIn 系メソッドは、相対差分を返す。

「相対差分?はっ?」って感じですが、要するにこういう事ですね。

Carbon 2 の場合

use Carbon\CarbonImmutable;

$immutable = new CarbonImmutable;
$now = $immutable->now();

$after = $now->addSeconds(30);
dump($after->diffInSeconds($now)); // 30
dump($now->diffInSeconds($after)); // 30

Carbon 3 の場合

use Carbon\CarbonImmutable;

$immutable = new CarbonImmutable;
$now = $immutable->now();

$after = $now->addSeconds(30);
dump($after->diffInSeconds($now)); // -30.0 ← マイナス
dump($now->diffInSeconds($after)); // 30.0

Carbon 2 の場合、どちらも 30 と絶対的な差分でした。Carbon 3 の場合、どちら($after or $now)を先に書くかによって、マイナスとプラスになり得るという事ですね。

Carbon 3 の公式ドキュメントもチラと見てみる

Carbon 3 の公式ドキュメントにも軽く説明があるのですが、情報が詰まっていて何とも分かりにくいのですが、上記が分かれば、大丈夫でしょうか。

ドキュメントによると、

$after = Carbon::now()->addSeconds(2);
$before = Carbon::now();

var_dump($after->diffInSeconds($before));

Carbon 2 では、int(1)
Carbon 3 では、double(-1.999508)

一瞬迷うのは、
Carbon 2 では、2 ではなく、1
Carbon 3 では、-2.0 ではなく、-1.999508
となったりしますが、これは、2 つの now() が実行されたタイミング(時間)が、微妙に異なるから起こる違いですね。

雑感

Laravel のアップグレードガイドは、「Carbon の変更ログ」のリンク先に丸投げなので、意外と見落としてしまうかも知れませんね。

「特に diff* 系メソッドにご注意下さい」位のフォローがあるといいかもですね。(→ ドキュメントにプルリク送ると、マージされますよ。たぶん。)

Discussion