株式会社プロネット

 

WEBシステム開発、ITコンサルティング、自社サービス、教育事業 - これからのビジネスへのIT活用ソリューションをご提案致します。

PHPで日付の月を加算する

2015.1.28(Wed) 21:26 | PHP | sofuku

特定の日付を元にnヶ月後を求める、という処理はよくあると思います。

月額課金や期限日などを求める際に、PHPでは通常strtotime関数を使いますが1ヶ月後などを算出する場合、ちょっと気をつけることがあります。

 

環境

PHP:5.3.3

 

strtotime関数

strtotime関数の詳細はこちらを参考にしてください。

n日後、とかであれば単純にこうすればOK。

 

// 2015-03-31の1日後
echo date('Y-m-d', strtotime('2015-03-31 +1 day'));
// 2015-04-01が算出される
?>

 

では1ヶ月後はというと、「month」を+1すればいいわけです。

しかし算出元の日付が末日だったりすると問題が発生します。

 

<?php
// 2015-03-31の1か月後
echo date('Y-m-d', strtotime('2015-03-31 +1 month'));
// 2015-05-01が算出される
?>

どうしてこうなるかというと、strtotime関数は2015-03-31の1ヶ月後を2015-04-31と算出します。

4月は30日までなので、+1日して5月1日が結果として返ってきます。

2015-04-30を返してほしいということで検索してみると、

同じような問題に悩んでいる方が作成した1ヶ月後の日付を返す関数があったので

参考にさせてもらい元になる日付と加算する月数を引数で指定できるようにしてみました。

 

<?php
    public function addMonth($date, $add_month) {
        // 年月日別に分離
        $year = date('Y', strtotime($date));
        $month = date('n', strtotime($date));
        $day = date('j', strtotime($date));
        
        // 年を跨ぐ場合
        if ($month + $add_month > 12) {
            $year++;
            $month = $month + $add_month - 12;
        } else {
            $month = $month + $add_month;
        }
        
        // 算出結果の日付を返す
        if (checkdate($month, $day, $year)) {
            return date('Y-m-d', strtotime(sprintf('%04d-%02d-%02d', $year, $month, $day)));
        } else {
            // 2月31日などになった場合、月末の日付を返す
            return date('Y-m-d', strtotime(sprintf('%04d-%02d-01 -1 day', $year, ($month+1))));
        }
    }
?>

年月日に引数の日付を分割し、加算する月数を月に足します。
年跨ぎした場合は年を+1し加算月数を算出しなおし、算出結果の日付が不正だった場合は翌月の1日から-1します。
この関数を使えば、nヶ月後の日付を求めることができます。