Come ottenere l'ora corrente in millisecondi in PHP?


Risposte:


506

La risposta breve è:

$milliseconds = round(microtime(true) * 1000);

26
@FredrikWendt, penso che ti confonda time(). microtime(true)d'altra parte restituisce l'ora corrente in secondi poiché l'epoca Unix è precisa al microsecondo più vicino (vedi riferimento PHP). In realtà è molto semplice testare se si esegue il codice sopra in un ciclo e si visualizzano i millisecondi.
laurent,

6
L'ho fatto assolutamente! :-)
Fredrik Wendt il

10
Mi piace la risposta breve.
Erick Robertson,

9
Non dovrebbe essere microtime(true) / 1000(divisione invece di mulitplication)?
Jordan Lev,

18
@JordanLev, dovrebbe essere una moltiplicazione perché microtime (true) restituisce il timestamp Unix in secondi come float.
laurent,

88

Usa microtime. Questa funzione restituisce una stringa separata da uno spazio. La prima parte è la parte frazionaria dei secondi, la seconda parte è la parte integrale. Passa trueper ottenere come numero:

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

Fai attenzione alla perdita di precisione se lo usi microtime(true).

C'è anche gettimeofdayche restituisce la parte di microsecondi come un numero intero.

var_dump(gettimeofday());
/*
array(4) {
  ["sec"]=>
  int(1283846202)
  ["usec"]=>
  int(891199)
  ["minuteswest"]=>
  int(-60)
  ["dsttime"]=>
  int(1)
}
*/

Quindi in generale è microtime()uguale 1000*time(), giusto?
Venuto il

Vedo, ci possono essere errori, ma l'errore dovrebbe essere inferiore a 1000, giusto?
Venuto il

@COMer: Di quale variante stai parlando?
kennytm,

microtime(true)e1000*time()
COMer,

@COMer: 1000*time()non ti darà millisecondi. microtime(true)restituisce a floatche ha 14 cifre di precisione. La parte dei secondi ha già impiegato 10, quindi sono rimaste 4 cifre per la parte dei microsecondi. Questo dovrebbe essere sufficiente poiché i millisecondi richiedono solo 3 cifre extra.
kennytm,

46

Risposta breve:

Solo piattaforme a 64 bit!

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

[ Se si esegue PHP a 64 bit, la costante PHP_INT_SIZEequivale a8 ]


Risposta lunga:

Se si desidera una funzione equivalente di time()in millisecondi, è necessario innanzitutto considerare che, poiché time()restituisce il numero di secondi trascorsi dal "tempo dell'epoca" (01/01/1970), il numero di millisecondi dal "tempo dell'epoca" è un numero elevato e non rientra in un numero intero a 32 bit.

La dimensione di un numero intero in PHP può essere di 32 o 64 bit a seconda della piattaforma.

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

La dimensione di un numero intero dipende dalla piattaforma, sebbene un valore massimo di circa due miliardi sia il valore normale (ovvero 32 bit con segno). Le piattaforme a 64 bit hanno in genere un valore massimo di circa 9E18, ad eccezione di Windows, che è sempre a 32 bit. PHP non supporta numeri interi senza segno. Le dimensioni intere possono essere determinate usando la costante PHP_INT_SIZE e il valore massimo usando la costante PHP_INT_MAX da PHP 4.4.0 e PHP 5.0.5.

Se si dispone di numeri interi a 64 bit, è possibile utilizzare la seguente funzione:

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

microtime() restituisce il numero di secondi dal "tempo dell'epoca" con precisione fino a microsecondi con due numeri separati da spazio, come ...

0.90441300 1409263371

Il secondo numero è i secondi (numero intero) mentre il primo è la parte decimale.

La funzione precedente milliseconds()prende la parte intera moltiplicata per1000

1409263371000

quindi aggiunge la parte decimale moltiplicata per 1000e arrotondata a 0 decimali

1409263371904

Si noti che entrambi $mt[1]e il risultato di roundvengono sottoposti a cast int. Ciò è necessario perché sono floats e l'operazione su di essi senza il cast comporterebbe la restituzione della funzione a float.

Infine, quella funzione è leggermente più precisa di

round(microtime(true)*1000);

che con un rapporto di 1:10 (circa) restituisce 1 millisecondo in più rispetto al risultato corretto. Ciò è dovuto alla precisione limitata del tipo float ( microtime(true)restituisce un float). Comunque, se preferisci ancora il più corto round(microtime(true)*1000);, suggerirei di lanciare intil risultato.


