【PHP/Laravel】Carbonの月またぎ NoOverFlow (月末月初)

前書き

時間操作系のライブラリ・処理を実装時に最新の注意を払う処理は月またぎといった境界値だと思います。

今回自社のシステムでフレームワークのアップデート時に見つけたCarbonの関数の問題について書いてみようと思います。

なお今回のバージョンアップで、筆者らはCarbon1 から Carbon2へのアップデートしました。

※ ここのCarbonのナンバリングはバージョンを指しております。

例題

2019年3月30日 から1ヶ月前は、2019年2月28日 を指していてほしいところです。

<?php 
use Carbon\Carbon;
$day = Carbon::parse('2019-03-30 00:00:00', 'Asia/Tokyo');
echo $day->subMonth();
?>

この結果は

2019-03-02 00:00:00。

1ヶ月前指定して、月跨いでねぇじゃん!(寺田心くん風に)

ということで、「Carbon 月またぎ subMonth」なんて調べると、

<?php
use Carbon\Carbon;
$day = Carbon::parse('2019-03-30 00:00:00', 'Asia/Tokyo');
echo $day->subMonthNoOverFlow();
?>

なんて書かれています。

ただ、これができるのは、Carbon1までで、Carbon2になるとメソッドが削除されているので、Undefined Functionってなります。

なので、別の対策が必要になります。

解消法

Carbon::useMonthsOverflow(false) を使いましょう
<?php
use Carbon\Carbon;
Carbon::useMonthsOverflow(false); // ← 追加
$day = Carbon::parse('2019-03-30 00:00:00', 'Asia/Tokyo');
echo $day->subMonth(); // 2019-02-28 00:00:00

$day = Carbon::parse('2019-01-30 00:00:00', 'Asia/Tokyo');
$day->addMonth();
echo $day; // 2019-02-28 00:00:00;
?>

上の例で、月の減算を使いましたが、加算も同様に解決できます。

私自身、この手の障害を過去に経験したので、過敏に反応してしまうのですが、

今回気づけてよかったなと思ってます。