Nigdy nie musiałem przeliczać czasu na i od UTC. Niedawno otrzymałem prośbę, aby moja aplikacja była świadoma strefy czasowej, a ja pracuję w kółko. Wiele informacji na temat konwersji czasu lokalnego na UTC, które uważam za dość elementarne (być może robię to również źle), ale nie mogę znaleźć żadnych informacji na temat łatwego konwertowania czasu UTC na strefę czasową użytkowników końcowych.
Krótko mówiąc, aplikacja na Androida wysyła mi (aplikację silnika) dane, w których obrębie znajduje się znacznik czasu. Aby zapisać ten znacznik czasu na czas utc, którego używam:
datetime.utcfromtimestamp(timestamp)
To wydaje się działać. Gdy moja aplikacja przechowuje dane, są one zapisywane z wyprzedzeniem 5 godzin (mam EST -5)
Dane są przechowywane na BigTable aplikacji, a po ich odzyskaniu są wyświetlane jako ciąg znaków:
"2011-01-21 02:37:21"
Jak przekonwertować ten ciąg na DateTime we właściwej strefie czasowej użytkowników?
Jakie jest zalecane miejsce do przechowywania informacji o strefie czasowej użytkowników? (Jak zazwyczaj przechowujesz informacje tz, tj .: „-5: 00” lub „EST” itp.?) Jestem pewien, że odpowiedź na moje pierwsze pytanie może zawierać parametr odpowiadający odpowiedziom na drugie.
Odpowiedzi:
Jeśli nie chcesz udostępniać własnych
tzinfo
obiektów, sprawdź bibliotekę python-dateutil . Zapewniatzinfo
implementacje na bazie bazy danych zoneinfo (Olson) , dzięki czemu można odwoływać się do reguł strefy czasowej pod nieco kanoniczną nazwą.Edytuj Rozszerzony przykład, aby pokazać
strptime
użycieEdytuj 2 Naprawiono użycie interfejsu API, aby pokazać lepszą metodę punktu wejścia
Edycja 3 Dołączone metody automatycznego wykrywania stref czasowych (Yarin)
źródło
dateutil.tz
i użyćtz.tzutc()
itz.tzlocal()
jako obiektów strefy czasowej szukałem. Wygląda na to, że baza danych stref czasowych w moim systemie jest dobra (zalogowałem się/usr/share/zoneinfo
). Nie jestem pewien, co było grane.tz
Moduł jest poprawny punkt wejścia do korzystania z tej biblioteki. Zaktualizowałem swoją odpowiedź, aby to odzwierciedlić.dateutil.zoneinfo
Moduł I pokazywał wcześniej jest używane wewnętrznie przeztz
moduł jako cofać, jeśli nie można zlokalizować-tych systemowych zoneinfo DB. Jeśli zajrzysz do biblioteki, zobaczysz, że tarball DB strefyinfo w pakiecie, którego używa, jeśli nie może znaleźć DB twojego systemu. Mój stary przykład próbował trafić bezpośrednio w tę bazę danych i domyślam się, że miałeś problemy z ładowaniem tej prywatnej bazy danych (nie ma w jakiś sposób ścieżki Pythona?)dateutil
, użyjpytz
zamiast tego .Oto odporna metoda, która nie zależy od żadnych zewnętrznych bibliotek:
Pozwala to uniknąć problemów z synchronizacją w przykładzie DelboyJay. I mniej problemów z terminem w poprawce Erika van Oostena.
Jako interesujący przypis, obliczone powyżej przesunięcie strefy czasowej może różnić się od następującego pozornie równoważnego wyrażenia, prawdopodobnie ze względu na zmiany reguł dotyczących czasu letniego:
Aktualizacja: ten fragment ma słabość korzystania z przesunięcia UTC bieżącego czasu, które mogą różnić się od przesunięcia UTC wejściowej daty i godziny. Zobacz komentarze do tej odpowiedzi dla innego rozwiązania.
Aby obejść różne czasy, chwyć epokę od upływu czasu. Oto, co robię:
źródło
pytz
db-db jest niemożliwe, patrz PEP-431. Chociaż możesz napisać tylko rozwiązanie stdlib, które działa w takich przypadkach na systemach, które mają już historyczną strefę czasową db np. Linux, OS X, zobacz moją odpowiedź .utc_datetime
momencie.Zobacz dokumentację datetime dotyczącą obiektów tzinfo . Musisz zaimplementować strefy czasowe, które chcesz wesprzeć. Są to przykłady na dole dokumentacji.
Oto prosty przykład:
Wynik
źródło
replace
aby ustawić strefę czasową na GMT i ustawić ją jako „świadomą”, a następnie użyj,astimezone
aby przekonwertować na inną strefę czasową.Jeśli chcesz uzyskać poprawny wynik nawet dla czasu, który odpowiada dwuznacznemu czasowi lokalnemu (np. Podczas przejścia DST) i / lub lokalne przesunięcie utc jest różne w różnych momentach w lokalnej strefie czasowej, użyj
pytz
stref czasowych:źródło
Ta odpowiedź powinna być pomocna, jeśli nie chcesz używać innych modułów oprócz
datetime
.datetime.utcfromtimestamp(timestamp)
zwracadatetime
obiekt naiwny (nieświadomy). Ci świadomi są świadomi strefy czasowej, a naiwni nie. Chcesz wiedzieć, jeśli chcesz konwertować między strefami czasowymi (np. Między czasem UTC i czasem lokalnym).Jeśli nie tworzysz daty na początek, ale nadal możesz utworzyć naiwny
datetime
obiekt w czasie UTC, możesz wypróbować ten kod Python 3.x, aby go przekonwertować:Uważaj, aby nie błędnie założyć, że jeśli twoja strefa czasowa to obecnie MDT, oszczędności czasu dziennego nie działają z powyższym kodem, ponieważ drukuje MST. Zauważysz, że jeśli zmienisz miesiąc na sierpień, wydrukuje MDT.
Innym łatwym sposobem na uzyskanie świadomego
datetime
obiektu (również w Pythonie 3.x) jest utworzenie go ze strefą czasową określoną na początek. Oto przykład z użyciem UTC:Jeśli używasz języka Python 2.x, prawdopodobnie będziesz musiał podklasę
datetime.tzinfo
i użyć go, aby pomóc w utworzeniu świadomegodatetime
obiektu, ponieważdatetime.timezone
nie istnieje on w języku Python 2.x.źródło
Jeśli używasz Django, możesz użyć
timezone.localtime
metody:źródło
Możesz użyć strzałki
możesz karmić
arrow.get()
czymkolwiek. znacznik czasu, ciąg ISO itpźródło
Tradycyjnie odkładam to na frontend - wysyłam czasy z backendu jako znaczniki czasu lub inny format daty i godziny w UTC, a następnie pozwalam klientowi ustalić przesunięcie strefy czasowej i renderować te dane we właściwej strefie czasowej.
W przypadku aplikacji internetowej jest to dość łatwe w javascript - można łatwo ustalić przesunięcie strefy czasowej przeglądarki za pomocą wbudowanych metod, a następnie poprawnie wyrenderować dane z zaplecza.
źródło
Możesz użyć
calendar.timegm
do przeliczenia czasu na sekundy od epoki Uniksa itime.localtime
do konwersji:Daje
Fri Jan 21 05:37:21 2011
(ponieważ jestem w strefie czasowej UTC + 03: 00).źródło
na przykład moja strefa czasowa to „ +08: 00 ”. input utc = 2018-10-17T00: 00: 00.111Z , a następnie dostanę wynik = 2018-10-17T08: 00: 00 + 08: 00
źródło
Z odpowiedzi tutaj możesz skorzystać z modułu czasu do konwersji z utc na czas lokalny ustawiony na twoim komputerze:
źródło
Oto szybka i brudna wersja, która wykorzystuje lokalne ustawienia systemu do obliczenia różnicy czasu. UWAGA: To nie zadziała, jeśli musisz przekonwertować na strefę czasową, w której obecny system nie działa. Przetestowałem to z ustawieniami brytyjskimi w strefie czasowej BST
źródło
datetime.fromtimestamp(ts)
: znacznik czasu posix (liczba zmiennoprzecinkowa) -> obiekt datetime w czasie lokalnym (działa dobrze, jeśli system operacyjny pamięta poprzednie przesunięcia utc dla lokalnej strefy czasowej, tj. w systemie Unix, ale nie w systemie Windows dla dat w przeszłości)). W przeciwnym razie można użyć pytza.offset = datetime.utcnow().replace(minute=0, second=0, microsecond=0) - datetime.now().replace(minute=0, second=0, microsecond=0)
Mam dziwne różnice w mikrosekundach bez tego.datetime.fromtimestamp(ts)
zamiast odpowiedzi?Skonsolidowanie odpowiedzi z franków w wygodnej metodzie.
źródło