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");
コメント