ottenere il formato della data mdY H: i: su da millisecondi


117

Sto cercando di ottenere una data formattata, inclusi i microsecondi da millisecondi.

L'unico problema è che continuo a ricevere 000000

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

ex. 28-07-2013 11: 26: 14.000000


6
È strano che la domanda richieda la conversione dei millisecondi , ma tutti rispondono come convertire i microsecondi. So che puoi convertire tra entrambi, ma in realtà rispondere alla domanda invece di copiare e incollare codice non correlato dal documento PHP o altrove sarebbe bello.
laurent

So che è passato un po 'di tempo, ma la risposta di bamossza è stata la migliore che ho trovato qui
Piyin,

Risposte:


122

php.net dice:

Microsecondi (aggiunti in PHP 5.2.2). Nota che date()genererà sempre 000000poiché richiede un parametro intero, mentre DateTime::format()supporta i microsecondi se è DateTimestato creato con microsecondi.

Quindi usa il più semplice:

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

Consigliato e utilizzare la dateTime()classe da riferimento:

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

La nota uè microsecondi (1 secondo = 1000000 µs).

Un altro esempio da php.net :

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

Riferimento di dateTime()su php.net

Ho risposto alla domanda più breve e semplificata per l'autore. Per ulteriori informazioni, vedere l'autore: ottenere il formato della data mdY H: i: su da millisecondi


4
In genere opto per il secondo modulo in quanto è più facile da leggere e capire. Inoltre, DateTime è molto più flessibile e robusto delle funzioni data / ora. La gestione dei microsecondi è un caso calzante.
Herbert

3
@Geo e AlBundy potrebbe essere che lo stai provando su una macchina con php <5.2.2? PHP 5.4.39 funziona perfettamente bene ...
RichardBernards

non sarebbe facile? data ('mdY H: i: s'). (int) microtime (true);
Anant

@ Anant, sarebbe abbastanza facile, anzi. Ma sbagliato. ;) Quello che ottieni è solo l'epoca in pochi secondi. (Sfortunatamente, non funzionerebbe con microtime(false)nessuno dei due.)
Sz.

Questo codice non funziona correttamente su tutte le impostazioni locali. Alcuni paesi come la Germania scrivono "0,1234" o "0,1234" invece di ".1234", quindi il tuo codice fornisce il seguente output per me: 2012-07-08 11:14:15.0.889342
Daniel Marschall

138

Puoi farlo facilmente con il formato di input U.u.

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

Questo produce il seguente output:

04-13-2015 05:56:22.082300

Dalla pagina di manuale PHP per i formati di data:

  • U = Secondi dall'epoca di Unix
  • u = microsecondi

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


Grazie a Giggsey per aver segnalato un difetto nella mia risposta originale, l'aggiunta number_format()alla riga dovrebbe risolvere il caso del secondo esatto. Peccato che non sia più così elegante ...

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

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


Una nota sui fusi orari in risposta a DaVe.

Normalmente il createFromFormat() metodo utilizza il fuso orario locale se non è specificato.

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

Tuttavia, la tecnica qui descritta consiste nell'inizializzare l'oggetto DateTime utilizzando microtime()che restituisce il numero di secondi trascorsi dall'Epoch di Unix (01 gennaio 1970 00:00:00 GMT).

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

Ciò significa che l'oggetto DateTime viene inizializzato in modo implicito in UTC, il che va bene per le attività interne del server che vogliono solo tenere traccia del tempo trascorso.

Se è necessario visualizzare l'ora per un determinato fuso orario, è necessario impostarlo di conseguenza. Tuttavia, questo dovrebbe essere fatto come passaggio separato dopo l'inizializzazione ( senza utilizzare il terzo parametro di createFromFormat()) per i motivi discussi sopra.

Il setTimeZone() metodo può essere utilizzato per soddisfare questo requisito.

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

Come esempio:

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

Produce il seguente output:

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

Nota che se vuoi inserire in mysql, il formato dell'ora deve essere:

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

19
Nota: DateTime::createFromFormat('U.u', microtime(true));restituirà false se microtime(true)viene eseguito sul secondo esatto. Restituisce "1438616239" invece di "1438616239.000000".
giggsey

1
Ottima soluzione, grazie. Sembra che sto perdendo il mio tempo locale creando $ adesso da microtime. Qualche idea?
daVe

1
@daVe ho aggiunto alcune informazioni sui fusi orari, spero che sia quello che cercavi.
ArchCodeMonkey

1
Il number_formatè sempre necessario, anche quando non è al secondo esatto. Altrimenti sei in balia precisiondell'opzione di configurazione PHP (per "display"), che non è abbastanza alta di default a partire da PHP 7.0 causando una perdita di precisione (non accurata fino al microsecondo).
Teoh Han Hui

1
Scorri sempre verso il basso in StackOverflow
tom10271

15

Ecco un approccio leggermente più breve. Anziché lavorare per creare una data / ora numerica ad alta precisione, converto il valore in microsecondi in una stringa, rimuovo il 0e lo aggiungo alla fine della stringa data / ora. Posso facilmente tagliare il numero di decimali regolando il parametro della lunghezza della stringa; qui io uso 4per ottenere millisecondi, ma potresti usare 7per ottenere microsecondi.

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

Per un valore microtime () di 0.98236000 1407400573, restituisce 08-07-14 01:08:13.982.


9

Sto usando

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

output di esempio:

02-06-2019 16:45:03.53811192512512

