Działa dla dowolnej strefy czasowej, w tym tych, które obserwują czas letni (DST), tj. Działa dla stref czasowych, które mogą mieć różne przesunięcia utc w różnych momentach (nie ustalone przesunięcie utc). Nie używaj tz.localize(datetime.now())- może się nie powieść podczas przejścia na koniec DST, gdy czas lokalny jest niejednoznaczny.
Ale nie ma żadnego dobrego powodu, aby był on naiwny dla strefy czasowej - jest określony jako UTC. Dlaczego musisz wyszukać bibliotekę innej firmy, aby działała poprawnie?
Mark Ransom,
4
Zgadzam się; dla mnie „naiwne” czasy są całkowicie bezużyteczne. W tej chwili trwa dyskusja na liście python na temat dodawania pytza do stdlib; problemem nie jest licencjonowanie, ale fakt, że dane strefy czasowej są tak często aktualizowane (czym nie może być sam Python). Pytz również nie implementuje interfejsu tzinfo w oczekiwany sposób, więc możesz dostać błędy, jeśli spróbujesz użyć niektórych stref czasowych miasta astimezone. Datetime nie tylko nie ma natywnych stref czasowych, ale jedyna szeroko dostępna implementacja tzinfo jest niezgodna z domniemanym standardem.
bobince
5
@bobince Dlaczego pytz i standardowe biblioteki datetime nie działają dla Ciebie? Rdzeń Pythona i ewolucja Pytza jako niezależne projekty zmniejszają złożoność logistyczną dla głównego zespołu. Tak, zmniejszenie złożoności dla głównego zespołu Python zwiększa złożoność dla wszystkich użytkowników Pythona, którzy muszą radzić sobie ze strefami czasowymi, ale ufam, że podjęli tę decyzję nie bez powodu. Zasada „Biblioteka standardowa nie ma instancji tzinfo ...” jest świetna, ponieważ jest prosta, po co tutaj robić wyjątek?
Derek Litz,
15
Jak o właśnieu=datetime.now(pytz.utc)
Craig McQueen
4
@bain: nie używaj tz.localize(datetime.now()); użyj datetime.now(tz)zamiast tego.
Który jest preferowany? datetime.now(timezone.utc)czy datetime.utcnow(timezone.utc)?
Jesse Webb,
8
datetime.utcnow()nie przyjmuje żadnych argumentów. Tak musiało być datetime.now(timezone.utc).
Craig McQueen,
1
datetime.now()zwróci czas maszyny, ale datetime.utcnow()zwróci rzeczywisty czas UTC.
Babu,
13
@Babu: datetime.utcnow()nie ustawia tzinfowskazania, że jest to UTC. Ale datetime.now(datetime.timezone.utc)zwraca czas UTC ztzinfo ustawionym.
Craig McQueen,
@CraigMcQueen Więc jeśli przekażemy tzobiekt w konstruktorze teraz, zwróci on czas w tej strefie czasowej? Dobrze! Dzięki za wskazanie.
Babu
71
Standardowe biblioteki Pythona nie zawierają żadnych klas tzinfo (ale patrz pep 431 ). Mogę tylko zgadywać przyczyny. Osobiście uważam, że błędem było nie uwzględnienie klasy tzinfo dla UTC, ponieważ jest ona wystarczająco kontrowersyjna, aby mieć standardową implementację.
Edycja: Chociaż nie ma implementacji w bibliotece, istnieje jedna podana jako przykład w tzinfodokumentacji .
from datetime import timedelta, tzinfo
ZERO = timedelta(0)# A UTC class.class UTC(tzinfo):"""UTC"""def utcoffset(self, dt):return ZERO
def tzname(self, dt):return"UTC"def dst(self, dt):return ZERO
utc = UTC()
Aby go użyć, aby uzyskać bieżący czas jako świadomy obiekt datetime:
from datetime import datetime
now = datetime.now(utc)
Jest datetime.timezone.utcw Python 3.2+:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
Zastanów się, dlaczego ta klasa nie była zapewniona w pierwszej kolejności (i, co ważniejsze, używana do datetimeobiektów stworzonych przez utcnow()) ...
André Caron
17
Obiekt strefy czasowej timezone.utczostał wreszcie dodany do Pythona 3.2. Dla kompatybilności wstecznej utcnow()nadal zwraca obiekt czasowy bez strefy czasowej, ale możesz uzyskać to, co chcesz, dzwoniąc now(timezone.utc).
mhsmith
4
@rgove, to rodzaj naprawiania krzywd, które miały być uczciwą grą dla Pythona 3. Nie powinni się martwić o kompatybilność wsteczną. Jest inny przykład, który przeczytałem w ciągu ostatnich kilku dni - structmoduł przeprowadzałby automatyczne konwersje z Unicode na bajtowanie, a ostateczną decyzją było złamanie zgodności z wcześniejszymi wersjami Pythona 3, aby zapobiec podjęciu złej decyzji.
@LS tak, pytzto świetny zasób. Zanim zredagowałem swoją odpowiedź, aby wstawić przykładowy kod, ktoś już ją zasugerował i nie chciałem kraść grzmotu.
Mark Ransom,
20
pytzModuł jest jedną z opcji, a nie ma innegopython-dateutil , który chociaż jest również pakiet osoba trzecia, może już być dostępne w zależności od innych uzależnień i systemu operacyjnego.
Chciałem tylko dołączyć tę metodologię w celach informacyjnych - jeśli już zainstalowałeś python-dateutildo innych celów, możesz użyć jej tzinfozamiast duplikować zpytz
import datetime
import dateutil.tz
# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())
Zgadzam się, że wezwania do utcnowpowinny zawierać informacje o strefie czasowej UTC. Podejrzewam, że nie zostało to uwzględnione, ponieważ natywna biblioteka datetime domyślnie ustawia czas naiwnych dat danych w celu zachowania kompatybilności.
Korzystałem z wywołania datetime.datetime.utcfromtimestamp () i potrzebowałem dodać tzinfo. Drugie rozwiązanie zadziałało dla mnie: utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
Ponieważ mój program został już importowania dateutildo dateutil.parserlubiłem to rozwiązanie najlepsze. To było tak proste, jak: utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc()). Altówka!!
Rzeczywiście, interfejs API Python datetime zawsze zwraca nieświadome obiekty datetime, co jest bardzo niefortunne. Rzeczywiście, jak tylko dostaniesz jeden z tego obiektu, nie ma sposobu, aby dowiedzieć się, jaka jest strefa czasowa, dlatego te obiekty same w sobie są dość „bezużyteczne”.
Niestety, nawet jeśli możesz użyć utcnow(), nadal nie zobaczysz informacji o strefie czasowej, jak odkryłeś.
Rekomendacje:
Zawsze używaj świadomych datetimeobiektów, tj. Z informacjami o strefie czasowej. Dzięki temu możesz je porównać bezpośrednio (świadomy i nieświadomy)datetime
obiekty nie są porównywalne) i zwróci je poprawnie użytkownikom. Wykorzystaj pytz, aby mieć obiekty strefy czasowej.
Posługiwać się ISO 8601 jako formatu ciągu wejściowego i wyjściowego. Służy datetime.datetime.isoformat()do zwracania znaczników czasu w postaci łańcucha sformatowanego przy użyciu tego formatu, który zawiera informacje o strefie czasowej.
Jeśli chcesz przeanalizować ciągi znaków zawierające sformatowane znaczniki czasu ISO 8601, możesz polegać na iso8601, który zwraca znaczniki czasu z poprawnymi informacjami o strefie czasowej. To sprawia, że znaczniki czasu są bezpośrednio porównywalne.
Jest to nieco mylące zalecenie. Zasadą jest, aby nigdy nie zajmować się strefami czasowymi. Zawsze przechowuj i przesyłaj tz nieużywane obiekty utc (obiekty epoki). Strefę czasową należy obliczać tylko w momencie reprezentacji w interfejsie użytkownika
dniu
1
Wygląda na to, że całkiem dobrze pasuje do myśli Juliena. Które z jego konkretnych zaleceń (jak wspomniano powyżej) są mylące?
Joe D'Andrea,
10
Aby dodać timezoneinformacje w Python 3.2+
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)>>>print(d.tzinfo)'UTC+00:00'
O ile wiem z docs.python.org/library/datetime.html , data i godzina bez tzinfo to taka, w której strefa czasowa jest nieokreślona. Tutaj strefa czasowa nie została określona, więc logicznie powinien być obecny. Istnieje duża różnica między datą / godziną bez powiązanej strefy czasowej a tą, która jest zdecydowanie w UTC. (Idealnie powinny to być różne typy IMO, ale to już inna sprawa ...)
Jon Skeet
@JonSkeet Myślę, że brakuje ci punktu Ignacio, że UTC nie jest strefą czasową. Niesamowite, że ta odpowiedź ma wynik -9, gdy wpisuję to ...
CS
3
@CS: Cóż, Ignacio nigdy nie stwierdził, że ... i chociaż ściśle mówiąc UTC nie jest strefą czasową, zwykle jest traktowany jako taki, aby znacznie ułatwić życie (w tym w Pythonie, np. Z pytz.utc). Zauważ, że istnieje duża różnica między wartością, której przesunięcie względem UTC jest nieznane, a tą, w której wiadomo, że wynosi 0. To ostatnie utcnow()powinno zwrócić IMO. To by pasowało do „Świadomego obiektu używa się do przedstawienia określonego momentu w czasie, który nie jest otwarty na interpretację” zgodnie z dokumentacją.
Odpowiedzi:
Oznacza to, że strefa czasowa jest naiwna, więc nie można jej używać
datetime.astimezone
możesz nadać mu taką strefę czasową
teraz możesz zmienić strefy czasowe
Aby uzyskać aktualny czas w danej strefie czasowej, możesz przekazać tzinfo
datetime.now()
bezpośrednio:Działa dla dowolnej strefy czasowej, w tym tych, które obserwują czas letni (DST), tj. Działa dla stref czasowych, które mogą mieć różne przesunięcia utc w różnych momentach (nie ustalone przesunięcie utc). Nie używaj
tz.localize(datetime.now())
- może się nie powieść podczas przejścia na koniec DST, gdy czas lokalny jest niejednoznaczny.źródło
astimezone
. Datetime nie tylko nie ma natywnych stref czasowych, ale jedyna szeroko dostępna implementacja tzinfo jest niezgodna z domniemanym standardem.u=datetime.now(pytz.utc)
tz.localize(datetime.now())
; użyjdatetime.now(tz)
zamiast tego.Zauważ, że od wersji Python 3.2
datetime
moduł zawieradatetime.timezone
. Dokumentacjadatetime.utcnow()
mówi:Możesz więc zrobić:
źródło
datetime.now(timezone.utc)
czydatetime.utcnow(timezone.utc)
?datetime.utcnow()
nie przyjmuje żadnych argumentów. Tak musiało byćdatetime.now(timezone.utc)
.datetime.now()
zwróci czas maszyny, aledatetime.utcnow()
zwróci rzeczywisty czas UTC.datetime.utcnow()
nie ustawiatzinfo
wskazania, że jest to UTC. Aledatetime.now(datetime.timezone.utc)
zwraca czas UTC ztzinfo
ustawionym.tz
obiekt w konstruktorze teraz, zwróci on czas w tej strefie czasowej? Dobrze! Dzięki za wskazanie.Standardowe biblioteki Pythona nie zawierają żadnych klas tzinfo (ale patrz pep 431 ). Mogę tylko zgadywać przyczyny. Osobiście uważam, że błędem było nie uwzględnienie klasy tzinfo dla UTC, ponieważ jest ona wystarczająco kontrowersyjna, aby mieć standardową implementację.
Edycja: Chociaż nie ma implementacji w bibliotece, istnieje jedna podana jako przykład w
tzinfo
dokumentacji .Aby go użyć, aby uzyskać bieżący czas jako świadomy obiekt datetime:
Jest
datetime.timezone.utc
w Python 3.2+:źródło
datetime
obiektów stworzonych przezutcnow()
) ...timezone.utc
został wreszcie dodany do Pythona 3.2. Dla kompatybilności wstecznejutcnow()
nadal zwraca obiekt czasowy bez strefy czasowej, ale możesz uzyskać to, co chcesz, dzwoniącnow(timezone.utc)
.struct
moduł przeprowadzałby automatyczne konwersje z Unicode na bajtowanie, a ostateczną decyzją było złamanie zgodności z wcześniejszymi wersjami Pythona 3, aby zapobiec podjęciu złej decyzji.tzinfo
dokumentacja Pythona zawiera przykłady kodu do jego implementacji, ale nie zawierają one tej funkcji w samym czasie! docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutcpytz
to świetny zasób. Zanim zredagowałem swoją odpowiedź, aby wstawić przykładowy kod, ktoś już ją zasugerował i nie chciałem kraść grzmotu.pytz
Moduł jest jedną z opcji, a nie ma innegopython-dateutil
, który chociaż jest również pakiet osoba trzecia, może już być dostępne w zależności od innych uzależnień i systemu operacyjnego.Chciałem tylko dołączyć tę metodologię w celach informacyjnych - jeśli już zainstalowałeś
python-dateutil
do innych celów, możesz użyć jejtzinfo
zamiast duplikować zpytz
Zgadzam się, że wezwania do
utcnow
powinny zawierać informacje o strefie czasowej UTC. Podejrzewam, że nie zostało to uwzględnione, ponieważ natywna biblioteka datetime domyślnie ustawia czas naiwnych dat danych w celu zachowania kompatybilności.źródło
utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
datetime.now(pytz_tz)
tego zawsze działa;datetime.now(dateutil.tz.tzlocal())
może zawieść podczas przejścia DST . PEP 495 - Ujednoznacznienie czasu lokalnego może poprawićdateutil
sytuację w przyszłości.utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())
(uwaga:dateutil
z nietrwałego przesunięcie UTC (takie jakdateutil.tz.tzlocal()
) może się nie udać tutaj użyć dopytz
opartych rozwiązanie zamiast ).dateutil
dodateutil.parser
lubiłem to rozwiązanie najlepsze. To było tak proste, jak:utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc())
. Altówka!!Julien Danjou napisał dobry artykuł wyjaśniający, dlaczego nigdy nie należy zajmować się strefami czasowymi . Fragment:
Niestety, nawet jeśli możesz użyć
utcnow()
, nadal nie zobaczysz informacji o strefie czasowej, jak odkryłeś.Rekomendacje:
źródło
Aby dodać
timezone
informacje w Python 3.2+źródło
AttributeError: 'module' object has no attribute 'timezone'
Python 2.7.13 (domyślnie, 19 stycznia 2017 r., 14:48:08)źródło
Daty UTC nie potrzebują żadnych informacji o strefie czasowej, ponieważ są UTC, co z definicji oznacza, że nie mają przesunięcia.
źródło
pytz.utc
). Zauważ, że istnieje duża różnica między wartością, której przesunięcie względem UTC jest nieznane, a tą, w której wiadomo, że wynosi 0. To ostatnieutcnow()
powinno zwrócić IMO. To by pasowało do „Świadomego obiektu używa się do przedstawienia określonego momentu w czasie, który nie jest otwarty na interpretację” zgodnie z dokumentacją.