PHPで前月・翌月の末日を取得する。

PHPで前月・翌月の末日を取得するときに気を付けないといけない点。
dateとstrtotimeを用いて翌月の末日を取得したいときに以下のように当月末日(2017-01-31)を指定しても期待した結果と異なる。

echo date('Y-m-d', strtotime('+1 month' . '2017-01-31'));
// 期待した結果:2017-02-28
// 実際の結果:2017-03-03

これはphp.netにも注意書きがされている。
http://php.net/manual/ja/datetime.formats.relative.php

月数を相対指定すると、その途中に経過する月の日数を使って結果を算出します。 たとえば “+2 month 2011-11-30” の結果は “2012-01-30” となります。 11 月の日数は 30 日、12 月の日数は 31 日なので、 その合計である 61 日後となるわけです。

前月・翌月の末日を取得したいときは以下のようにする。

echo date('Y-m-d', strtotime('last day of previous month' . '2017-01-31'));
// 結果:2016-12-31

echo date('Y-m-d', strtotime('last day of next month' . '2017-01-31'));
// 結果:2017-02-28

// 月の途中でも計算してくれる。
echo date('Y-m-d', strtotime('last day of previous month' . '2017-01-15'));
// 結果:2016-12-31

おまけ
末日ではなく前月・翌月の初日を取得したいとき。

echo date('Y-m-d', strtotime('first day of previous month' . '2017-01-31'));
// 結果:2016-12-01

echo date('Y-m-d', strtotime('first day of next month' . '2017-01-31'));
// 結果:2017-02-01

// 月の途中でも計算してくれる。
echo date('Y-m-d', strtotime('first day of previous month' . '2017-01-15'));
// 結果:2016-12-01

以下のsandboxサイトを用いてPHP 5.6.40, 7.4.33, 8.2.5で確認した。
https://legacy-sandbox.onlinephpfunctions.com/

本記事のコードをsandboxサイトにそのまま貼り付けるとタイムゾーンのwarningが出力されるので、最初にタイムゾーンの設定をした方が実行結果が見やすい。

date_default_timezone_set("Asia/Tokyo");

コメント

タイトルとURLをコピーしました