Czy funkcja time.time () Pythona zwraca znacznik czasu lokalnego lub UTC?

558

Czy time.time()w module czasu Python zwraca czas systemowy czy czas w UTC?

Saransh Mohapatra
źródło
87
Znaczniki czasu nie mają stref czasowych. Reprezentują liczbę sekund od epoki. Epoka jest szczególnym momentem w czasie, który nie zależy od strefy czasowej.
jwg
2
@jwg: powszechnie używane znaczniki czasu POSIX nie liczą sekund przestępnych, a zatem nie są „liczbą [upływających SI] sekund od epoki” (są blisko).
jfs
7
Nie sądzę, że jest to trafny sprzeciw @JFSebastian. Sekundy przestępcze nie są „upływającymi sekundami od epoki”. Są to zmiany w reprezentacjach czasu zarejestrowanych przez zegary, które nie odpowiadają upływającym sekundom.
jwg
4
@JFSebastian Przepraszamy za zamieszanie. Sekundy przestępcze nie są „upływającymi sekundami”. Dlatego znaczniki czasu, które są „liczbami upływających sekund”, nie zawierają i nie powinny obejmować sekund przestępnych.
jwg
2
@jwg źle. Nie możesz wymazać czasu fizycznego. Znacznik czasu POSIX nie jest liczbą upływających sekund SI. Oto przykład: upłynęły 3 sekundy między „31 grudnia 2016 r. O 18:59:59” a „31 grudnia 2016 r. O 19:00:01” w Nowym Jorku, ale różnica między odpowiednimi znacznikami czasu POSIX wynosi tylko 2 sekundy ( sekunda przestępna nie jest liczona).
jfs

Odpowiedzi:

779

time.time()Funkcja zwraca liczbę sekund od początku epoki, jak sekund. Należy pamiętać, że „epoka” jest zdefiniowana jako początek 1 stycznia 1970 r. W UTC. Tak więc epoka jest zdefiniowana w kategoriach UTC i ustanawia globalny moment w czasie. Bez względu na to, gdzie jesteś „sekund po epoce” (time.time ()) zwraca tę samą wartość w tym samym momencie.

Oto kilka przykładowych danych wyjściowych, które uruchomiłem na komputerze, a także przekonwertowałem na ciąg.

