Wie erhalte ich die aktuelle Zeit in Millisekunden in PHP?

323

time() ist in Sekunden - gibt es eine in Millisekunden?

COMer
quelle

Antworten:

506

Die kurze Antwort lautet:

$milliseconds = round(microtime(true) * 1000);
Laurent
quelle
26
@FredrikWendt, ich denke du bist verwirrend mit time(). microtime(true)Auf der anderen Seite wird die aktuelle Zeit in Sekunden seit der Unix-Epoche auf die nächste Mikrosekunde genau zurückgegeben (siehe PHP-Referenz). Es ist tatsächlich sehr einfach zu testen, ob Sie den obigen Code in einer Schleife ausführen und die Millisekunden anzeigen.
Laurent
6
Ich habe es absolut getan! :-)
Fredrik Wendt
9
Ich mag die kurze Antwort.
Erick Robertson
9
Sollte das nicht sein microtime(true) / 1000(Teilung statt Multiplikation)?
Jordan Lev
18
@JordanLev, es sollte eine Multiplikation sein, da microtime (true) den Unix-Zeitstempel in Sekunden als Float zurückgibt .
Laurent
88

Verwenden Sie microtime. Diese Funktion gibt eine durch ein Leerzeichen getrennte Zeichenfolge zurück. Der erste Teil ist der Bruchteil von Sekunden, der zweite Teil ist der integrale Teil. Geben Sie ein true, um eine Nummer zu erhalten:

var_dump(microtime());       // string(21) "0.89115400 1283846202"
var_dump(microtime(true));   // float(1283846202.89)

Achten Sie bei der Verwendung auf Präzisionsverluste microtime(true).

Es gibt auch, gettimeofdaydass der Mikrosekunden-Teil als Ganzzahl zurückgegeben wird.

var_dump(gettimeofday());
/*
array(4) {
  ["sec"]=>
  int(1283846202)
  ["usec"]=>
  int(891199)
  ["minuteswest"]=>
  int(-60)
  ["dsttime"]=>
  int(1)
}
*/
kennytm
quelle
Also im Allgemeinen microtime()gleich 1000*time(), oder?
COMer
Ich sehe, es kann Fehler geben, aber der Fehler sollte kleiner sein als 1000, oder?
COMer
@COMer: Von welcher Variante sprichst du?
Kennytm
microtime(true)und1000*time()
COMer
@COMer: gibt 1000*time()dir keine Millisekunden. microtime(true)Gibt a mit einer floatGenauigkeit von 14 Stellen zurück. Der Sekunden-Teil dauerte bereits 10, so dass 4 Stellen für den Mikrosekunden-Teil übrig blieben. Dies sollte ausreichen, da für Millisekunden nur 3 zusätzliche Ziffern erforderlich sind.
Kennytm
45

Kurze Antwort:

Nur 64-Bit-Plattformen!

function milliseconds() {
    $mt = explode(' ', microtime());
    return ((int)$mt[1]) * 1000 + ((int)round($mt[0] * 1000));
}

[ Wenn Sie 64-Bit-PHP ausführen, PHP_INT_SIZEentspricht die Konstante8 ]


Lange Antwort:

Wenn Sie zuerst eine gleichwertige Funktion time()in Millisekunden wünschen, müssen Sie berücksichtigen, dass time()die Anzahl der Millisekunden seit der "Epochenzeit" eine große Zahl ist , da die Anzahl der seit der "Epochenzeit" (01.01.1970) verstrichenen Sekunden zurückgegeben wird und passt nicht in eine 32-Bit-Ganzzahl.

Die Größe einer Ganzzahl in PHP kann je nach Plattform 32 oder 64 Bit betragen.

Von http://php.net/manual/en/language.types.integer.php

Die Größe einer Ganzzahl ist plattformabhängig, obwohl ein Maximalwert von etwa zwei Milliarden der übliche Wert ist (das sind 32 Bit Vorzeichen). 64-Bit-Plattformen haben normalerweise einen Maximalwert von etwa 9E18, mit Ausnahme von Windows, das immer 32-Bit ist. PHP unterstützt keine vorzeichenlosen Ganzzahlen. Die Ganzzahlgröße kann mit der Konstanten PHP_INT_SIZE und der Maximalwert mit der Konstanten PHP_INT_MAX seit PHP 4.4.0 und PHP 5.0.5 bestimmt werden.

Wenn Sie 64-Bit-Ganzzahlen haben, können Sie die folgende Funktion verwenden:

