ミリ秒から日付形式mdY H:i:suを取得する


117

ミリ秒からマイクロ秒を含むフォーマットされた日付を取得しようとしています。

唯一の問題は私が000000を取得し続けることです

date("m-d-Y H:i:s.u", $milliseconds/1000);

例。07-28-2013 11:26:14.000000


6
質問がミリ秒の変換を要求するのは奇妙ですが、マイクロ秒の変換方法はだれでも答えます。私はあなたが両方の間で変換できることを知っていますが、PHP docまたは他の場所から無関係なコードをコピーして貼り付ける代わりに、実際に質問に答えるのが良いでしょう。
Laurent

久しぶりですが、バモッサの答えはここで見つけた中で最高でした
ピイン

回答:


122

php.netさんのコメント

マイクロ秒(PHP 5.2.2で追加)。注date()常に生成されます。000000一方で、それは、整数パラメータを取りますので、DateTime::format()サポートマイクロ秒があればないDateTimeマイクロ秒で作成されました。

だから簡単に使う:

$micro_date = microtime();
$date_array = explode(" ",$micro_date);
$date = date("Y-m-d H:i:s",$date_array[1]);
echo "Date: $date:" . $date_array[0]."<br>";

dateTime()参照からの推奨および使用クラス:

$t = microtime(true);
$micro = sprintf("%06d",($t - floor($t)) * 1000000);
$d = new DateTime( date('Y-m-d H:i:s.'.$micro, $t) );

print $d->format("Y-m-d H:i:s.u"); // note at point on "u"

uはマイクロ秒です(1秒= 1000000 µs)。

php.netの別の例:

$d2=new DateTime("2012-07-08 11:14:15.889342");

参考dateTime()php.net

私は質問に対して簡潔に、そして作者にとって単純化して答えました。作成者への詳細については、ミリ秒から日付形式mdY H:i:suを取得するを参照してください。


4
読みやすく、理解しやすい2番目のフォームを選択します。さらに、DateTimeは日付/時刻関数よりもはるかに柔軟で堅牢です。マイクロ秒の処理は適切なケースです。
ハーバート

私はハーバートに同意します。@slik、これが最良の答えです:)
Marco Sulla

3
@GeoとAlBundyは、php <5.2.2のマシンでこれを試しているのでしょうか?PHP 5.4.39はこれを完璧に実行します...
RichardBernards

これは簡単ではないでしょうか?日付( 'mdY H:i:s')。(int)microtime(true);
Anant、

@Anant、それは確かに非常に簡単でしょう。しかし、間違っています。;)そこに到達するのは秒単位のエポックだけです。(残念ながら、microtime(false)どちらでも機能しません。)
Sz。

138

これは、入力フォーマットで簡単に実行できますU.u

$now = DateTime::createFromFormat('U.u', microtime(true));
echo $now->format("m-d-Y H:i:s.u");

これにより、次の出力が生成されます。

04-13-2015 05:56:22.082300

日付形式のPHPマニュアルページから:

  • U = Unixエポックからの秒数
  • u =マイクロ秒

http://php.net/manual/en/function.date.php


元の回答の欠陥を指摘してくれたgiggseyに感謝します。number_format()行を追加すると、正確な2番目のケースが修正されます。残念なことに、これ以上エレガントではありません...

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));

http://php.net/manual/en/function.number-format.php


DaVeに対応するタイムゾーンに関する注意。

通常、createFromFormat()ローカルタイムゾーンが指定されていない場合、メソッドはローカルタイムゾーンを使用します。

http://php.net/manual/en/datetime.createfromformat.php

ただし、ここで説明する手法は、DateTimeオブジェクトを使用して初期化しています。 microtime()、Unixエポック(1970年1月1日00:00:00 GMT)から経過した秒数を返すいます。

http://php.net/manual/en/function.microtime.php

これは、DateTimeオブジェクトが暗黙的にUTCに初期化されることを意味します。これは、経過時間を追跡するだけのサーバー内部タスクに適しています。