Se hai bisogno di limitare il numero di cifre decimali, la riga sottostante (credit mgutt) sarebbe una buona alternativa. (Con il codice seguente, il 6 limita il numero di cifre decimali a 6.)

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

output di esempio:

02-11-2019 15:33:03.624493

Hai perso la precisione e lo zero iniziale per secondi. Quindi dovrebbe essere la versione corretta echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));. Spiegazione perché abbiamo bisogno 09: stackoverflow.com/a/28739819/318765
mgutt

Hai perso di nuovo la precisione;)echo date('H:i:s').substr(fmod(microtime(true), 1), 1, 7);
mgutt

Ma attenzione, substr()non arrotonda. E in combinazione con round()esso taglierebbe gli zeri finali: stackoverflow.com/questions/7493305/… Questo è il motivo per cui ho proposto sprintf().
mgutt

@mgutt Quando la prima cifra non sarebbe zero? Fondamentalmente ciò che serve è semplicemente rimuovere lo zero che è sempre lì quando si ottiene il resto da fmod di 1. La domanda richiede microsecondi ma sotto forma di cifre decimali dei secondi. Non c'è motivo per limitare il numero di cifre decimali. Più cifre decimali sono semplicemente una migliore precisione.
ghbarratt

@mgutt Ho aggiunto la tua prima alternativa suggerita alla mia risposta, spiegando che sarebbe un buon modo per limitare il numero di cifre decimali se necessario
ghbarratt

3

Se (new Date()).toISOString()per qualche motivo vuoi formattare una data come JavaScript , ecco come puoi farlo in PHP:

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

Output di esempio:

2016-04-27T18:25:56.696Z

Solo per dimostrare che la sottrazione dell'intero numero non riduce la precisione della parte decimale:

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

PHP ha arrotondato le cifre decimali, ma le ha arrotondate allo stesso modo in entrambi i casi.


1
No. Non usare la matematica sul numero in virgola mobile, è impreciso. Inoltre, non perdere tempo a chiamare diverse funzioni. Basta usare substr () per troncare la data formattata a tre cifre decimali.
BS

@LS Truncating non arrotonda il terzo decimale, il che è probabilmente ancora più impreciso. I galleggianti non si rompono finché non si raggiungono precisioni minuscole; 3 cifre decimali dovrebbero andare bene. In realtà, non credo di alterare affatto la precisione, i float diventano più precisi man mano che ci si avvicina a 0. La sottrazione dell'intero numero non dovrebbe alterare le cifre decimali AFAIK.
mpen

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

@ F8ER Se il tuo $timeè già in millisecondi, sì, tecnicamente funzionerebbe. Non amare ilsubstr hack, ma immagino che funzionerebbe per le date tra il 2001 e il 2286.
mpen

Sì, il $time è la SM, ma che dire 2286, perché la penso così e come sarebbe possibile sfuggire a tale?
F8ER

3

Questo è basato sulla risposta di ArchCodeMonkey.

Ma semplificato, se vuoi solo qualcosa di veloce che funzioni.

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

Quindi per me allora

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

3

Ecco un altro metodo che trovo leggermente più elegante / semplice:

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

A partire da PHP 7.1 puoi semplicemente fare questo:

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

Verrà visualizzato come:

04-11-2018 10:54:01.321688

0

La documentazione dice quanto segue:

Microsecondi (aggiunti in PHP 5.2.2). Nota che date () genererà sempre 000000 poiché accetta un parametro intero, mentre DateTime :: format () supporta i microsecondi.

Cioè, usa DateTime invece.


6
Questo non funziona! date_format (new DateTime (), 'u') restituisce zero: phpfiddle.org/lite/code/ggh-mvz
Jānis Elmeris

Sì, come per la risposta sopra (e le mie prove) new DateTime()restituirà anche 0000 per te. Ma se gli fornisci un tempo di precisione del microsecondo durante la creazione dell'istanza, funziona bene.
scipilot

@scipilot ok, quindi come si fa?
Geo

@Geo vedi la risposta accettata. new DateTime( 'Y-m-d H:i:s.'.$micro);
scipilot

0

Con PHP 7.0 e versioni successive ora qui puoi fare quanto segue:

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

Questo fa quanto segue in ordine:

  1. Taglia gli ultimi 4 zeri dalla stringa in questo modo Date() poter gestire la data.
  2. Utilizza la data per formattare i millisecondi in una stringa di data e ora che DateTime può comprendere.
  3. DateTime()può quindi consentirti di modificare il fuso orario in cui ti trovi, ma assicurati che date_default_timezone_set("Timezone");sia impostato prima dell'usoDateTime() funzioni e classi.
  4. È buona norma utilizzare un costruttore nelle classi per assicurarsi di trovarsi nel fuso orario corretto quando DateTime()vengono utilizzate classi o funzioni.

0

se stai usando Carbon, puoi usare la specifica definita "RFC3339_EXTENDED". o personalizzalo.

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

0

Basato sulla risposta di @ArchCodeMonkey.

Se lo declare(strict_types=1)hai, devi lanciare il secondo argomento su string

inserisci qui la descrizione dell'immagine


0

Ho messo in panchina diversi modi:

1) microtime + sscanf + data:

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

Non sono sicuro del motivo per cui microtime () restituisce 10 caratteri (0.dddddd00) per la parte dei microsecondi ma forse qualcuno può dirmelo?

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

non funziona 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-> formato:

$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)
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.