【PHP】0埋めされていない1桁の分をDateTime::createFromFormat()に入れたらfalseを返してきた
- 2021.08.01
- PHP
- DateTime::createFromFormat
とあるCSVファイルをインポートしてDBに登録するシステムの中でエラーが発生したので中を覗いてみた。すると日付変換のところでDateTime::createFromFormat()がfalseを返していた。
エラーが起きたコード
$importTime = '2021年08月01日 11時5分'; $date = DateTime::createFromFormat('Y年m月d日 H時i分', $importTime); $formated = $date->format('Y-m-d H:i');
$dateにfalseが返っているので、$date->format()が以下のエラーを吐いていた。
Call to a member function format() on bool
原因
どうやら入力ファイル内の日時の仕様が変更されていて日時を読み取れなくなっていたのが原因。具体的には、ヤフオクの売上CSVファイルなのだが、取扱日の欄で今までは「○年○月○日 ○時○分」の「時」「分」が0埋め2桁だったのに、ここひと月以内に仕様が変更されて、1桁の時は0埋めせず1桁のままで出力されていた。
DateTime::createFromFormat()の仕様
DateTime::createFromFormat()の「時」は「H」で拾えて、0埋めされていてもされていなくてもどちらでもOK。なのに対して、「分」は「i」で拾えるが、必ず0埋めされた2桁じゃないと拾ってくれないという仕様。「秒」も同様。
解決方法
そこで、DateTime::createFromFormat()にかける前に、0埋めされていない「分」に0を付けて対処。
$importTime = '2021年08月01日 11時5分'; // 0埋めされていない分に0を付ける $replaced = preg_replace('/時([0-9])分/', "時0\${1}分", $importTime); echo $replaced; // 2021年08月01日 11時05分
上記のコードは、入力する日時が’2021年08月01日 11時5分’のような場合で、単純に「分」をピンポイントで抽出して置き換えているだけなので、入力形式が違えばそれに合わせた置き換えコードが必要です。
ちなみに、秒も一緒に0埋めしたい場合
$importTime = '2021年08月01日 11時5分2秒'; // 0埋めされていない分と秒に0を付ける $replaced = preg_replace(['/時([0-9])分/', '/分([0-9])秒/'], ["時0\${1}分", "分0\${1}秒"], $importTime); echo $replaced; // 2021年08月01日 11時05分02秒
違ったアプローチから(結果は同じです)
$importTime = '2021年08月01日 11時5分2秒'; // 0埋めされていない分と秒に0を付ける $replaced = preg_replace_callback('/([0-9]*)分([0-9]*)秒/', function ($time) { return str_pad($time[1], 2, 0, STR_PAD_LEFT) . '分' . str_pad($time[2], 2, 0, STR_PAD_LEFT) . '秒'; }, $importTime); echo $replaced; // 2021年08月01日 11時05分02秒
-
前の記事
PHPでconsole.log(JavaScript)する1番簡単な方法 2019.07.10
-
次の記事
phpQueryで「Array and string offset access syntax with curly braces is deprecated」 2022.08.02
コメントを書く