Hatena::ブログ(Diary)

bushimichiの日記 RSSフィード

この日記のはてなブックマーク数

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


ぶっちゃけ、昨日上記のバグを発見したからこのエントリーなんですけどね(汗)

かなり初歩的なバグが混入していて情けない思いをしました。未熟者です。

こんなのは常識だよーって言われそうですが、知らない人がいましたら後学のために参考になれば幸いです。

イケテルイケテル 2011/03/31 14:58 安易に便利関数と思い使用していて同じ症状が出ていました。
対処方法助かりました!こいう記事助かりますっ

bushimichibushimichi 2011/04/19 19:51 お役に立てて光栄です。
間違いやすいポイントだと思いますので
私の失敗を共有できたらと思います。

ikumiikumi 2011/06/08 17:50 今から参考に関数実装します!

seekerseeker 2013/07/12 11:44 事前のこちらの記事に出会えたことで、安全に実装することができました!
ありがとうございます!!

yohitosukeyohitosuke 2016/08/31 17:01 ツボにはまってました。。。
助かりました。
ありがとうございます!!

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証