日付処理でCarbonを使う時の注意ポイント

PHPで日付処理を行うのに便利なCarbonですが、いくつか注意した点があるので共有。


1.加減算処理は元の変数に結果が入る。

(※これはハマらない人の方が多いかも・・。)

例:2019/05/01から、5日後と10日後の日をそれぞれ算出する


間違ったプログラム

$dt = Carbon::parse('2019/05/01');

// 5日後
$after_5_day = $dt->addDay(5); // <- この処理で$dtが、2019/05/06になる。
echo($after_5_day->format('Y/m/d'). "\n");
// 10日後
$after_10_day = $dt->addDay(10); <- 2019/05/06の10日後になる
echo($after_10_day->format('Y/m/d'). "\n");

結果

2019/05/06

2019/05/16


正解プログラム

$dt = Carbon::parse('2019/05/01');

// 5日後
$after_5_day = $dt->addDay(5);
echo($after_5_day->format('Y/m/d'). "\n");

$dt2 = Carbon::parse('2019/05/01'); // <- 基準日を再定義する。
// 10日後
$after_10_day = $dt2->addDay(10);
echo($after_10_day->format('Y/m/d'). "\n");


結果

2019/05/06

2019/05/11


2.Xヶ月後は、addMonthではなく、addMonthsNoOverflowを使う。

例:2019/01/01から1ヶ月後の2019/02/01を出したい

$dt = Carbon::parse('2019/01/01')->addMonth(1);

echo($dt->format('Y/m/d'). "\n");

結果

2019/02/01

この場合は、addMonthでOK。

例:2019/01/31から1ヶ月後の2019/02/28を出したい

1月末日から、2月末日を算出する時

$dt = Carbon::parse('2019/01/31')->addMonth(1);

echo($dt->format('Y/m/d'). "\n");

結果

2019/03/03

addMonthだと、2019/02/29〜31までの値がないので、31日と28の差分で03/03となる。

上記の場合は、addMonthsNoOverflowを使う。

$dt = Carbon::parse('2019/01/31')->addMonthsNoOverflow(1);

echo($dt->format('Y/m/d'). "\n");

結果

2019/02/28

subMonthも同様に、subMonthsNoOverflowを使う。


3.日数の差分は、dと、daysを使い分ける。

例:2019/04/05と、2019/05/10の差分を算出

$diff = Carbon::parse('2019/04/05')->diff(Carbon::parse('2019/05/10'));

echo($diff->d. "\n"); // 日数のみの差分
echo($diff->days. "\n"); // 年月を含めた差分

結果

5

35