function milliseconds() {
    $mt = explode(' ', microtime());
    return ((int)$mt[1]) * 1000 + ((int)round($mt[0] * 1000));
}

microtime() Gibt die Anzahl der Sekunden seit der "Epochenzeit" mit einer Genauigkeit von bis zu Mikrosekunden zurück, wobei zwei durch Leerzeichen getrennte Zahlen wie ...

0.90441300 1409263371

Die zweite Zahl ist die Sekunde (Ganzzahl), während die erste der Dezimalteil ist.

Die obige Funktion milliseconds()nimmt den ganzzahligen Teil multipliziert mit1000

1409263371000

addiert dann den Dezimalteil multipliziert mit 1000und gerundet auf 0 Dezimalstellen

1409263371904

Beachten Sie, dass beide $mt[1]und das Ergebnis von in umgewandelt roundwerden int. Dies ist notwendig, weil sie floats sind und die Operation an ihnen ohne Gießen dazu führen würde, dass die Funktion a zurückgibt float.

Schließlich ist diese Funktion etwas genauer als

round(microtime(true)*1000);

dass bei einem Verhältnis von 1:10 (ungefähr) 1 Millisekunde mehr als das richtige Ergebnis zurückgegeben wird. Dies ist auf die begrenzte Genauigkeit des Float-Typs zurückzuführen ( microtime(true)gibt einen Float zurück). Wie auch immer, wenn Sie immer noch die kürzere bevorzugen, round(microtime(true)*1000);würde ich vorschlagen, intdas Ergebnis zu besetzen.


Auch wenn dies den Rahmen der Frage sprengt, ist es erwähnenswert, dass Sie, wenn Ihre Plattform 64-Bit-Ganzzahlen unterstützt , die aktuelle Zeit in Mikrosekunden abrufen können, ohne dass es zu einem Überlauf kommt.

Wenn die Tatsache 2^63 - 1(größte vorzeichenbehaftete Ganzzahl) geteilt durch 10^6 * 3600 * 24 * 365(ungefähr die Mikrosekunden in einem Jahr) ergibt 292471.

Das ist der gleiche Wert, den Sie erhalten

echo (int)( PHP_INT_MAX / ( 1000000 * 3600 * 24 * 365 ) );

Mit anderen Worten, eine vorzeichenbehaftete 64-Bit-Ganzzahl bietet Platz für eine Zeitspanne von über 200.000 Jahren, gemessen in Mikrosekunden.

Sie können dann haben

function microseconds() {
    $mt = explode(' ', microtime());
    return ((int)$mt[1]) * 1000000 + ((int)round($mt[0] * 1000000));
}
Paolo
quelle
warum nicht einfach: `function getMilliEpoch () {$ mt = explode ('', microtime ()); return $ mt [1]. substr ($ mt [0], 0, 5) * 1000; } `
Michael
Jetzt gibt es einen Parameter für die Mikrozeitfunktion. Wenn dieser Wert auf true gesetzt ist, werden die Sekunden und Millisekunden seit dem 1. Januar 1970 zurückgegeben, 0 Stunden 0 Minuten 0 Sekunden als float. Hier ist ein Beispiel: microtime (true) // 1553260455.7242
kukko
@kukko ja, aber aufgrund der begrenzten Genauigkeit des Float-Typs führt die Berechnung der Anzahl von Millicesonds aus der Mikrozeit (wahr) zu einem leicht ungenauen Wert
Paolo
42

Wie bereits erwähnt, können Sie mit microtime()Zeitstempeln eine Millisekundengenauigkeit erzielen.

Aus Ihren Kommentaren geht hervor, dass Sie es als hochpräzisen UNIX-Zeitstempel wünschen. So etwas wie DateTime.Now.Ticksin der .NET-Welt.

Sie können dazu die folgende Funktion verwenden:

