PHPでDateTime型の指定日時の1か月前と1か月後を算出する
PHPに限らず日付の加算減算は注意する必要があります。今回はPHPの DateTime オブジェクトを使った日付の操作で、1か月前、1か月後を取得する方法と例外に対処する方法を紹介します。
DateTime型の使い方
// 現在日時
$now = new DateTime();
$now->setTimeZone(new DateTimeZone('Asia/Tokyo'));
$now_str = $now->format('Y-m-d');
echo $now_str;
// 指定日時
$date = new DateTime('2016-11-01');
$date_str = $now->format('Y-m-d');
echo $date_str; // 2016-11-01
DateTime オブジェクトを new して、format() で出力形式を指定します。
1か月前を取得
modify()関数を使う
$date = new DateTime('2016-11-01 12:00:00');
$prev_date = $date->modify('-1 month')->format('Y-m-d H:i:s');
echo $prev_date; // 2016-10-01 12:00:00
modify(‘-1 month’) で1か月前 を指定しています。これで普通は1か月前の日付を取得することができるのですが、一部例外もあります。
$date = new DateTime('2016-03-31 00:00:00');
$prev_date = $date->modify('-1 month')->format('Y-m-d H:i:s');
echo $prev_date; // 2016-03-02 00:00:00
2016-03-31 の1か月前は 2016-02-29 ですよね。しかし、プログラム内では、1か月前は 2016-02-31 とまず定義されます。次に、この日付は実際には存在しない(29日まで)ので、不足した2日分を足して、2016-03-02 となるわけです。このような挙動をされては困る場合もあると思います。
例外を考慮する
$date = new DateTime('2016-03-31 00:00:00');
// 先月の末日
$last_date = new DateTime(date('Y-m-d H:i:s', strtotime('last day of previous month', $date->getTimestamp())));
$last_date = $last_date->format('Y-m-d H:i:s');
// 1か月前
$prev_date = $date->modify('-1 month')->format('Y-m-d H:i:s');
if ($last_date < $prev_date)
{
echo $last_date;
}
else
{
echo $prev_date;
}
先月の末日を取得する必要があるので、strtotime() 関数で取得します。あとは普通に modify() で1か月前を取得します。次に、両者を比較するif文を作り、条件分岐させます。これで、正しい日付が出力されます。
1か月後を取得
$date = new DateTime('2016-01-31 00:00:00');
$last_date = new DateTime(date('Y-m-d H:i:s', strtotime('last day of next month', $date->getTimestamp())));
$last_date = $last_date->format('Y-m-d H:i:s');
$next_date = $date->modify('+1 month')->format('Y-m-d H:i:s');
if ($last_date < $next_date)
{
echo $last_date;
}
else
{
echo $next_date;
}
仕組みは同じなので、一部変更して、あとは同様にするだけです。