久々にPHPFXXK案件に遭遇してしまった・・・・・
やりたかったこと
一ヶ月前の今日を求める
例を挙げると
- 2016年4月28日 → 2016年3月28日
- 2016年1月28日 → 2015年12月28日
ただし2016年3月31日のように先月にその日付が存在しない(先月日数<今月日数)場合は先月末日を返してほしい
たったこれだけ
PHPで書いてみる
<?php // not work date_default_timezone_set('Asia/Tokyo'); echo date('Y-m-d', strtotime('2016-03-31 -1 month')); =>2016-03-02
ん??????????????????????????????
どうしてこうなった
そもそもPHPの日付の計算において、少なくとも◯ヶ月前、◯ヶ月後を求めようとすると単純につきの足し引きのみ行われる
- 2016-03-31の1ヶ月前は2016-02-31
- 2月は29日(2016年は閏年)までなので超過した日数は翌月に繰り越される
- 結果、2016-02-29に超過分の2日が足されて2016-03-02
改善策
モダン(笑)なDatetimeオブジェクトでも同じ結果だったので自分で関数作るしかない
<?php // 先月の当日求める function hoge($date){ $dt = new DateTime($date); $dt2 = clone $dt; return ($dt->modify('-1 month')->format('m')===$dt2->format('m')) ? $dt->modify('last day of previous month')->format('Y-m-d') : $dt->format('Y-m-d'); } echo hoge('2014-03-31'),PHP_EOL; echo hoge('2016-03-31'),PHP_EOL; echo hoge('2014-03-15'),PHP_EOL; echo hoge('2014-12-31'),PHP_EOL; echo hoge('2014-01-31'),PHP_EOL;
以下が返ってくるはず
2014-02-28 2016-02-29 2014-02-15 2014-11-30 2013-12-31