2009-11-01
PHPで、先月、翌月などを扱うときの注意
※ かなり初歩的な話ですのでご了承ください
PHPで、先月、翌月の月を取得するような場合、以下のようなプログラムを書いてしまいませんか?
echo '先月 => '. date('m', strtotime('-1 month')) .'<br>';
echo '今月 => '. date('m') .'<br>';
echo '翌月 => '. date('m', strtotime('+1 month')) .'<br>';
------ 結果 ------
前月 => 10
今月 => 11
翌月 => 12
(今日を11月01日とした場合です)
上記の結果は期待した結果で現状11月01日の場合は問題ありません。
ところが、10月31日の場合を例にとって見ます。
echo '前月 => '. date('m', strtotime('2009-10-31 -1 month')) .'<br>';
echo '今月 => '. date('m', strtotime('2009-10-31') ) .'<br>';
echo '翌月 => '. date('m', strtotime('2009-10-31 +1 month')) .'<br>';
------ 結果 ------
先月 => 10
今月 => 10
翌月 => 12
大変なことに、先月が10になってしまいました。
もっと、過去にもどって見てみると
for($i=1;$i<=12;$i++){
echo $i. 'ヶ月前 => '. date('m', strtotime('2009-10-31 -'.$i.' month')) .'<br>';
}
------ 結果 ------
1ヶ月前 => 10
2ヶ月前 => 08
3ヶ月前 => 07
4ヶ月前 => 07
5ヶ月前 => 05
6ヶ月前 => 05
7ヶ月前 => 03
8ヶ月前 => 03
9ヶ月前 => 01
10ヶ月前 => 12
11ヶ月前 => 12
12ヶ月前 => 10
もう、ありえないことになってしまいますね。
よく見ると31日のある日とない日で計算が狂ってしまうという内容です。
2月にいたっては、29〜31日もアウトですね。
これはおそらく10月31日の1ヶ月前は9月31日となり
9月31日とは9月30日の次の日だから10月1日のことになるってことでしょう。
そのため、10月31日の1ヶ月前の月は10月って事になります。
strtotime の -1 month とは、日付はそのままで月だけ1減らすという意味で
決して先月にシフトするという意味ではない。
関数を作った側の理屈はなんとなくあっている気がするのですが
使ってる側にしてみると間違いやすいポイントかなと思います。
従いまして、先月、翌月とかを正確に取得するには現在の日を考慮いれて
今月の1日から起算して1ヶ月前とかになるようにします。
echo '先月 => '. date('m', strtotime(date('Y-m-1').' -1 month')) .'<br>';
echo '今月 => '. date('m') .'<br>';
echo '翌月 => '. date('m', strtotime(date('Y-m-1').' +1 month')) .'<br>';
------ 結果 ------
前月 => 10
今月 => 11
翌月 => 12
for($i=1;$i<=12;$i++){
echo $i. 'ヶ月前 => '. date('m', strtotime(date('Y-m-1').' -'.$i.' month')) .'<br>';
}
------ 結果 ------
1ヶ月前 => 10
2ヶ月前 => 09
3ヶ月前 => 08
4ヶ月前 => 07
5ヶ月前 => 06
6ヶ月前 => 05
7ヶ月前 => 04
8ヶ月前 => 03
9ヶ月前 => 02
10ヶ月前 => 01
11ヶ月前 => 12
12ヶ月前 => 11
ぶっちゃけ、昨日上記のバグを発見したからこのエントリーなんですけどね(汗)
かなり初歩的なバグが混入していて情けない思いをしました。未熟者です。
こんなのは常識だよーって言われそうですが、知らない人がいましたら後学のために参考になれば幸いです。
トラックバック - http://d.hatena.ne.jp/bushimichi/20091101/1257007448
リンク元
- 44 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja-JP-mac:official&hs=Qpo&num=20&newwindow=1&q=mod_proxy+ssl&btnG=検索&lr=lang_ja&aq=f&oq=
- 32 http://sai10sight.typepad.jp/sai10sight/2009/11/linuxhamachi2-a.html
- 27 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4ADBR_jaJP328JP328&q=IE+ちらつき セレクトボックス
- 13 http://www.google.co.jp/search?hl=ja&lr=lang_ja&client=firefox-a&rls=org.mozilla:ja:official&hs=2dl&q=jabascript+ip取得&start=10&sa=N
- 12 http://d.hatena.ne.jp/katsat/20090422/1240413907
- 10 http://www.google.co.jp/search?client=firefox-a&rls=org.mozilla:ja:official&channel=s&hl=ja&source=hp&q=PHP 日付の減算&lr=&btnG=Google+検索
- 8 http://www.google.co.jp/search?hl=ja&source=hp&q=ie6+javascript+動かない&lr=&aq=2&oq=ie6+java
- 8 http://www.google.com/search?hl=ja&rls=com.microsoft:ja:IE-SearchBox&rlz=1I7ADBS_ja&q=content-type+image/jpg+AU&lr=&aq=f&oq=
- 7 http://www.google.co.jp/search?hl=ja&safe=off&client=firefox-a&rls=org.mozilla:ja:official&tbo=1&num=30&tbs=qdr:y&q=postgresql+複数+起動&btnG=検索&lr=lang_ja&aq=0&oq=postgreSQL+複数+
- 6 http://b.hatena.ne.jp/entry/d.hatena.ne.jp/bushimichi/20080910/1221040110




対処方法助かりました!こいう記事助かりますっ
間違いやすいポイントだと思いますので
私の失敗を共有できたらと思います。