これはなに?
PHPでstrtotime("- 1 month")とかstrtotime("+ 1 month")とか書いちゃだめだよって話です。
今日は何の日でしょう?
今日は、弊社の自動テストが落ちた日です。
昨日は落ちなかったのに、いったいなぜ今日落ちてしまったのでしょう。
なぜ落ちた?
それは今日が31日
だからです。
テストコードに現在時刻を使ったコードがありました。
ただし、現在時刻から+1ヶ月したり-1ヶ月したりして、相対的な日付でテストをしているので、
普段は時刻が変わることによる問題は起こっていませんでした。
しかし、今日初めて問題が発覚しました。
現在時刻から前月の月を取得する計算が31日だけおかしかったのです。
前月の計算の仕方(NGケース)
strtotime("- 1 month")
一見良さそうです。今から マイナス1ヶ月後の日付が取れそうです。
7/1なら6/1
7/20なら6/20
7/31なら7/1
( ゚д゚) ・・・
(つд⊂)ゴシゴシ
(;゚д゚) ・・・
(つд⊂)ゴシゴシゴシ
_, ._
(;゚ Д゚) …!?
0ヶ月前やん!
strtotime("+ 1 month")
の場合でも問題が起こります。
8/31の1ヶ月後は
10/1になってしまします。
2ヶ月後ですね。
正しい書き方
strtotime('first day of previous month');
strtotime('first day of next month');
参考コード
間違った例
date('Y-m-d H:i:s', strtotime('+ 1 Month', strtotime('2020/08/31 00:00:01')))
=> "2020-10-01 00:00:01"
>>> date('Y-m-d H:i:s', strtotime('- 1 Month', strtotime('2020/07/31 00:00:01')))
=> "2020-07-01 00:00:01"
正しい例
>>> date('Y-m-d H:i:s', strtotime('first day of previous month', strtotime('2020/07/31 00:00:01')))
=> "2020-06-01 00:00:01"
>>> date('Y-m-d H:i:s', strtotime('first day of next month', strtotime('2020/08/31 00:00:01')))
=> "2020-09-01 00:00:01"
参考
https://bugs.php.net/bug.php?id=44073
https://stackoverflow.com/questions/19727274/strtotime-bug-when-using-1-month-from-january