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