Próbuję uzyskać sformatowaną datę, w tym mikrosekundy z milisekund.
Jedynym problemem jest to, że ciągle otrzymuję 000000
date("m-d-Y H:i:s.u", $milliseconds/1000);
dawny. 07-28-2013 11:26: 14.000000
Próbuję uzyskać sformatowaną datę, w tym mikrosekundy z milisekund.
Jedynym problemem jest to, że ciągle otrzymuję 000000
date("m-d-Y H:i:s.u", $milliseconds/1000);
dawny. 07-28-2013 11:26: 14.000000
Odpowiedzi:
php.net mówi:
Mikrosekundy (dodane w PHP 5.2.2). Zauważ, że
date()
zawsze generuje,000000
ponieważ przyjmuje parametr całkowity, podczasDateTime::format()
gdy obsługuje mikrosekundy, jeśliDateTime
został utworzony z mikrosekundami.
Więc użyj tak prostego:
$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>";
Zalecana i używana dateTime()
klasa z przywołanych:
$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"
Uwaga u
to mikrosekundy (1 sekunda = 1000000 µs).
Inny przykład z php.net :
$d2=new DateTime("2012-07-08 11:14:15.889342");
Odniesienie do dateTime()
na php.net
Odpowiedziałem na pytanie jako krótkie i uproszczone do autora. Więcej informacji dla autora: pobieranie formatu daty mdY H: i: su z milisekund
microtime(false)
żadnym niestety nie zadziała .)
2012-07-08 11:14:15.0.889342
Możesz to łatwo zrobić za pomocą formatu wejściowego U.u
.
$now = DateTime::createFromFormat('U.u', microtime(true));
echo $now->format("m-d-Y H:i:s.u");
Daje to następujący wynik:
04-13-2015 05:56:22.082300
Ze strony podręcznika PHP dla formatów dat:
http://php.net/manual/en/function.date.php
Podziękowania dla Giggsey za wskazanie błędu w mojej pierwotnej odpowiedzi, dodanie number_format()
do wiersza powinno naprawić wielkość dokładnej sekundy. Szkoda, że nie jest już tak elegancki ...
$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
http://php.net/manual/en/function.number-format.php
Uwaga dotycząca stref czasowych w odpowiedzi na DaVe.
Zwykle createFromFormat()
metoda będzie używać lokalnej strefy czasowej, jeśli nie zostanie ona określona.
http://php.net/manual/en/datetime.createfromformat.php
Jednak technika opisana tutaj polega na inicjalizacji obiektu DateTime za pomocą, microtime()
który zwraca liczbę sekund, które upłynęły od epoki uniksowej (1 stycznia 1970 00:00:00 GMT).
http://php.net/manual/en/function.microtime.php
Oznacza to, że obiekt DateTime jest niejawnie inicjowany do czasu UTC, co jest wystarczające w przypadku wewnętrznych zadań serwera, które chcą tylko śledzić upływający czas.
Jeśli chcesz wyświetlić czas dla określonej strefy czasowej, musisz go odpowiednio ustawić. Należy to jednak zrobić jako osobny krok po inicjalizacji ( nie używając trzeciego parametru z createFromFormat()
) z powodów omówionych powyżej.
Plik setTimeZone()
Sposób może być stosowany do realizacji tego wymagania.
http://php.net/manual/en/datetime.settimezone.php
Jako przykład:
$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>';
Daje następujący wynik:
10-29-2015 00:40:09.433818
10-29-2015 11:40:09.433818
Pamiętaj, że jeśli chcesz wprowadzić dane do mysql, format czasu musi być następujący:
format("Y-m-d H:i:s.u")
DateTime::createFromFormat('U.u', microtime(true));
zwróci wartość false, jeśli zostanie microtime(true)
uruchomiona dokładnie w sekundzie. Zwraca „1438616239” zamiast „1438616239.000000”.
number_format
to zawsze konieczne, nawet jeśli nie jest to dokładna sekunda. W przeciwnym razie jesteś zdany na łaskę precision
opcji konfiguracyjnej PHP (dla "wyświetlania"), która domyślnie nie jest wystarczająco wysoka od PHP 7.0, powodując utratę precyzji (niedokładność do mikrosekundy).
Oto nieco krótsze podejście. Zamiast pracować nad utworzeniem liczbowej daty / godziny o wysokiej precyzji, konwertuję wartość mikrosekund na ciąg, usuwam znak 0
i dodaję go na końcu ciągu daty / godziny. Mogę łatwo skrócić liczbę miejsc po przecinku, dostosowując parametr długości łańcucha; tutaj używam 4
do uzyskania milisekund, ale możesz użyć 7
do uzyskania mikrosekund.
$t = explode(" ",microtime());
echo date("m-d-y H:i:s",$t[1]).substr((string)$t[0],1,4);
W przypadku wartości microtime () 0.98236000 1407400573
zwraca 08-07-14 01:08:13.982
.
echo date('m-d-Y H:i:s').substr(fmod(microtime(true), 1), 1);
przykładowe dane wyjściowe:
02-06-2019 16:45:03.53811192512512
Jeśli chcesz ograniczyć liczbę miejsc po przecinku, poniższa linia (kredyt mgutt) byłaby dobrą alternatywą. (W poniższym kodzie 6 ogranicza liczbę miejsc dziesiętnych do 6).
echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));
przykładowe dane wyjściowe:
02-11-2019 15:33:03.624493
echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));
. Wyjaśnienie, dlaczego potrzebujemy 09
: stackoverflow.com/a/28739819/318765
echo date('H:i:s').substr(fmod(microtime(true), 1), 1, 7);
substr()
nie zaokrągla się. I w połączeniu z round()
tym wyciąłby końcowe zera: stackoverflow.com/questions/7493305/… To jest powód, dla którego się zaproponowałem sprintf()
.
Jeśli (new Date()).toISOString()
z jakiegoś powodu chcesz sformatować datę taką jak JavaScript , możesz to zrobić w PHP:
$now = microtime(true);
gmdate('Y-m-d\TH:i:s', $now).sprintf('.%03dZ',round(($now-floor($now))*1000));
Przykładowe dane wyjściowe:
2016-04-27T18:25:56.696Z
Aby udowodnić, że odjęcie liczby całkowitej nie zmniejsza dokładności części dziesiętnej:
>>> number_format(123.01234567890123456789,25)
=> "123.0123456789012408307826263"
>>> number_format(123.01234567890123456789-123,25)
=> "0.0123456789012408307826263"
PHP zrobił wokół miejsc po przecinku, ale zaokrąglona do nich w ten sam sposób w obu przypadkach.
date('Y-m-d\TH:i:s', $time / 1000) . sprintf('.%03dZ', substr($time, 10));
?
$time
jest już w milisekundach, tak, to technicznie zadziała. Nie podoba mi się substr
hack, ale myślę, że zadziała w przypadku dat między 2001 a 2286.
$time
jest stwardnienie rozsiane, ale o co chodzi 2286
, mam na myśli, dlaczego tak myślisz i jak można by uciec od takiego?
Jest to oparte na odpowiedzi z ArchCodeMonkey.
Ale po prostu uproszczone, jeśli potrzebujesz czegoś szybkiego, co działa.
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()));
}
Więc dla mnie
$now = DateTime_us();
$now->format("m-d-Y H:i:s.u");
Od PHP 7.1 możesz po prostu zrobić to:
$date = new DateTime( "NOW" );
echo $date->format( "m-d-Y H:i:s.u" );
Wyświetli się jako:
04-11-2018 10:54:01.321688
Dokumentacja mówi, co następuje:
Mikrosekundy (dodane w PHP 5.2.2). Zauważ, że date () zawsze generuje 000000, ponieważ przyjmuje parametr będący liczbą całkowitą, podczas gdy DateTime :: format () obsługuje mikrosekundy.
Oznacza to, że zamiast tego użyj DateTime.
new DateTime()
również zwróci 0000 dla u. Ale jeśli podasz mu czas z dokładnością do mikrosekund podczas tworzenia jego wystąpienia, wszystko działa poprawnie.
new DateTime( 'Y-m-d H:i:s.'.$micro);
Dzięki PHP 7.0+ możesz teraz wykonać następujące czynności:
$dateString = substr($millseconds_go_here,0,10);
$drawDate = new \DateTime(Date('Y-m-d H:i',$dateString));
$drawDate->setTimezone(new \DateTimeZone('UTC'));
Wykonuje to w kolejności:
Date()
móc obsłużyć datę.DateTime()
możesz wtedy zezwolić na zmianę strefy czasowej, w której się znajdujesz, ale upewnij się, że date_default_timezone_set("Timezone");
została ustawiona przed użyciemDateTime()
funkcji i klas.DateTime()
używane są klasy lub funkcje.jeśli używasz Carbon, możesz użyć zdefiniowanej specyfikacji „RFC3339_EXTENDED”. lub dostosuj go.
Carbon::RFC3339_EXTENDED = 'Y-m-d\TH:i:s.vP';
Na podstawie odpowiedzi @ArchCodeMonkey.
Jeśli tak declare(strict_types=1)
, musisz rzucić drugi argument na łańcuch
Wyciągałem kilka różnych sposobów:
1) microtime + sscanf + date:
sscanf(microtime(), '0.%6s00 %s', $usec, $sec);
$date = date('Y-m-d H:i:s.', $sec) . $usec;
Nie jestem pewien, dlaczego microtime () zwraca 10 znaków (0.dddddd00) dla części mikrosekundowej, ale może ktoś może mi powiedzieć?
$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');
nie działa w 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)