こんにちは〜
何となく釣りタイトルを作りたい気分だったので、こういうタイトルになりましたすいません。まぁ興味のある人は最後まで見てください〜(笑)
さて本題。phpでミリ秒ありの現在時刻を取得する際、どうやって取得しますか?
調べてみるとこういう感じのコードをよく見かけます。
$time = date("Y-m-d H:i:s") . "." . substr(explode(".", (microtime(true) . ""))[1], 0, 3);
出力例:2020-05-13 09:41:40.208(※アクセス時間によって変化しません。例です)
一見これでも大丈夫なように見えます。実際動いてますし。
じゃあ何がダメなのか。
explode(".", (microtime(true) . ""))[1]
ここです。
explode関数は、最初の引数の文字列で、二つ目の文字列を区切り、配列化します。
今回は、”.”(ピリオド)で、(microtime(true) . “”)を区切っています。
次に、microtime(true) 。これは現在時刻をマイクロ秒まで含めて返します。
これは、引数にtrueを指定すると、float値で返します。
1589363558.7723
こんな感じ。(編集時間バレそう)
さて、どこが問題かわかったでしょうか?
そう、microtime(true)です。これの戻り値はfloatで返すのが問題なのです。
例えば、下記はどう表示するのか。
echo 205.250; // 205.25 と出力
echo 306.100; // 306.1 と出力
echo 110.000; // 110 と出力
そう、小数点以下が.000になると、ドットが消えるのです!
ドットが消えるとどうなるかと言いますと、
explode(“.”, (microtime(true) . “”))
の値が、要素が1個の配列が返されるのです。
ということで、小数点以下が.0000の時に、下記を実行すると、
explode(".", (microtime(true) . ""))[1] //Undefined offset:エラーが起きる
まぁそもそもmicrotimeが小数点以下4桁まで出力するので、0000を出すのはごく稀ですが。
それでもエラーが起きてしまった場合、最初のコードの$timeにはnullが返されてしまいます。(warningエラーなので止まらない)
実装方法にもよりますが、時間操作で重要なコードを実行していると、大変なことになるかもしれません。(いや可視化の時間出力で重要なコードってあんまりないか・・・?)
ではどうするのか。変数に代入してifする?でもそれは面倒です。
簡単な方法があります。
ドットがなければ、ドットを作ればいいのです。(笑)
$time = date("Y-m-d H:i:s") . "." . substr(explode(".", (microtime(true) . ".000"))[1], 0, 3);
float型をstring型にしていた、 . “”に、.000を付け足すのです。
(ちなみに、.1200みたいな感じで、小数点以下が2桁になる時も3桁にしたい場合は、”000.000″にすると0埋めされますので、一石二鳥?)
こうすることで、仮にint型になるような値が返ってきても、.000が2つ目の要素となり、エラーにならずに返すことができるようになります。
改めて考えれば当たり前の配慮ですが、整数値になる可能性が1万分の1が故、あまり気付けなかった弱点です。
ちなみにこの記事を書いた理由は、このエラーが起きたからですね(笑)
唐突に予期しないところからエラーが起きてびっくりしました
ということで、またね〜
↓もしこの記事が参考になったら、下のいいねボタンを押していただけると非常に助かります!(ログイン不要)↓