MENU

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;
}

仕組みは同じなので、一部変更して、あとは同様にするだけです。