【PHP】年月の文字列を DateTime にする際の注意点

2023/01 のような文字列を DateTime クラスにする際の注意点を紹介します。

注意すべきコード

DateTimeImmutable::createFromFormat() を利用して、次のようなコードを書いた場合、 実行日によっては想定していないオブジェクトが生成される可能性があります。

$dt = DateTimeImmutable::createFromFormat('Y/m', '2023/02');

// 2023/01/15 に実行した場合
echo $dt->format('Ym');    // 202302

// 2023/01/31 に実行した場合
echo $dt->format('Ym');    // 202303

DateTimeImmutable::createFromFormat() では、解析しないフィールドは現在の日付や時刻で初期化されます。 そのため、2023/01/31 に年月のみ 2023/02 を指定すると、2023/2/31 → 2023/3/3 となります。

回避策

この事象を回避するにはフォーマットの指定に | を追加して、Ym| のようにすると想定する値を取得することができます。 | はすべてのフィールドをゼロ相当の値(※)に設定します。

※ゼロ相当の値は 1970-01-01 00:00:00.000000 UTC となります。

$dt = DateTimeImmutable::createFromFormat('Y/m|', '2023/02');

参考