Python 2.7.3 (default, Apr 24 2012, 00:00:54) 
[GCC 4.7.0 20120414 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> ts = time.time()
>>> print ts
1355563265.81
>>> import datetime
>>> st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
>>> print st
2012-12-15 01:21:05
>>>

tsZmienny jest czas zwrócony w ciągu kilku sekund. Następnie przekonwertowałem go na ciąg znaków za pomocą datetimebiblioteki, dzięki czemu jest to ciąg czytelny dla ludzi.

zwięźle
źródło
72
Dlaczego mielibyśmy, import timeskoro datetime zasadniczo daje ci znacznik czasu? Po prostu usuń milisekundy -str(datetime.datetime.now()).split('.')[0]
Hussain
17
@Alexis Epoka uniksowa jest tu dość wyraźnie zdefiniowana . Wskazuje nawet przykład Pythona na wiele stron. Nie rozumiem twojego komentarza.
squiguy
9
@ szczerze mówiąc, nie pamiętam, co skłoniło mnie do powiedzenia tego. Musiałem coś źle odczytać i starałem się dowiedzieć, dlaczego niektóre testy się psują, kiedy przeprowadzałem się między Francją i USA, aby w końcu stwierdzić, że przyczyną problemu był czas letni, który wydłużył tydzień w tym okresie roku. Przepraszam za to i dziękuję za zwrócenie na to uwagi.
Alexis,
5
to nie „sekundy w UTC”. . Zwrócony znacznik czasu time.time()nie znajduje się w żadnej strefie czasowej . „sekundy od epoki” to termin; nie upłynęły sekundy od pewnego momentu (epoki). Możesz łatwo przekonwertować go na czas lokalny (z bazą danych tz) i / lub strefę czasową UTC. btw, jeśli upuścisz .strftime()wynik jest (prawie) taki sam (+/- mikrosekund).
jfs
3
właśnie go przetestowałem, time.time () nie podaje czasu UTC, daje czas mojej lokalnej strefie
sliders_alpha
301

Jest to forma tekstowa znacznika czasu, którego można używać w plikach tekstowych. (W przeszłości tytuł pytania był inny, więc wprowadzenie do tej odpowiedzi zostało zmienione, aby wyjaśnić, jak można ją interpretować jako czas. [Zaktualizowano 14.01.2016])

Można uzyskać znacznik czasu jako ciąg przy użyciu .now()lub .utcnow()z datetime.datetime:

>>> import datetime
>>> print datetime.datetime.utcnow()
2012-12-15 10:14:51.898000

W nowróżni się od utcnowjak oczekiwano - w przeciwnym razie one działają w ten sam sposób:

>>> print datetime.datetime.now()
2012-12-15 11:15:09.205000

Możesz jawnie renderować znacznik czasu w ciągu:

>>> str(datetime.datetime.now())
'2012-12-15 11:15:24.984000'

Lub możesz być jeszcze bardziej wyraźny, aby sformatować znacznik czasu tak, jak chcesz:

>>> datetime.datetime.now().strftime("%A, %d. %B %Y %I:%M%p")
'Saturday, 15. December 2012 11:19AM'

Jeśli chcesz format ISO, użyj .isoformat()metody obiektu:

>>> datetime.datetime.now().isoformat()
'2013-11-18T08:18:31.809000'

Możesz użyć ich w zmiennych do obliczeń i drukowania bez konwersji.

>>> ts = datetime.datetime.now()
>>> tf = datetime.datetime.now()
>>> te = tf - ts
>>> print ts
2015-04-21 12:02:19.209915
>>> print tf
2015-04-21 12:02:30.449895
>>> print te
0:00:11.239980
pepr
źródło
1
Chciałem epoki .... nie w formacie daty ... co było oczywiste z mojej wzmianki o komendzie time.time ()
Saransh Mohapatra 15.12
34
Ok, nie ma problemu. Ktoś inny może potrzebować sygnatury czasowej do umieszczenia w plikach tekstowych.
pepr
1
Jestem kolejnym, przekierowanym tutaj prawdopodobnie z powodu nieuzasadnionej liczby głosów pozytywnych. Pytanie jest źle sformułowane, a przyjęta odpowiedź wprowadza w błąd w związku z typową potrzebą: uzyskanie sufiksu czytelnego dla człowieka - na przykład w przypadku nazw plików - w najczęściej używanej strefie czasowej serwera.
Aby wydrukować znacznik czasu jako część ciągu, użyj tego: Python2: import datetime; print "%s: My timestamp message" % datetime.datetime.utcnow()Python3:import datetime; print ("%s: My timestamp message" % datetime.datetime.utcnow())
Mr-IDE
datetime.datetime.utcnow()jest zły. Tworzy naiwny czas danych, który nie jest czasem lokalnym. O ile Twój czas lokalny to UTC, będzie NIEPRAWIDŁOWY. Użyj datetime.datetime.now(datetime.timezone.utc)zamiast tego. Spowoduje to utworzenie strefy czasowej uwzględniającej strefę czasową reprezentującą bieżącą godzinę.
Terrel Shumway
139

W oparciu o odpowiedź z #squiguy, aby uzyskać prawdziwy znacznik czasu, napisałbym: cast z float.

>>> import time
>>> ts = int(time.time())
>>> print(ts)
1389177318

Przynajmniej taka jest koncepcja.

Rudi Strydom
źródło
1
Jaki jest powód odlewania znacznika czasu? Jaki typ jest domyślnie?
Tizzee,
3
@Tizzee type(time.time())daje<type 'float'>
Famousgarkin
4
Ale jeśli potrzebujesz dokładniejszego czasu niż w sekundach, pływak ma sens.
pepr
3
@RudiStrydom: Python jest silnie napisany. Nie myl tego z statycznym pisaniem na klawiaturze.
jfs
1
@CheokYanCheng: int()jest polimorficzny. Zwróci, longjeśli to konieczne, w starych wersjach Pythona - wszystkie liczby całkowite są długie w nowych wersjach Pythona.
jfs
30

Odpowiedź może być nie na jedno lub oba.

  • none: time.time()zwraca przybliżoną liczbę sekund, które upłynęły od Epoki. Wynik nie zależy od strefy czasowej, więc nie jest to ani czas UTC, ani czas lokalny. Oto definicja POSIX dla „Seconds Since the Epoch” .

  • oba: time.time()nie wymaga synchronizacji zegara systemowego, więc odzwierciedla jego wartość (chociaż nie ma to nic wspólnego z lokalną strefą czasową). Różne komputery mogą uzyskiwać różne wyniki w tym samym czasie. Z drugiej strony, jeśli czas komputera jest zsynchronizowany, łatwo jest uzyskać czas UTC z datownika (jeśli zignorujemy sekundy przestępne):

    from datetime import datetime
    
    utc_dt = datetime.utcfromtimestamp(timestamp)

O tym, jak uzyskać znaczniki czasu z czasu UTC w różnych wersjach Pythona, zobacz Jak mogę przekonwertować datę na sekundy od epoki zgodnie z UTC?

jfs
źródło
4
Jest to jedyna odpowiedź, która jest poprawnie wspomniana, datetime.utcfromtimestamppodczas gdy na odpowiedzi jest 308 głosów pozytywnych z datetime.fromtimestamp:-(
@TerrelShumway pytanie dotyczy tego, co time.time()funkcja zwraca (jest bardzo krótka). Twój komentarz odnosi się do innego pytania (zmieniłeś swój komentarz, odkąd zacząłem na nie odpowiadać. Gorzej). Nota boczna; słowa „poprawne” należy używać oszczędnie (strefy czasowe są skomplikowane - nie ma srebrnej kuli - tylko kompromisy dla konkretnego przypadku użycia).
jfs
Nie używać datetime.datetime.utcfromtimestamp(ts). O ile Twój czas lokalny nie jest UTC, będzie NIEPRAWIDŁOWY, ponieważ tworzy naiwny czas danych, który nie jest czasem lokalnym. Użyj datetime.datetime.fromtimestamp(ts,datetime.timezone.utc)zamiast tego. To tworzy strefę czasową uwzględniającą strefę czasową reprezentującą ten sam moment co znacznik czasu.
Terrel Shumway
Tak. Mój poprzedni komentarz był całkowicie błędny. Większość kodu w module datetime traktuje naiwne czasy danych jako czas lokalny. Korzystanie z naiwnych okresów danych jest jak otwieranie pliku tekstowego bez znajomości kodowania.
Terrel Shumway
@TerrelShumway Błędem jest zakładanie, że czasu UTC można używać tylko w systemach, w których jest to czas lokalny. Prawdą jest, że niektóre części stdlib traktują naiwne obiekty datetime jako mające lokalną strefę czasową (niestety). Wolałbym, naive_dt.astimezone()żeby nie istniało tak, jak ukryte, bytes.encode()nie istnieje już w Pythonie 3. Prawdą jest, że w wielu przypadkach korzystna jest wewnętrzna praca z czasem UTC. Jest wiele rzeczy, które można powiedzieć o module datetime (odpowiedziałem na wystarczającą liczbę pytań, aby uzyskać złotą odznakę), większość nie mieści się w pytaniu: co time.time()zwraca.
jfs
4

W końcu zdecydowałem się na:

>>> import time
>>> time.mktime(time.gmtime())
1509467455.0
Natim
źródło
1
Może to zaspokoić twoje lokalne potrzeby, ale może wprowadzać w błąd osoby oczekujące, że liczby w tym zakresie będą sekundami od epoki [GMT]. time.time()zwraca 1574115250.818733int(time.time() * 1000)1574115254915
MarkHu,
3

W określonej strefie czasowej nie ma czegoś takiego jak „epoka”. Epoka jest dobrze zdefiniowana jako konkretny moment w czasie, więc jeśli zmienisz strefę czasową, zmieni się również sam czas. Tym razem jest to czas Jan 1 1970 00:00:00 UTC. time.time()Zwraca więc liczbę sekund od epoki.

HyperNeutrino
źródło
Chociaż prawdą jest, że UTC jest standardem czasowym, a nie strefą czasową, standardem jest to, że dzieli ten sam czas co GMT. Więc ....
Craig Hicks
3

znacznik czasu jest zawsze czasem w utc, ale gdy datetime.datetime.fromtimestamp go wywołujesz , zwraca on czas w lokalnej strefie czasowej odpowiadający temu znacznikowi czasu, więc wynik zależy od ustawień regionalnych.

>>> import time, datetime

>>> time.time()
1564494136.0434234

>>> datetime.datetime.now()
datetime.datetime(2019, 7, 30, 16, 42, 3, 899179)
>>> datetime.datetime.fromtimestamp(time.time())
datetime.datetime(2019, 7, 30, 16, 43, 12, 4610)

Istnieje ładna biblioteka arrowo różnych zachowaniach. W tym samym przypadku zwraca obiekt czasowy ze strefą czasową UTC.

>>> import arrow
>>> arrow.now()
<Arrow [2019-07-30T16:43:27.868760+03:00]>
>>> arrow.get(time.time())
<Arrow [2019-07-30T13:43:56.565342+00:00]>
Ryabchenko Alexander
źródło