strtotimeの罠

PHPのstrtotimeという便利な関数がありますが、落とし穴があったりします。引数に「-1 month」「+1 month」とかを渡すと、前月とか来月のタイムスタンプを取得してくれるんですが、月末とかだと、挙動が怪しくなるので注意が必要なんですよ。

■ 例えば2008年10月31日に前月と翌月の「年月」を取得する。

<?php
echo date('ym',strtotime('-1 month'))."\n";//200809が欲しい
echo date('ym',strtotime('+1 month'))."\n";//200811が欲しい

こんな風に書くと実行結果はこんな風になるんですよ。

200810
200812

ミラン・バロシュ!!wwwな結果になりますねw
まぁ理由は単純?でこんな感じです。

  • 9月31日は存在しないので代わりに10月1日が返って来てしまう。
  • 11月31日は存在しないので代わりに12月1日が返って来てしまう。

正確に翌月、先月が欲しかったらこんな感じにすれば、大丈夫だと思います。だって1日がない月はないからね。

<?php
//なんかイケてない気がするけど
echo date('ym',strtotime('-1 month',mktime(0,0,0,date('m'),1,date('Y'))))."\n";
echo date('ym',strtotime('+1 month',mktime(0,0,0,date('m'),1,date('Y'))))."\n";

//少しは短くなったけどこれもなんだなー。
echo date('ym',strtotime('-1 month',strtotime(date('Ym01'))))."\n";
echo date('ym',strtotime('+1 month',strtotime(date('Ym01'))))."\n";

//てかstrtotimeを無理して使わんでよろし。便利だけどね。
echo date('ym',mktime(0,0,0,date('m')-1,1,date('Y')))."\n";
echo date('ym',mktime(0,0,0,date('m')+1,1,date('Y')))."\n";

常識じゃんと思った方もいるかもしれませんが、知らない人がコレに関する不具合を作り込んでしまったら、月末じゃない時は正常に動いてるように見えるから、見つけづらいだろうなーと思って書いておきました。

*1:この記事で先月の日付文字列を取得したいのに、取得した文字列をぶち込む変数名が「next_month」なのは是如何に?