BLOG

ブログ

2021/09/14 技術系

【PHP】月末日付を扱う時は気をつけようという話

この記事を書いた人 K.T

PHPerにとっては今更感溢れる話題ですが、
2021/07/31の1ヶ月前を取得しようとしたら思っていた動きにならなかったのでメモ。

何が起きたか

$date = new Carbon('20210731')->subMonth(1);
echo($date);

このようにして2021/07/31の1ヶ月前を取得しようとしたが

2021-07-01 00:00:00

2021-06-30 00:00:00ではなく、2021-07-01 00:00:00が出力された。

なぜか

CarbonはDateTimeのラッパー

7/31から1ヶ月減算すると6/31になるが、6/31という日付は存在しない。
なので、6月の月末日の6/30と6/31の差分を計算し、6/30に日付を1日加算する。
結果として7/1になる。という動きをするとのこと。

解決策

Carbonを使う場合はsubMonthsNoOverflowを使う

$date = new Carbon('20210731');
echo($date->subMonthsNoOverflow(1));
2021-06-30 00:00:00
$date = new Carbon('20210731123005');
echo($date->subMonthsNoOverflow(1));
2021-06-30 12:30:05

補足

翌月版もある

$date = new Carbon('20210831123005');
echo($date->addMonthsNoOverflow(1));
2021-09-30 12:30:05

2021/08/31の翌月、2021/09/31は存在しない日付なので、
オーバーフロー分の日付を加算せずに2021/09/30が出力される。

アーカイブ