【PHP】DateTimeクラスで 2020/06/31 が通っちゃった!?


環境

OS:CentOS 7.7
PHP: 7.1.26

現象

DateTimeクラス のコンストラクタで、日にちが31までなら、
存在しない年月日でも、正常に受け付けるようです(ただし翌月に繰り上がる。)

PHP歴は長いのに知らなかった。じつは常識なのか?

$date = new DateTime( '2020-02-28' ); // OK
$date = new DateTime( '2020-02-29' ); // OK
$date = new DateTime( '2020-02-30' ); // OK
$date = new DateTime( '2020-02-31' ); // OK
$date = new DateTime( '2020-02-32' ); // Error!

$date = new DateTime( '2020-06-30' ); // OK
$date = new DateTime( '2020-06-31' ); // OK
$date = new DateTime( '2020-06-32' ); // Error!

たしかに マニュアル には こっそり下記の説明があります。

// 存在しない値は繰り上がります
$date = new DateTime('2000-02-30');
echo $date->format('Y-m-d H:i:sP') . "\n";
    
2000-03-01 00:00:00-05:00

対策

日付チェックには checkdate() を併用したほうがよさそうです。