PHPで日付の加算、減算と先月を取得する際のおかしな挙動

  • このエントリーをはてなブックマークに追加
  • Pocket

スポンサードリンク

明日の日付や1週間後の日付、一時間後の時間などの日時の加算や、昨日の日付や昨年の日付などの日時の減算の方法をご紹介します。

strtotime()DateTimeクラスでのやり方をそれぞれ見ていきましょう。

先月の日付を取得する際は、月末日の関係でおかしな日付になることもあるため、その解決法にも触れています。

 

strtotime関数での加算、減算

※以下は今日が2016-1-29の場合

明日の日付を表示

どちらも明日の日付が表示されます。

+1 daytomorrowどちらでも明日の日付が取得できますね。

 1年後の日付を取得

ちょうど1年後の日付が取得できました。

ついでに、フォーマットも「年月日」にして表示させています。

所定の日付の翌日を表示

strtotime()に所定の日付を入れ、半角スペースで繋ぎました。

2015-12-31の翌日、つまり2016-01-01の日付が取得できています。

1時間後の時間を表示

※以下は現在の時刻が21:49の場合

昨日の日付を表示

昨日や昨年、先月などの減算もできますよ。

strtotime関数のフォーマット一覧

以下のようなフォーマットを使って日付の加算、減算ができます。

フォーマット説明サンプル
now現在の日時を取得2016/01/29 21:49:15
tomorrow明日の日付を取得2016/01/30 21:49:15
yesterday昨日の日付を取得2016/01/28 21:49:15
+1 day1日後の日時を取得2016/01/30 21:49:15
+1 week1週間後の日時を取得2016/02/05 21:49:15
+1 month1ヶ月後の日時を取得2016/02/29 21:49:15
+1 year1年後の日時を取得2016/03/01 21:49:15
+1 hour1時間後の日時を取得2016/01/30 22:49:15
+1 minute1分後の日時を取得2016/01/30 21:50:15
+1 second1秒後の日時を取得2016/01/30 21:49:16
last day of previous month先月の末日を取得2015/12/31

ただstrtotime()は2038年問題などもあり、DateTimeクラスを使うように推奨されることも多いようです。

次は、DateTimeクラスで同じことをやってみましょう。

DateTimeクラスで加算、減算

※以下は現在が2016-1-29 21:49の場合

modifyを使う

説明

DateTimeクラスでmodifyを使った日付の加算、減算は以下のようになっています。

$date = new DateTime();

  • まずnew DateTime();DateTimeオブジェクトを作る
  • そしてそのオブジェクトを変数$dateに格納

echo $date->modify(相対的な書式)->format(出力フォーマット);

  • 変数$datemodifyで加算、減算の相対的な書式で指定した日付に移動させる(tomorrow+1 day…など)
  • その日付をformatで指定した書式で表示させる

参考:PHPのアロー演算子(->)をできるだけ分かりやすく

変数$dateはオブジェクト型で、日時やタイムゾーンが格納されています。

そこから日付を->modifyで加算、減算させて、さらに->formatY-m-dの書式でフォーマットして表示しているんですね。

参考:PHPで日付や時刻をフォーマットする

先月の日付を取得する際は要注意!

日付の加算、減算で先月の日付を取得する場合の注意点です。

まずは下記サンプルをご覧ください。

先月の日付を取得

上記は問題なく1ヶ月前の日付が取れていますね。

それでは3/31の1ヶ月前だとどうなるでしょうか?

月によって末日が違うことで起きる弊害

3/31の1ヶ月前が3/2と出力されます。これは問題ですね!

理屈は以下のとおりです。

 

  1. 3/31の-1 monthは2/31と判定
  2. しかし2/31なんて日付はないから、実際に存在する2/29の次から2つ余った分を3月に自動的に変換してしまう(この年はうるう年ですw)
  3. そのまま3/2と表示された

月の加算、減算の場合のみ、1ヶ月前の日と、その月の末日と比較してちょっと一工夫する必要があります。

次の項目で、月の加算、減算の簡単なプログラムを作ってみました。

先月の日付を正確に表示させるプログラム

2016-02-29

3/31の1ヶ月前でもきちんと2月の末日の2/29と表示されました。

このプログラムの概要は以下のとおりです。

 

  1. 変数$dateに所定の日付を格納
  2. 変数$lastDayに先月末日を取得するコードを格納
  3. 変数$prev-1 monthした時の日付を格納
  4. if文で先月の末日と、日付を-1 monthして取得した日付を比較
  5. もし、日付を-1 monthして取得した日付の方が大きければ、先月末日を表示
  6. もし、先月末日と同じか、それよりも小さい日付ならば、日付を-1 monthして取得した日付を表示

ポイントは、2.のstrtotime()に設定したlast day of previous monthですね。

「前の月の最後の日」と直訳できるかと思いますが、先月の末日を取得するフォーマットです。

これで、簡単に先月末の正確な日付を取得できますね。

DateTimeクラスでも同じようにやってみましょう。

スポンサードリンク

  • このエントリーをはてなブックマークに追加
  • Pocket

コメントを残す

*