PHPで月末の日付を取得する方法について

By | 2016/11/06

PHPの月末を取得する方法は少し変です。直感的ではないというかなんというか。
通常は以下のように書けば良いです。

// 今日の月末の日付を取得
date('Y-m-t' , strtotime('now'));  => 2016-04-30など

 

しかし、例えば2016-10-31の1ヶ月前の末日を取得する場合以下のように書くのが素直な形でしょう。しかし欲しい答えは返ってきません。

// 2016-10-31の1ヶ月前の月末の日付を取得
date('Y-m-t' , strtotime('2016-10-31' . ' -1 month'));  => 2016-10-31!?
// ちなみに2ヶ月前は・・正しい
date('Y-m-t' , strtotime('2016-10-31' . ' -2 month'));  => 2016-08-31

どうやら2016-10-31の前の月は2016-09-31!?と思っているのか、しかしその日はないので正常な答えを返せないでいるようです。
また03-30は30日ですが、2月に30日はないので、03-30の1ヶ月前の末日も正常な答えを返してくれません。

 

そういうわけで29、30、31日に今日の1ヶ月前後の末日はなどと一番最初の書き方で書くとひどい目にあいます!!これ本番のサービスで使ってたら本当にまずいことになることもあるでしょう。

私は運営用のサイトで過去のデータの集計を表示する際に以下のような書き方をしていて、ちゃんと表示されないというクレームを何度かいただいて気づきました。最初は全然コードに問題がなさそうだったので気づけませんでした。

// 1ヶ月ごとの集計データを取得
$current = 0;
for($i=0 ; $i<7 ; $i++, $current--){
    $begin_date = date('Y-m-t' , strtotime(($current-1) . " month"));
    $end_date   = date('Y-m-t' , strtotime($current     . " month"));

    // 集計処理
}

 

そんなわけで正常な末日を欲しい場合はその月の1日の日付を一旦取得してその次にその前後の末日を取れば問題を回避できます。

// 2016-10-31の1ヶ月前の月末の日付を取得
date('Y-m-t' , strtotime('2016-10-01' . ' -1 month'));  => 2016-09-30
date('Y-m-t' , strtotime('2016-10-01' . ' -2 month'));  => 2016-08-31

// 一般的な書き方は
date('Y-m-t' , strtotime(date('Y-m-01') . ' -1 month'));

注意しましょう!


コメントを残す

メールアドレスが公開されることはありません。