特定のタイムゾーンの時刻を表示する必要がある場合は、それに応じて設定する必要があります。ただし、これは、上記で説明した理由により、初期化後に(3番目のパラメーターを使用せcreateFromFormat())別のステップとして実行する必要があります。

setTimeZone()方法は、この要件を達成するために使用できます。

http://php.net/manual/en/datetime.settimezone.php

例として:

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
echo $now->format("m-d-Y H:i:s.u") . '<br>';

$local = $now->setTimeZone(new DateTimeZone('Australia/Canberra'));
echo $local->format("m-d-Y H:i:s.u") . '<br>';

次の出力を生成します。

10-29-2015 00:40:09.433818
10-29-2015 11:40:09.433818

mysqlに入力する場合、時間形式は次のようにする必要があることに注意してください。

format("Y-m-d H:i:s.u")

19
注:正確な秒で実行さDateTime::createFromFormat('U.u', microtime(true));れるとfalseを返しますmicrotime(true)。「1438616239.000000」ではなく「1438616239」を返します。
giggsey、2015

1
素晴らしい解決策、ありがとうございます。マイクロタイムから$ nowを作成するために現地時間を失っているようです。何か案が?
2015年

1
@daVeタイムゾーンに関する情報をいくつか追加しました。それがあなたが求めていたものであることを願っています。
ArchCodeMonkey 2015年

1
number_formatそれが正確な二にない場合でも、常に必要です。それ以外の場合、precisionPHP構成オプション( "display"用)に翻弄されます。これは、デフォルトではPHP 7.0の時点では十分に高くないため、精度が失われます(マイクロ秒までは正確ではありません)。
Teoh Han Hui

1
StackOverflowで常に下にスクロール
tom10271

15

これは少し短いアプローチです。高精度の数値の日付/時刻を作成するのではなく、マイクロ秒の値を文字列に変換し、を削除して0、日付/時刻の文字列の末尾に追加します。文字列の長さパラメーターを調整することで、小数点以下の桁数を簡単にトリミングできます。ここでは4ミリ秒を取得するために使用していますが、7マイクロ秒を取得するために使用することもできます。

$t = explode(" ",microtime());
echo date("m-d-y H:i:s",$t[1]).substr((string)$t[0],1,4);

microtime()の値がの0.98236000 1407400573場合、これはを返します08-07-14 01:08:13.982


9

私は使っています

echo date("Y-m-d H:i:s.").gettimeofday()["usec"];

output: 2017-09-05 17:04:57.555036

6
echo date('m-d-Y H:i:s').substr(fmod(microtime(true), 1), 1);

出力例:

02-06-2019 16:45:03.53811192512512

小数点以下の桁数を制限する必要がある場合は、下の行(クレジットmgutt)が適切な代替手段になります。(以下のコードでは、6は小数点以下の桁数を6に制限します。)

echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));

出力例:

02-11-2019 15:33:03.624493

秒の精度と先行ゼロを逃しました。したがって、正しいバージョンはになるはずですecho date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));。必要な理由の説明09stackoverflow.com/a/28739819/318765
mgutt

精度を逃した;)echo date('H:i:s').substr(fmod(microtime(true), 1), 1, 7);
mgutt

しかし、注意してください、substr()丸めません。そして、それと組み合わせてround()、末尾のゼロを削減します:stackoverflow.com/questions/7493305/…それが私が提案した理由sprintf()です。
mgutt

@mgutt最初の数字がゼロにならないのはいつですか?基本的に必要なのは、fmodから余りを1で取得するときに常に存在するゼロを削除することだけです。質問ではマイクロ秒を要求しますが、秒の小数点以下の形式をとります。小数点以下の桁数を制限する理由はありません。小数点以下の桁数が多いほど、精度が高くなります。
ghbarratt

@mgutt私はあなたの最初の提案された代替案を私の答えに追加しました、それは必要に応じて小数点以下の桁数を制限する良い方法であると説明しました
ghbarratt

