PHPで ISO 8601
のフォーマット('c')
を扱う際にハマりました。
他にも同じ罠にひっかかる人が出てこないことを願っています 🥱
ISO 8601 フォーマットについて
年、月、日、時間、分、秒と「タイムゾーン」を出力してくれる便利なフォーマットです。
多言語サイト等を扱う際、時差を考慮する際にとても便利なフォーマットですよね。
例
$datetime = new DateTime('now');
echo $datetime->format('c');
// 出力 2024-06-24T21:00:00+09:00
罠にハマりました
何故か c
フォーマットを createFromFormat
で Datetime
オブジェクトを生成しようとしてもうまくいかない...。
デバッグしようと ↓↓ を試してみました。
$datetime = new DateTime('now');
$create_format_datetime = Datetime::createFromFormat('c', $datetime->format('c'));
echo $create_format_datetime;
// 出力 false
え、false
になるんですね...。
なんでだよ。
原因
軽く調べました。
$datetime->format('c');
では.u
が含まれないです。
ただ、createFromFormat('c', $datetime);
では、.u
が入ることを期待しているみたい。
対策
もちろん回避策もあるようです。
パターン①
.u
を含める。
まぁ予想通りですね。ただ、わざわざ含める処理を追加実装するのもめんどいですよね。
こんな感じですかね。
$datetime = new DateTime('now');
$create_format_datetime = Datetime::createFromFormat('Y-m-d\TH:i:s.uP', $datetime->format('Y-m-d\TH:i:s.uP'))
echo create_format_datetime->format('c');
// 出力 2024-06-24T21:00:00+09:00
パターン②
new Datetime(${'c'のフォーマット})
で行けるみたい。
$datetime = new Datetime('now');
$create_datetime = new Datetime($datetime->format('c'));
echo $create_datetime->format('c');
// 出力 2024-06-24T21:00:00+09:00
うーん。こっちのほうがわかりやすいかも。
まとめ
やっぱり、タイムゾーンを含む日付データの受け渡しにはISO 8601
が便利ですよね。
クエリパラメータ等での活躍場面が今後も多そうです。
参考