はじめに
PHPで日付の計算をしていて、1ヶ月後や2ヶ月後の日付を求めたいというケースはよくあります。
2019年1月28日の1ヶ月後が2019年2月28日であることに異論がある人はいないはずです。
ただ、2019年1月29日の1ヶ月後として2019年3月1日という値が欲しい場合と2018年2月28日という値が欲しい場合の2つがあると考えられます。
今回はこの両者を求める方法を備忘として残して置こうと思います。
前者を求める方法
2019年1月29日の1ヶ月後が2019年3月1日である場合です。
こちらは単純でPHPの標準関数のstrtotime
の第1引数に+1 month
のように相対書式を渡してあげれば求めることができます。1
strtotime('+1 month');
後者を求める方法
2019年1月29日の1ヶ月後が2019年2月28日である場合です。
まずはいきなりソースから。
function addMonths( $date, $add_months ){
//◯ヶ月後の末日
$lastDay = strtotime("last day of +".$add_months." month", $date);
//◯ヶ月後
$day = strtotime("+".$add_months." month", $date);
if ( $day < $lastDay ){
return $day;
}else {
return $lastDay;
}
}
分かりやすいように下に具体例を表で表しました。
基本的には、1ヶ月後の日付より1ヶ月の末日の方が大きいです。
ただ、当該の日付がない場合は、一ヶ月後の日付の方が大きくなります。
それぞれのケースで欲しい値が異なるので、ifで◯ヶ月後の末日と◯ヶ月後の日付(前者のパターン)を比較してどちらを返すかを決めています。
1ヶ月後の日付 | 1ヶ月の末日 | |
---|---|---|
2018-10-20 | 2018-11-20(正解) | 2018-11-30 |
2019-01-29 | 2019-03-01 | 2019-02-28(正解) |
余談
strtotime("last day of +1 month")
とすると、内部的には以下の順で処理されているみたいです。
- 1月29日の1ヶ月後は2月29日 ←+1 month
- 2月の末日は2月28日← last day of
1の段階では3月1日に変換されないみたいですね。