Abrufen des Datumsformats mdY H: i: su von Millisekunden

117

Ich versuche, ein formatiertes Datum zu erhalten, einschließlich der Mikrosekunden von Millisekunden.

Das einzige Problem ist, dass ich immer 000000 bekomme

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

Ex. 28.07.2013 11: 26: 14.000000

slik
quelle
6
Es ist seltsam, dass die Frage nach der Konvertierung von Millisekunden fragt , aber jeder antwortet, wie Mikrosekunden konvertiert werden. Ich weiß, dass Sie zwischen beiden konvertieren können, aber es wäre schön, die Frage tatsächlich zu beantworten, anstatt nicht verwandten Code aus dem PHP-Dokument oder anderswo zu kopieren und einzufügen.
Laurent
Ich weiß, es ist eine Weile her, aber Bamosszas Antwort war die beste, die ich hier gefunden habe
Piyin

Antworten:

122

php.net sagt:

Mikrosekunden (hinzugefügt in PHP 5.2.2). Beachten Sie, dass dies date()immer generiert wird, 000000da ein ganzzahliger Parameter verwendet wird, während DateTime::format()Mikrosekunden unterstützt werden, wenn diese DateTimemit Mikrosekunden erstellt wurden.

Verwenden Sie also so einfach:

$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>";

Empfohlen und dateTime()Klasse von referenziert verwenden:

$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"

Hinweis uist Mikrosekunden (1 Sekunde = 1000000 µs).

Ein weiteres Beispiel von php.net :

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

Referenz von dateTime()auf php.net

Ich habe die Frage als kurz beantwortet und dem Autor vereinfacht. Weitere Informationen zum Autor finden Sie unter: Abrufen des Datumsformats mdY H: i: su aus Millisekunden

Marin Sagovac
quelle
4
Ich entscheide mich im Allgemeinen für die zweite Form, da sie leichter zu lesen und zu verstehen ist. Darüber hinaus ist DateTime weitaus flexibler und robuster als die Datums- / Uhrzeitfunktionen. Der Umgang mit Mikrosekunden ist ein typisches Beispiel.
Herbert
Ich stimme Herbert zu. @slik, das ist die beste Antwort :)
Marco Sulla
3
@Geo und AlBundy Könnten Sie dies auf einem Computer mit PHP <5.2.2 versuchen? PHP 5.4.39 läuft dies einwandfrei ...
RichardBernards
Wäre das nicht einfach? Datum ('mdY H: i: s'). (int) Mikrozeit (wahr);
Anant
@Anant, es wäre in der Tat ganz einfach. Aber falsch. ;) Was du dort bekommst, ist nur die Epoche in Sekunden. (Würde leider auch nicht funktionieren microtime(false).)
Sz.
138

Sie können dies problemlos mit dem Eingabeformat tun U.u.

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

Dies erzeugt die folgende Ausgabe:

04-13-2015 05:56:22.082300

Auf der PHP-Handbuchseite für Datumsformate:

  • U = Sekunden seit der Unix-Epoche
  • u = Mikrosekunden

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


Vielen Dank an Giggsey für den Hinweis auf einen Fehler in meiner ursprünglichen Antwort. Durch Hinzufügen number_format()zur Zeile sollte der Fall der genauen Sekunde behoben werden . Schade, dass es sich nicht mehr ganz so elegant anfühlt ...

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

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


Ein Hinweis zu Zeitzonen als Antwort auf DaVe.

Normalerweise verwendet die createFromFormat()Methode die lokale Zeitzone, wenn keine angegeben ist.

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

Die hier beschriebene Technik initialisiert jedoch das DateTime-Objekt, mit microtime()dem die Anzahl der Sekunden zurückgegeben wird, die seit der Unix-Epoche (01. Januar 1970, 00:00:00 GMT) vergangen sind.

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

Dies bedeutet, dass das DateTime-Objekt implizit auf UTC initialisiert wird. Dies ist in Ordnung für serverinterne Aufgaben, die nur die verstrichene Zeit verfolgen möchten.

Wenn Sie die Zeit für eine bestimmte Zeitzone anzeigen müssen, müssen Sie sie entsprechend einstellen. Dies sollte jedoch aus den oben diskutierten Gründen als separater Schritt nach der Initialisierung erfolgen ( ohne Verwendung des dritten Parameters von createFromFormat()).

Das setTimeZone()Verfahren kann verwendet werden, um diese Anforderung zu erfüllen.

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

Als Beispiel:

$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>';

Erzeugt die folgende Ausgabe:

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

Beachten Sie, dass das Zeitformat sein muss, wenn Sie in MySQL eingeben möchten:

