datetime.datetime.utcnow()
Dlaczego datetime
nie ma żadnych informacji o strefie czasowej, skoro jest to wyraźnie UTC datetime
?
Spodziewałbym się, że to zawiera tzinfo
.
datetime.datetime.utcnow()
Dlaczego datetime
nie ma żadnych informacji o strefie czasowej, skoro jest to wyraźnie UTC datetime
?
Spodziewałbym się, że to zawiera tzinfo
.
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ą
import pytz # 3rd party: $ pip install pytz
u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) #NOTE: it works only with a fixed utc offset
teraz możesz zmienić strefy czasowe
print(u.astimezone(pytz.timezone("America/New_York")))
Aby uzyskać aktualny czas w danej strefie czasowej, możesz przekazać tzinfo datetime.now()
bezpośrednio:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
print(datetime.now(pytz.timezone("America/New_York")))
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.
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żyj datetime.now(tz)
zamiast tego.
Zauważ, że od wersji Python 3.2 datetime
moduł zawiera datetime.timezone
. Dokumentacja datetime.utcnow()
mówi:
Świadomy aktualny czas UTC można uzyskać, dzwoniąc .
datetime.now
(
timezone.utc
)
Możesz więc zrobić:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)
datetime.now(timezone.utc)
czy datetime.utcnow(timezone.utc)
?
datetime.utcnow()
nie przyjmuje żadnych argumentów. Tak musiało być datetime.now(timezone.utc)
.
datetime.now()
zwróci czas maszyny, ale datetime.utcnow()
zwróci rzeczywisty czas UTC.
datetime.utcnow()
nie ustawia tzinfo
wskazania, że jest to UTC. Ale datetime.now(datetime.timezone.utc)
zwraca czas UTC z tzinfo
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 .
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.utc
w Python 3.2+:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
datetime
obiektów stworzonych przez utcnow()
) ...
timezone.utc
został 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)
.
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.fromutc
pytz
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ć jej tzinfo
zamiast 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 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.
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 jak dateutil.tz.tzlocal()
) może się nie udać tutaj użyć do pytz
opartych rozwiązanie zamiast ).
dateutil
do dateutil.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:
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
datetime
obiektó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.
Aby dodać timezone
informacje w Python 3.2+
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'
AttributeError: 'module' object has no attribute 'timezone'
Python 2.7.13 (domyślnie, 19 stycznia 2017 r., 14:48:08)
from datetime import datetime
from dateutil.relativedelta import relativedelta
d = datetime.now()
date = datetime.isoformat(d).split('.')[0]
d_month = datetime.today() + relativedelta(months=1)
next_month = datetime.isoformat(d_month).split('.')[0]
Daty UTC nie potrzebują żadnych informacji o strefie czasowej, ponieważ są UTC, co z definicji oznacza, że nie mają przesunięcia.
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ą.