3

(new Date()).toISOString()なんらかの理由でJavaScriptのような日付をフォーマットしたい場合は、PHPでこれを行う方法を次に示します。

$now = microtime(true);
gmdate('Y-m-d\TH:i:s', $now).sprintf('.%03dZ',round(($now-floor($now))*1000));

出力例:

2016-04-27T18:25:56.696Z

整数を差し引いても小数部分の精度が低下しないことを証明するだけです。

>>> number_format(123.01234567890123456789,25)
=> "123.0123456789012408307826263"
>>> number_format(123.01234567890123456789-123,25)
=> "0.0123456789012408307826263"

PHP 小数点以下を丸めましたが、どちらの場合も同じように丸めました。


1
いいえ。浮動小数点数の計算は使用しないでください。正確ではありません。また、いくつかの関数を呼び出す時間を無駄にしないでください。substr()を使用して、フォーマットされた日付を小数点以下3桁に切り捨てます。
LS 2016年

@LS Truncatingは、おそらくさらに不正確な3番目の10進数を丸めません。本当に小さい精度に入るまで、フロートは故障しません。小数点以下3桁で問題ありません。実際、私は精度をまったく変更していないと思います。浮動小数点数は、0に近づくほど正確になります。整数を減算しても、小数点以下の桁数は変更されません。
2016年

どうdate('Y-m-d\TH:i:s', $time / 1000) . sprintf('.%03dZ', substr($time, 10));ですか?
F8ER

@ F8ERもしあなた$timeがすでにミリ秒単位であるなら、ええ、それは技術的にはうまくいくでしょう。愛していないsubstrハックを、私はそれが2001と2286.の間の日付のために働くだろうと思います
MPEN

はい、これ$timeはMSですが、は2286どうですか、なぜそう思うのか、どうしてそのように脱出することができるのでしょうか?
F8ER

3

これはArchCodeMonkeyからの回答に基づいています。

しかし、単純化して、機能する簡単なものが必要な場合は、

function DateTime_us_utc(){
    return DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
}
function DateTime_us(){
    $now = DateTime_us_utc();
    return $now->setTimeZone(new DateTimeZone(date_default_timezone_get()));
}

それで私にとっては

$now = DateTime_us();
$now->format("m-d-Y H:i:s.u");

3

これがもう少しエレガント/シンプルな方法です。

echo date('Y-m-d-H:i:s.').preg_replace("/^.*\./i","", microtime(true));

1
// Procedural
$fineStamp = date('Y-m-d\TH:i:s') . substr(microtime(), 1, 9);
echo $fineStamp . PHP_EOL;

// Object-oriented (if you must). Still relies on $fineStamp though :-\
$d = new DateTime($fineStamp);
echo $d->format('Y-m-d\TH:i:s.u') . PHP_EOL;

1

PHP 7.1以降では、これを簡単に行うことができます。

$date = new DateTime( "NOW" );
echo $date->format( "m-d-Y H:i:s.u" );

次のように表示されます。

04-11-2018 10:54:01.321688

0

ドキュメントには次のように書かれています:

マイクロ秒(PHP 5.2.2で追加)。date()は整数パラメーターを取るため、常に000000を生成しますが、DateTime :: format()はマイクロ秒をサポートしていることに注意してください。

つまり、代わりにDateTimeを使用します。


6
これは動作しません!DATE_FORMAT(新しい日時()、 'U')はゼロを与える:phpfiddle.org/lite/code/ggh-mvz
ジャニスElmeris

上記の回答(および私の試用)のとおり、はいの場合はnew DateTime()0000が返されます。ただし、インスタンス化するときにマイクロ秒の精度の時間を指定すると、問題なく動作します。
scipilot 2014年

@scipilotわかりました。どうすればよいですか。
Geo

@Geoは受け入れられた答えを参照してください。new DateTime( 'Y-m-d H:i:s.'.$micro);
scipilot 2014年

0

PHP 7.0以降では、次のことが可能です。

