【PHP】DateTime::createFromFormat の特殊文字で正規表現いらずの文字列 to 日時変換

  • 2021年7月2日
  • PHP

 PHP には任意のフォーマットで日時文字列を日時オブジェクト(DateTime, DatetimeImmutable インスタンス)に変換するメソッドである createFromFormat があります。これのフォーマット定義機能は強力であり、別途正規表現等で文字列を解析せずとも目的を果たしやすいです。
 フォーマットで使える文字列は次リンクの”format パラメータに渡せる文字”表にあります。
PHP: DateTime::createFromFormat – Manual
PHP: DateTimeImmutable::createFromFormat – Manual
 よくある年月日時分秒に加えて特殊文字を使った例が次です。

/** 例. 文字列先頭にある年月日だけ読んで後は捨てる */
echo DateTimeImmutable::createFromFormat('Y/m/d|+', '2021/02/28(謎の文字列) 1206:07.234')->format('Y-m-d H:i:s');
// 2021-02-28 00:00:00

Y/m/dで 2021/06/29 を読み取った後、|で時分秒を現在の時分秒を0時0分0秒にセットし、+で後に続く文字列がパース失敗してもエラーを起こさず黙らせます。
 これにより、不思議なフォーマットであっても文字列先頭のみで年月日を識別して DateTime オブジェクトとしていろいろできます。

 また、次の様にワイルドカードである?, *を使って多少の表記ゆれなら無視できるようなコードも作れます。

<?php
$dt = DateTimeImmutable::createFromFormat('Y/m/d(???) H:i', '2021/07/01(金) 17:39');
echo $dt->format('Y-m-d H:i:s');// 2021-07-01 17:39:00
echo '<br>';
$dt = DateTimeImmutable::createFromFormat('Y/m/d* H:i', '2021/07/01(金) 17:39');
echo $dt->format('Y-m-d H:i:s');// 2021-07-01 17:39:00
echo '<br>';
$dt = DateTimeImmutable::createFromFormat('Y/m/d* H:i', '2021/07/01(金 ) 17:39');
echo $dt->format('Y-m-d H:i:s');// 2021-07-01 17:39:00

?はバイト単位のワイルドカードのため自然言語に対しては少々扱い難いですが、*は区切り文字でも数字でもない文字を最長でマッチ、となっており使いどころはそれなりに多いです。また区切り文字限定のワイルドカード#があり、この辺りの曖昧な部分を吸収する特殊文字を使うと使いまわしのきくフォーマットにしやすいです。

<?php
$format = 'Y#m#d* H#i|+';
$dt = DateTimeImmutable::createFromFormat($format, '2021/07/01(金) 17:39');
echo $dt->format('Y-m-d H:i:s');// 2021-07-01 17:39:00
$dt = DateTimeImmutable::createFromFormat($format, '2021/07/01_17:39');
echo $dt->format('Y-m-d H:i:s');// 2021-07-01 17:39:00
$dt = DateTimeImmutable::createFromFormat($format, '2021/07/01 17:39');
echo $dt->format('Y-m-d H:i:s');// 2021-07-01 17:39:00
$dt = DateTimeImmutable::createFromFormat($format, '2021-07-01-17-39');
echo $dt->format('Y-m-d H:i:s');// 2021-07-01 17:39:00
$dt = DateTimeImmutable::createFromFormat($format, '2021-07.01(Fri) 17,39');
echo $dt->format('Y-m-d H:i:s');// 2021-07-01 17:39:00
$dt = DateTimeImmutable::createFromFormat($format, '2021-07.01(Fri) 17,39.123456');
echo $dt->format('Y-m-d H:i:s');// 2021-07-01 17:39:00
>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG