To dziwne, że pytanie dotyczy konwersji milisekund , ale wszyscy odpowiadają, jak konwertować mikrosekundy. Wiem, że możesz konwertować między nimi, ale w rzeczywistości odpowiadanie na pytanie zamiast kopiowania i wklejania niepowiązanego kodu z dokumentu PHP lub gdzie indziej byłoby miłe.
laurent
Wiem, że minęło trochę czasu, ale odpowiedź Bamosszy była najlepsza, jaką tu znalazłem
Mikrosekundy (dodane w PHP 5.2.2). Zauważ, że date()zawsze generuje, 000000ponieważ przyjmuje parametr całkowity, podczas DateTime::format()gdy obsługuje mikrosekundy, jeśli DateTimezostał utworzony z mikrosekundami.
Generalnie wybieram drugi formularz, ponieważ jest łatwiejszy do odczytania i zrozumienia. Ponadto DateTime jest znacznie bardziej elastyczny i niezawodny niż funkcje daty / czasu. Obsługa mikrosekund jest istotna.
Herbert
3
@Geo i AlBundy czy to możliwe, że próbujesz tego na komputerze z php <5.2.2? PHP 5.4.39 działa doskonale ...
RichardBernards
czy to nie byłoby łatwe? data („mdY H: i: s”). (int) microtime (true);
Anant
@Anant, byłoby to naprawdę łatwe. Ale źle. ;) To, co tam dostajesz, to tylko epoka w kilka sekund. (Z microtime(false)żadnym niestety nie zadziała .)
Sz.
Ten kod nie działa poprawnie we wszystkich lokalizacjach. Niektóre kraje, takie jak Niemcy, piszą „0,1234” lub „0,1234” zamiast „.1234”, dlatego Twój kod daje mi następujący wynik: 2012-07-08 11:14:15.0.889342
Daniel Marschall
138
Możesz to łatwo zrobić za pomocą formatu wejściowego U.u.
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 ...
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).
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.
Uwaga: 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”.
giggsey
1
Świetne rozwiązanie, dziękuję. Wygląda na to, że tracę czas lokalny, tworząc teraz $ z mikroczasu. Dowolny pomysł?
daVe
1
@daVe Dodałem trochę informacji o strefach czasowych, mam nadzieję, że o to Ci chodziło.
ArchCodeMonkey
1
Plik number_format to zawsze konieczne, nawet jeśli nie jest to dokładna sekunda. W przeciwnym razie jesteś zdany na łaskę precisionopcji 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).
Teoh Han Hui
1
Zawsze przewijaj w dół w StackOverflow
tom10271
15
Oto nieco krótsze podejście. Zamiast pracować nad utworzeniem liczbowej daty / godziny o wysokiej precyzji, konwertuję wartość mikrosekund na ciąg, usuwam znak 0i 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 4do uzyskania milisekund, ale możesz użyć 7do uzyskania mikrosekund.
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).
Przegapiłeś precyzję i wiodące zero przez kilka sekund. Więc powinna być poprawna wersja 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
Ale uwaga, 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().
mgutt
@mgutt Kiedy pierwsza cyfra nie byłaby zerem? Zasadniczo potrzebne jest po prostu usunięcie zera, które jest zawsze obecne podczas pobierania reszty z fmod przez 1. Pytanie dotyczy mikrosekund, ale w postaci miejsc dziesiętnych sekund. Nie ma powodu, aby ograniczać liczbę miejsc po przecinku. Więcej miejsc po przecinku to po prostu lepsza precyzja.
ghbarratt
@mgutt Dodałem twoją pierwszą sugerowaną alternatywę do mojej odpowiedzi, wyjaśniając, że w razie potrzeby byłby to dobry sposób na ograniczenie liczby miejsc dziesiętnych
ghbarratt,
3
Jeśli (new Date()).toISOString()z jakiegoś powodu chcesz sformatować datę taką jak JavaScript , możesz to zrobić w PHP:
Nie. Nie używaj matematyki na liczbie zmiennoprzecinkowej, jest niedokładna. Nie trać też czasu na wywoływanie kilku funkcji. Po prostu użyj funkcji substr (), aby skrócić sformatowaną datę do trzech miejsc po przecinku.
LS
@LS Obcinanie nie zaokrągli trzeciego miejsca po przecinku, co jest prawdopodobnie jeszcze bardziej niedokładne. Pływaki nie psują się, dopóki nie osiągniesz naprawdę małych precyzji; 3 miejsca po przecinku powinny wystarczyć. Właściwie nie sądzę, żebym w ogóle zmienił precyzję, liczby zmiennoprzecinkowe stają się dokładniejsze, im bliżej się do 0. Odejmowanie liczby całkowitej nie powinno zmieniać miejsc dziesiętnych AFAIK.
otwarte
O co chodzi date('Y-m-d\TH:i:s', $time / 1000) . sprintf('.%03dZ', substr($time, 10));?
F8ER
@ F8ER Jeśli twój $timejest już w milisekundach, tak, to technicznie zadziała. Nie podoba mi się substrhack, ale myślę, że zadziała w przypadku dat między 2001 a 2286.
mpen
Tak, to $timejest stwardnienie rozsiane, ale o co chodzi 2286, mam na myśli, dlaczego tak myślisz i jak można by uciec od takiego?
F8ER
3
Jest to oparte na odpowiedzi z ArchCodeMonkey.
Ale po prostu uproszczone, jeśli potrzebujesz czegoś szybkiego, co działa.
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.
Tak, jak na powyższą odpowiedź (i moje próby) 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.
scipilot
@scipilot ok, więc jak to robisz?
Geo
@Geo zobacz zaakceptowaną odpowiedź. new DateTime( 'Y-m-d H:i:s.'.$micro);
scipilot
0
Dzięki PHP 7.0+ możesz teraz wykonać następujące czynności:
Odcina ostatnie 4 zera z ciągu, aby Date()móc obsłużyć datę.
Używa daty do sformatowania milisekund w ciągu daty i godziny, który DateTime może zrozumieć.
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.
Dobrą praktyką jest używanie konstruktora w swoich klasach, aby upewnić się, że znajdujesz się we właściwej strefie czasowej, gdy DateTime()używane są klasy lub funkcje.
Odpowiedzi:
php.net mówi:
Więc użyj tak prostego:
Zalecana i używana
dateTime()
klasa z przywołanych:Uwaga
u
to mikrosekundy (1 sekunda = 1000000 µs).Inny przykład z php.net :
Odniesienie do
dateTime()
na php.netOdpowiedziałem na pytanie jako krótkie i uproszczone do autora. Więcej informacji dla autora: pobieranie formatu daty mdY H: i: su z milisekund
źródło
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
.Daje to następujący wynik:
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 ...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:
Daje następujący wynik:
Pamiętaj, że jeśli chcesz wprowadzić dane do mysql, format czasu musi być następujący:
źródło
DateTime::createFromFormat('U.u', microtime(true));
zwróci wartość false, jeśli zostaniemicrotime(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żywam4
do uzyskania milisekund, ale możesz użyć7
do uzyskania mikrosekund.W przypadku wartości microtime ()
0.98236000 1407400573
zwraca08-07-14 01:08:13.982
.źródło
Używam
źródło
przykładowe dane wyjściowe:
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).
przykładowe dane wyjściowe:
źródło
echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));
. Wyjaśnienie, dlaczego potrzebujemy09
: stackoverflow.com/a/28739819/318765echo date('H:i:s').substr(fmod(microtime(true), 1), 1, 7);
substr()
nie zaokrągla się. I w połączeniu zround()
tym wyciąłby końcowe zera: stackoverflow.com/questions/7493305/… To jest powód, dla którego się zaproponowałemsprintf()
.Jeśli
(new Date()).toISOString()
z jakiegoś powodu chcesz sformatować datę taką jak JavaScript , możesz to zrobić w PHP:Przykładowe dane wyjściowe:
Aby udowodnić, że odjęcie liczby całkowitej nie zmniejsza dokładności części dziesiętnej:
PHP zrobił wokół miejsc po przecinku, ale zaokrąglona do nich w ten sam sposób w obu przypadkach.
źródło
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 chodzi2286
, 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.
Więc dla mnie
źródło
Oto inna metoda, którą uważam za nieco bardziej elegancką / prostą:
źródło
Od PHP 7.1 możesz po prostu zrobić to:
Wyświetli się jako:
źródło
źródło
Dokumentacja mówi, co następuje:
Oznacza to, że zamiast tego użyj DateTime.
źródło
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:
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ę, żedate_default_timezone_set("Timezone");
została ustawiona przed użyciemDateTime()
funkcji i klas.DateTime()
używane są klasy lub funkcje.źródło
jeśli używasz Carbon, możesz użyć zdefiniowanej specyfikacji „RFC3339_EXTENDED”. lub dostosuj go.
źródło
Na podstawie odpowiedzi @ArchCodeMonkey.
Jeśli tak
declare(strict_types=1)
, musisz rzucić drugi argument na łańcuchźródło
Wyciągałem kilka różnych sposobów:
1) microtime + sscanf + date:
Nie jestem pewien, dlaczego microtime () zwraca 10 znaków (0.dddddd00) dla części mikrosekundowej, ale może ktoś może mi powiedzieć?
2) DateTime :: createFromFormat + Datetime-> format:
nie działa w PHP 5.x ...
3) gettimeofday + date:
-
4) microtime + number_format + DateTime :: createFromFormat + DateTime-> format:
-
5) microtime + sprintf + DateTime :: createFromFormat + DateTime-> format:
-
źródło