Anche se va oltre lo scopo della domanda, vale la pena ricordare che se la tua piattaforma supporta numeri interi a 64 bit, puoi anche ottenere l'ora corrente in microsecondi senza incorrere in un overflow.

Se fact 2^63 - 1(il più grande intero con segno) diviso per 10^6 * 3600 * 24 * 365(circa i microsecondi in un anno) dà 292471.

È lo stesso valore che ottieni

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

In altre parole, un intero con segno a 64 bit ha spazio per memorizzare un intervallo di tempo di oltre 200.000 anni misurato in microsecondi.

Potresti averlo allora

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

perché non solo: `funzione getMilliEpoch () {$ mt = explode ('', microtime ()); ritorna $ mt [1]. substr ($ mt [0], 0, 5) * 1000; } `
Michael,

Ora c'è un parametro per la funzione microtime, se impostato su true, restituisce i secondi e i millisecondi dal 1 ° gennaio 1970, 0 ore 0 minuti 0 secondi come float. Ecco un esempio: microtime (vero) // 1553260455.7242
kukko

@kukko sì, ma a causa della limitata precisione del tipo float, il calcolo del numero di millesimi di tempo dal microtime (vero) comporterà un valore leggermente impreciso
Paolo

42

Come altri hanno già detto, è possibile utilizzare microtime()per ottenere la precisione in millisecondi sui timestamp.

Dai tuoi commenti, sembri volerlo come un Timestamp UNIX di alta precisione. Qualcosa come DateTime.Now.Ticksnel mondo .NET.

A tale scopo è possibile utilizzare la seguente funzione:

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

Questo è il modo di farlo!
tonix,

1
perrrrrrfect .. ♥.
SRB vieta l'

Non restituisce l'ora del server? Nel mio caso vedo che l'ora memorizzata in db è l'ora del mio browser locale. Supponiamo che il mio fuso orario sever sia EST + 3 e il tempo del mio browser sia GMT + 6, mentre invio un modulo dalla posizione GMT + 6, vedo che l'ora memorizzata è GMT + 6 millisecondi equivalenti. Quindi qual'è il problema? :(
Zenith,

12

Utilizzare microtime(true)in PHP 5 o la seguente modifica in PHP 4:

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

Un modo portatile per scrivere quel codice sarebbe:

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

    return microtime(true);
}

11

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

produzione:

2016-11-19 15:12:34.346351


1
Questo utilizza lo stesso timestamp:$t = gettimeofday(); echo date('Y-m-d H:i:s.',$t['sec']) . $t['usec'];
Savvas Radevic,

i microsecondi dovrebbero essere a zero:$timeofday=gettimeofday(); echo sprintf("%s.%06d", date('Y-m-d H:i:s', $timeofday['sec']), $timeofday['usec']);
mabi

7

prova questo:

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

7

Funziona anche se sei su PHP a 32 bit:

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

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

Nota che questo non ti dà numeri interi, ma stringhe. Tuttavia, funziona bene in molti casi, ad esempio quando si creano URL per richieste REST.


Se hai bisogno di numeri interi, PHP a 64 bit è obbligatorio.

Quindi è possibile riutilizzare il codice sopra e trasmettere a (int):

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

Oppure puoi usare le vecchie vecchie battute:

$time_milli = (int) round(microtime(true) * 1000);    // 1491536422147
$time_micro = (int) round(microtime(true) * 1000000); // 1491536422147300

5
$timeparts = explode(" ",microtime());
$currenttime = bcadd(($timeparts[0]*1000),bcmul($timeparts[1],1000));
echo $currenttime;

NOTA: PHP5 è richiesto per questa funzione a causa dei miglioramenti con microtime () ed è richiesto anche il modulo matematico bc (dato che abbiamo a che fare con numeri grandi, puoi verificare se hai il modulo in phpinfo).

Spero che questo ti aiuti.


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

È davvero come riempire tre zeri a destra?
Zeeshan,

Affatto. Converte entrambe le parti in millisecondi e fornisce la somma. Quindi è più preciso di aggiungere zeri.
user3767296

1
Sebbene questo frammento di codice possa risolvere la domanda, inclusa una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro e quelle persone potrebbero non conoscere i motivi del tuo suggerimento sul codice. Cerca inoltre di non aggiungere il tuo codice a commenti esplicativi, ciò riduce la leggibilità sia del codice che delle spiegazioni!
Michał Perłakowski,


-2

Usa questo:

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

Ciao

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.