Mam dt = datetime(2013,9,1,11)
i chciałbym uzyskać uniksowy znacznik czasu tego obiektu datetime.
Kiedy mam, (dt - datetime(1970,1,1)).total_seconds()
mam sygnaturę czasową 1378033200
.
Podczas konwersji z powrotem za pomocą datetime.fromtimestamp
otrzymałem datetime.datetime(2013, 9, 1, 6, 0)
.
Godzina się nie zgadza. Za czym tęskniłem?
timestamp
metody, zamiast próbować to zrobić samodzielnie. Po pierwsze, pozwala to całkowicie uniknąć możliwości odejmowania naiwnych czasów z różnych stref czasowych.dt
bierze? Czy to czas lokalny czy UTC?Odpowiedzi:
To, co przegapiłeś, to strefy czasowe.
Prawdopodobnie masz pięć godzin poza czasem UTC, więc 2013-09-01T11: 00: 00 lokalna i 2013-09-01T06: 00: 00Z to ten sam czas.
Musisz przeczytać górną część
datetime
dokumentacji, która wyjaśnia o strefach czasowych oraz obiektach „naiwnych” i „świadomych”.Jeśli pierwotną naiwną datą i godziną był UTC, sposobem na jej odzyskanie jest użycie
utcfromtimestamp
zamiastfromtimestamp
.Z drugiej strony, jeśli pierwotna naiwna data i godzina była lokalna, nie powinieneś odejmować od niej znacznika czasu UTC; użyj
datetime.fromtimestamp(0)
zamiast tego.Lub, jeśli masz świadomy obiekt daty i godziny, musisz albo użyć lokalnej (świadomej) epoki po obu stronach, albo jawnie przekonwertować na iz UTC.
Jeśli masz lub możesz zaktualizować Python 3.3 lub nowszy, możesz uniknąć wszystkich tych problemów, używając po prostu tej
timestamp
metody, zamiast próbować samodzielnie wymyślić, jak to zrobić. A nawet jeśli tego nie zrobisz, możesz rozważyć wypożyczenie jego kodu źródłowego .(A jeśli możesz poczekać na Pythona 3.4, wygląda na to, że PEP 341 prawdopodobnie trafi do ostatecznej wersji, co oznacza, że wszystkie rzeczy, o których JF Sebastian i ja rozmawialiśmy w komentarzach, powinny być możliwe do wykonania za pomocą tylko standardowej biblioteki, a działa w ten sam sposób w systemach Unix i Windows.)
źródło
dt
znajduje się w lokalnej strefie czasowej, wówczas formuła w pytaniu jest niepoprawnadatetime.fromtimestamp(0)
(epoka w bieżącej strefie czasowej) powinna zostać użyta zamiastdatetime(1970, 1,1)
(epoka unix w UTC).fromtimestamp(0)
może się nie powieść, jeśli system nie przechowuje historycznych informacji o strefie czasowej, np. w systemie Windows.pytz
może być użyty w tym przypadku.pytz
to nie pomaga, chyba że już wiesz, w której strefie czasowej się znajdujesz; aby zrobić to programowo, potrzebujesz innej biblioteki, która pobiera aktualną strefę czasową Windows i konwertuje ją napytz
strefę czasową i / lub wyszukuje ją po nazwie.tzlocal
moduł, który działa również w systemie Windows. Oto jak można przekonwertować czas utc na czas lokalny .rozwiązaniem jest
źródło
d
jest to naiwny obiekt daty / daty i godziny, który reprezentuje czas lokalny (może się nie powieść w przypadku niejednoznacznych czasów lub przeszłych / przyszłych dat, jeśli system operacyjny nie dostarcza historycznej wartości tz db (przesunięcie UTC mogło być inne w przeszłości w lokalnym strefa czasowa)). Więcej opcji .Jeśli chcesz przekonwertować datetime w Pythonie na sekundy od epoki, powinieneś to zrobić jawnie:
W Pythonie 3.3+ możesz
timestamp()
zamiast tego użyć :źródło
%s
, ponieważ zostanie on zlokalizowany zgodnie z zegarem systemu, w którym aktualnie jesteś. Powinieneś używać tylko.timestamp()
do uzyskania prawidłowego czasu Epoki / UNIX.%s
nie działa w systemach Windows (ValueError: Invalid format string
)8
lub9
Zamiast tego wyrażenia do tworzenia sygnatury czasowej POSIX z
dt
,Użyj tego:
Uzyskuję właściwą odpowiedź w twoim przykładzie, używając drugiej metody.
EDYCJA: Trochę dalszych informacji ... Po kilku komentarzach (patrz poniżej) byłem zaciekawiony brakiem wsparcia lub dokumentacji dla
%s
instrftime
. Oto co znalazłem:W źródle Pythona dla
datetime
itime
, ciągSTRFTIME_FORMAT_CODES
mówi nam:Więc teraz, jeśli my
man strftime
(w systemach BSD, takich jak Mac OS X), znajdziesz wsparcie dla%s
:W każdym razie, dlatego
%s
działa na systemach, które robi. Ale są lepsze rozwiązania problemu OP (uwzględniające strefy czasowe). Zobacz zaakceptowaną odpowiedź @ abarnert tutaj.źródło
strftime("%s")
w dokumentacji, właśnie potwierdziłem, że działa na komputerach Mac i Linux. Dzięki.time.strftime()
idatetime.strftime
delegacja dokumentacji do platformystrftime(3)
działają w przypadku nieobsługiwanych dyrektyw.%s
może się nie powieść nawet w systemie Mac OS X, np. datetime.strftime ('% s') powinien uwzględniać tzinfo .%s
ponieważ będziesz używać tylko zlokalizowanego czasu systemowego systemu, na którym jesteś. Chcesz użyć,.timestamp()
jeśli próbujesz uzyskać prawdziwy znacznik czasu UNIX.Do pracy ze strefami czasowymi UTC:
źródło
Przegapiłeś informacje o strefie czasowej (już odpowiedział, zgodziłeś się)
arrow
pakiet pozwala uniknąć tej tortury z datami; Jest już napisany, przetestowany, opublikowany w pypi, cross-python (2.6 - 3.xx).Wszystko, czego potrzebujesz:
pip install arrow
(lub dodaj do zależności)Rozwiązanie dla Twojego przypadku
źródło
Jeśli obiekt datetime reprezentuje czas UTC, nie używaj time.mktime, ponieważ zakłada się, że krotka znajduje się w lokalnej strefie czasowej. Zamiast tego użyj calendar.timegm:
źródło
Cóż, podczas konwersji na znacznik czasu unixa, python zasadniczo przyjmuje UTC, ale podczas konwersji z powrotem da ci datę przekonwertowaną na lokalną strefę czasową.
Zobacz to pytanie / odpowiedź; Pobierz strefę czasową używaną przez datetime.datetime.fromtimestamp ()
źródło
Jeśli chcesz mieć znacznik czasu UTC:
time.mktime
tylko dla lokalnego dt. Użyjcalendar.timegm
jest bezpieczne, ale dt musi mieć strefę utc, więc zmień strefę na utc. Jeśli dt w UTC, po prostu użyjcalendar.timegm
.źródło
źródło
Ta klasa zaspokoi Twoje potrzeby, możesz przekazać zmienną do ConvertUnixToDatetime i wywołać funkcję, na której ma działać.
źródło