format("Y-m-d H:i:s.u")
ArchCodeMonkey
quelle
19
Hinweis: DateTime::createFromFormat('U.u', microtime(true));Gibt false zurück, wenn es microtime(true)genau in der Sekunde ausgeführt wird. Es wird '1438616239' anstelle von '1438616239.000000' zurückgegeben.
Giggsey
1
Tolle Lösung, danke. Es scheint, als würde ich meine Ortszeit verlieren und jetzt $ aus der Mikrozeit erstellen. Irgendeine Idee?
daVe
1
@daVe Ich habe einige Informationen zu Zeitzonen hinzugefügt. Ich hoffe, das war es, wonach Sie gesucht haben.
ArchCodeMonkey
1
Das number_formatist immer notwendig, auch wenn es nicht genau in der Sekunde ist. Andernfalls sind Sie der precisionPHP-Konfigurationsoption (für "Anzeige") ausgeliefert, die ab PHP 7.0 standardmäßig nicht hoch genug ist, was zu einem Genauigkeitsverlust führt (bis zur Mikrosekunde nicht genau).
Teoh Han Hui
1
Scrollen Sie
15

Hier ist ein etwas kürzerer Ansatz. Anstatt ein hochpräzises numerisches Datum / eine hochpräzise Uhrzeit zu erstellen, konvertiere ich den Mikrosekundenwert in eine Zeichenfolge, entferne die 0und füge sie am Ende der Datums- / Uhrzeitzeichenfolge hinzu. Ich kann die Anzahl der Dezimalstellen leicht reduzieren, indem ich den Parameter für die Zeichenfolgenlänge anpasse. hier verwende ich 4, um Millisekunden zu erhalten, aber Sie könnten verwenden 7, um Mikrosekunden zu erhalten.

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

Für einen microtime () -Wert von 0.98236000 1407400573wird zurückgegeben 08-07-14 01:08:13.982.

thotso
quelle
9

Ich benutze

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

output: 2017-09-05 17:04:57.555036
Bamossza
quelle
6
echo date('m-d-Y H:i:s').substr(fmod(microtime(true), 1), 1);

Beispielausgabe:

02-06-2019 16:45:03.53811192512512

Wenn Sie die Anzahl der Dezimalstellen begrenzen müssen, ist die folgende Zeile (credit mgutt) eine gute Alternative. (Mit dem folgenden Code begrenzt die 6 die Anzahl der Dezimalstellen auf 6.)

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

Beispielausgabe:

02-11-2019 15:33:03.624493
Ghbarratt
quelle
Sie haben die Präzision und die führende Null für Sekunden verfehlt. Also sollte die richtige Version sein echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));. Erklärung, warum wir brauchen 09: stackoverflow.com/a/28739819/318765
mgutt
Sie haben die Präzision wieder verpasst;)echo date('H:i:s').substr(fmod(microtime(true), 1), 1, 7);
mgutt
Aber Vorsicht, substr()rundet nicht. Und in Kombination round()damit würde die nachfolgenden Nullen schneiden: stackoverflow.com/questions/7493305/… Das ist der Grund, warum ich vorgeschlagen habe sprintf().
mgutt
@mgutt Wann wäre die erste Ziffer keine Null? Grundsätzlich ist es einfach erforderlich, die Null zu entfernen, die immer vorhanden ist, wenn der Rest von fmod um 1 abgerufen wird. Die Frage fragt nach Mikrosekunden, jedoch in Form von Dezimalstellen der Sekunden. Es gibt keinen Grund, die Anzahl der Dezimalstellen zu begrenzen. Mehr Dezimalstellen sind einfach eine bessere Genauigkeit.
Ghbarratt
@mgutt Ich habe Ihre erste vorgeschlagene Alternative zu meiner Antwort hinzugefügt und erklärt, dass dies eine gute Möglichkeit wäre, die Anzahl der Dezimalstellen bei Bedarf zu begrenzen
ghbarratt
3

Wenn Sie ein Datum wie JavaScript (new Date()).toISOString()aus irgendeinem Grund formatieren möchten, können Sie dies in PHP folgendermaßen tun:

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

Beispielausgabe:

2016-04-27T18:25:56.696Z

Nur um zu beweisen, dass das Subtrahieren der ganzen Zahl die Genauigkeit des Dezimalteils nicht verringert:

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

PHP hat die Dezimalstellen gerundet, aber in beiden Fällen auf die gleiche Weise gerundet.