function millitime() {
  $microtime = microtime();
  $comps = explode(' ', $microtime);

  // Note: Using a string here to prevent loss of precision
  // in case of "overflow" (PHP converts it to a double)
  return sprintf('%d%03d', $comps[1], $comps[0] * 1000);
}
Andrew Moore
quelle
So macht man das!
Tonix
1
perrrrrrfect .. ♥.
SRB verbietet
Gibt es nicht die Serverzeit zurück? In meinem Fall sehe ich, dass die in db gespeicherte Zeit meine lokale Browserzeit ist. Angenommen, meine schwere Zeitzone ist EST + 3 und meine Browserzeit ist GMT + 6. Während ich ein Formular vom GMT + 6-Standort abschicke, sehe ich, dass die gespeicherte Zeit GMT + 6 Zeitäquivalent Millisekunden ist. Also, wo liegt das Problem? :(
Zenith
12

Verwendung microtime(true)in PHP 5 oder die folgende Änderung in PHP 4:

array_sum(explode(' ', microtime()));

Eine tragbare Möglichkeit, diesen Code zu schreiben, wäre:

function getMicrotime()
{
    if (version_compare(PHP_VERSION, '5.0.0', '<'))
    {
        return array_sum(explode(' ', microtime()));
    }

    return microtime(true);
}
Alix Axel
quelle
11

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

Ausgabe:

2016-11-19 15:12:34.346351

mojmir.novak
quelle
1
Dies verwendet den gleichen Zeitstempel:$t = gettimeofday(); echo date('Y-m-d H:i:s.',$t['sec']) . $t['usec'];
Savvas Radevic
Mikrosekunden sollten mit $timeofday=gettimeofday(); echo sprintf("%s.%06d", date('Y-m-d H:i:s', $timeofday['sec']), $timeofday['usec']);
Nullen
7

Versuche dies:

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

    return $d->format("Y-m-d H:i:s.u"); 
}
Hồ Lê Thiện Thành
quelle
6

Dies funktioniert auch, wenn Sie mit 32-Bit-PHP arbeiten:

list($msec, $sec) = explode(' ', microtime());

$time_milli = $sec.substr($msec, 2, 3); // '1491536422147'
$time_micro = $sec.substr($msec, 2, 6); // '1491536422147300'

Beachten Sie, dass Sie hier keine ganzen Zahlen erhalten, sondern Zeichenfolgen. Dies funktioniert jedoch in vielen Fällen einwandfrei, beispielsweise beim Erstellen von URLs für REST-Anforderungen.


Wenn Sie Ganzzahlen benötigen, ist 64-Bit-PHP obligatorisch.

Dann können Sie den obigen Code wiederverwenden und in (int) umwandeln:

list($msec, $sec) = explode(' ', microtime());

// these parentheses are mandatory otherwise the precedence is wrong!
//                  ↓                        ↓
$time_milli = (int) ($sec.substr($msec, 2, 3)); // 1491536422147
$time_micro = (int) ($sec.substr($msec, 2, 6)); // 1491536422147300

Oder Sie können die guten alten Einzeiler verwenden:

$time_milli = (int) round(microtime(true) * 1000);    // 1491536422147
$time_micro = (int) round(microtime(true) * 1000000); // 1491536422147300
Gras Double
quelle
5
$timeparts = explode(" ",microtime());
$currenttime = bcadd(($timeparts[0]*1000),bcmul($timeparts[1],1000));
echo $currenttime;

HINWEIS: PHP5 ist für diese Funktion aufgrund der Verbesserungen mit microtime () erforderlich, und das bc-Mathematikmodul ist ebenfalls erforderlich (da es sich um große Zahlen handelt, können Sie überprüfen, ob Sie das Modul in phpinfo haben).

Hoffe das hilft dir.

Amnippon
quelle
5
$the_date_time = new DateTime($date_string);
$the_date_time_in_ms = ($the_date_time->format('U') * 1000) +
    ($the_date_time->format('u') / 1000);
user3767296
quelle
Ist das tatsächlich so, als würde man drei Nullen rechts auffüllen?
Zeeshan
Ganz und gar nicht. Es konvertiert beide Teile in Millisekunden und gibt die Summe an. Es ist also genauer als das Hinzufügen von Nullen.
user3767296
1
Während dieses Code-Snippet die Frage lösen kann, hilft eine Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen. Bitte versuchen Sie auch, Ihren Code nicht mit erklärenden Kommentaren zu überfüllen. Dies verringert die Lesbarkeit sowohl des Codes als auch der Erklärungen!
Michał Perłakowski
1

PHP 5.2.2 <

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

PHP 7.0.0 <7.1

$d = new DateTime();
echo $d->format("Y-m-d H:i:s.v"); // v : Milliseconds 
Sadee
quelle
1
In php <7.1 sind neue DateTime () Mikrosekunden immer 0, siehe php.net/manual/en/migration71.incompatible.php .
Mabi
-2

Benutze das:

function get_millis(){
  list($usec, $sec) = explode(' ', microtime());
  return (int) ((int) $sec * 1000 + ((float) $usec * 1000));
}

Tschüss

MIKEEEEE
quelle