$dateString = substr($millseconds_go_here,0,10);
$drawDate = new \DateTime(Date('Y-m-d H:i',$dateString));
$drawDate->setTimezone(new \DateTimeZone('UTC'));

これは次のことを順番に実行します。

  1. 文字列から最後の4つのゼロを削除してDate()、日付を処理できるようにします。
  2. 日付を使用して、ミリ秒をDateTimeが理解できる日付時刻文字列にフォーマットします。
  3. DateTime()これにより、現在のタイムゾーンを変更できるようになりますが、関数とクラスdate_default_timezone_set("Timezone");を使用DateTime()する前に設定されていることを確認してください。
  4. DateTime()クラスまたは関数が使用されるときは、クラスでコンストラクターを使用して、正しいタイムゾーンにあることを確認することをお勧めします。

0

Carbonを使用している場合は、定義された仕様「RFC3339_EXTENDED」を使用できます。またはそれをカスタマイズします。

Carbon::RFC3339_EXTENDED = 'Y-m-d\TH:i:s.vP';

0

@ArchCodeMonkeyの回答に基づいています。

あなたが持っているdeclare(strict_types=1)場合は、2番目の引数を文字列にキャストする必要があります

ここに画像の説明を入力してください


0

いくつかの方法でベンチマークを行いました。

1)マイクロタイム+ sscanf +日付:

sscanf(microtime(), '0.%6s00 %s', $usec, $sec);
$date = date('Y-m-d H:i:s.', $sec) . $usec;

microtime()がマイクロ秒の部分に10文字(0.dddddd00)を返す理由がわかりませんが、誰かが教えてくれますか?

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { sscanf(microtime(), '0.%6s00 %s', $usec, $sec); $date = date('Y-m-d H:i:s.', $sec) . $usec; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "22372.335910797 ms" // macOS PHP 5.6.30
string(18) "16772.964000702 ms" // Linux PHP 5.4.16
string(18) "10382.229089737 ms" // Linux PHP 7.3.11 (same linux box as above)

2)DateTime :: createFromFormat + Datetime-> format:

$now = new DateTime('NOW');
$date = $now->format('Y-m-d H:i:s.u');

PHP 5.xでは機能しない...

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = new DateTime('NOW'); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "45801.825046539 ms" // macOS PHP 5.6.30 (ms not working)
string(18) "21180.155038834 ms" // Linux PHP 5.4.16 (ms not working)
string(18) "11879.796028137 ms" // Linux PHP 7.3.11 (same linux box as above)

3)gettimeofday +日付:

$time = gettimeofday();
$date = date('Y-m-d H:i:s.', $time['sec']) . $time['usec'];

-

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $time = gettimeofday(); $date = date('Y-m-d H:i:s.', $time['sec']) . $time['usec']; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "23706.788063049 ms" // macOS PHP 5.6.30
string(18) "14984.534025192 ms" // Linux PHP 5.4.16
string(18) "7799.1390228271 ms" // Linux PHP 7.3.11 (same linux box as above)

4)microtime + number_format + DateTime :: createFromFormat + DateTime-> format:

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
$date = $now->format('Y-m-d H:i:s.u');

-

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', '')); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "83326.496124268 ms" // macOS PHP 5.6.30
string(18) "61982.603788376 ms" // Linux PHP 5.4.16
string(16) "19107.1870327 ms" // Linux PHP 7.3.11 (same linux box as above)

5)microtime + sprintf + DateTime :: createFromFormat + DateTime-> format:

$now = DateTime::createFromFormat('U.u', sprintf('%.6f', microtime(true)));
$date = $now->format('Y-m-d H:i:s.u');

-

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = DateTime::createFromFormat('U.u', sprintf('%.6f', microtime(true))); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "79387.331962585 ms" // macOS PHP 5.6.30
string(18) "60734.437942505 ms" // Linux PHP 5.4.16
string(18) "18594.941139221 ms" // Linux PHP 7.3.11 (same linux box as above)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.