mpen
quelle
1
Nein. Verwenden Sie keine Mathematik für die Gleitkommazahl, sie ist ungenau. Verschwenden Sie auch keine Zeit damit, mehrere Funktionen aufzurufen. Verwenden Sie einfach substr (), um das formatierte Datum auf drei Dezimalstellen zu kürzen.
LS
@LS Beim Abschneiden wird die 3. Dezimalstelle nicht gerundet, was wahrscheinlich noch ungenauer ist. Schwimmer brechen erst zusammen, wenn Sie wirklich winzige Präzisionen haben. 3 Dezimalstellen sollten in Ordnung sein. Eigentlich glaube ich nicht, dass ich die Genauigkeit überhaupt ändere. Floats werden genauer, je näher Sie 0 kommen. Wenn Sie die ganze Zahl abziehen, sollten Sie die AFAIK-Dezimalstellen nicht ändern.
Mpen
Was ist mit date('Y-m-d\TH:i:s', $time / 1000) . sprintf('.%03dZ', substr($time, 10));?
F8ER
@ F8ER Wenn du $timeschon in Millisekunden bist , würde das technisch funktionieren. substrIch mag den Hack nicht, aber ich denke, er würde für Daten zwischen 2001 und 2286 funktionieren.
mpen
Ja, das $timeist MS, aber was ist damit 2286, ich meine, warum denkst du das und wie wäre es möglich, solchen zu entkommen?
F8ER
3

Dies basiert auf der Antwort von ArchCodeMonkey.

Aber nur vereinfacht, wenn Sie nur etwas schnelles wollen, das funktioniert.

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()));
}

Also für mich dann

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

Hier ist eine andere Methode, die ich etwas eleganter / einfacher finde:

echo date('Y-m-d-H:i:s.').preg_replace("/^.*\./i","", microtime(true));
SDpyro
quelle
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;
Geo
quelle
1

Ab PHP 7.1 können Sie dies einfach tun:

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

Es wird angezeigt als:

04-11-2018 10:54:01.321688
Harveyhase68
quelle
0

In der Dokumentation heißt es:

Mikrosekunden (hinzugefügt in PHP 5.2.2). Beachten Sie, dass date () immer 000000 generiert, da ein ganzzahliger Parameter verwendet wird, während DateTime :: format () Mikrosekunden unterstützt.

Verwenden Sie stattdessen DateTime.

Havsmonstret
quelle
6
Das funktioniert nicht! date_format (new DateTime (), 'u') gibt Nullen: phpfiddle.org/lite/code/ggh-mvz
Jānis Elmeris
Ja, gemäß der obigen Antwort (und meinen Versuchen) new DateTime()wird auch 0000 für u zurückgegeben. Wenn Sie ihm jedoch beim Instanziieren eine Mikrosekundengenauigkeit geben, funktioniert er einwandfrei.
Scipilot
@scipilot ok, wie machst du das?
Geo
@Geo siehe die akzeptierte Antwort. new DateTime( 'Y-m-d H:i:s.'.$micro);
Scipilot
0

Mit PHP 7.0+ können Sie jetzt Folgendes tun:

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

Dies führt die folgenden Schritte aus:

  1. Schneidet die letzten 4 Nullen von der Zeichenfolge ab, damit Date()das Datum verarbeitet werden kann.
  2. Verwendet das Datum, um die Millisekunden in eine Datums- / Uhrzeitzeichenfolge zu formatieren, die DateTime verstehen kann.
  3. DateTime()Sie können dann die Zeitzone ändern, in der Sie sich befinden. Stellen Sie jedoch sicher, dass diese festgelegt date_default_timezone_set("Timezone");ist, bevor Sie DateTime()Funktionen und Klassen verwenden.
  4. Es wird empfohlen, in Ihren Klassen einen Konstruktor zu verwenden, um sicherzustellen, dass Sie sich in der richtigen Zeitzone befinden, wenn DateTime()Klassen oder Funktionen verwendet werden.
Jamie Ross
quelle
0

Wenn Sie Carbon verwenden, können Sie die definierte Spezifikation "RFC3339_EXTENDED" verwenden. oder passen Sie es an.

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

Basierend auf der Antwort von @ArchCodeMonkey.

Wenn Sie haben declare(strict_types=1), müssen Sie das zweite Argument in einen String umwandeln

Geben Sie hier die Bildbeschreibung ein

SandroMarques
quelle
0

Ich habe verschiedene Wege eingeschlagen:

1) microtime + sscanf + date:

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

Ich bin nicht sicher, warum microtime () 10 Zeichen (0.dddddd00) für den Mikrosekunden-Teil zurückgibt, aber vielleicht kann es mir jemand sagen?

$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');

funktioniert nicht in 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 + date:

$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)
Fravadona
quelle