Próbuję odjąć jedną wartość daty od wartości, datetime.today()
aby obliczyć, jak dawno coś było. Ale narzeka:
TypeError: can't subtract offset-naive and offset-aware datetimes
Ta wartość datetime.today()
nie wydaje się być „świadoma strefy czasowej”, podczas gdy moja inna wartość daty to. Jak uzyskać wartość tego, datetime.today()
co świadczy o strefie czasowej?
W tej chwili daje mi czas w czasie lokalnym, którym jest PST, czyli UTC - 8 godzin. W najgorszym przypadku, czy istnieje sposób, aby ręcznie wprowadzić wartość strefy czasowej do datetime
zwracanego obiektu datetime.today()
i ustawić ją na UTC-8?
Oczywiście idealnym rozwiązaniem byłoby automatyczne rozpoznanie strefy czasowej.
datetime.now().astimezone()
od Pythona 3.6Odpowiedzi:
W standardowej bibliotece nie ma wieloplatformowego sposobu tworzenia świadomych stref czasowych bez tworzenia własnej klasy stref czasowych.
W systemie Windows jest
win32timezone.utcnow()
, ale jest to część pywin32. Wolałbym raczej użyć biblioteki pytz , która ma stale aktualizowaną bazę danych większości stref czasowych.Praca z lokalnymi strefami czasowymi może być bardzo trudna (patrz łącza „Dalsze czytanie” poniżej), więc możesz raczej chcieć używać UTC w całej aplikacji, szczególnie do operacji arytmetycznych, takich jak obliczanie różnicy między dwoma punktami czasowymi.
Możesz uzyskać bieżącą datę / godzinę w następujący sposób:
Pamiętaj o tym
datetime.today()
idatetime.now()
zwróć czas lokalny , a nie czas UTC, więc zastosowanie się.replace(tzinfo=pytz.utc)
do nich byłoby nieprawidłowe.Innym dobrym sposobem na to jest:
który jest nieco krótszy i robi to samo.
Dalsze czytanie / oglądanie, dlaczego preferować UTC w wielu przypadkach:
źródło
datetime.now(pytz.utc)
zamiastdatetime.utcnow().replace(tzinfo = pytz.utc)
?now(utc)
nie wraca dzisiaj (chyba że jest północ do UTC), zwraca aktualny czas w UTC. Musisz także.replace(hour=0, minute=0, ...)
uzyskać początek dnia (jakdatetime.today()
)today()
zwraca aktualny czas, a nie o północy. Jeśli istnieje przypadek użycia, w którym wymagana jest północ, tak, wymiana musi zostać wykonana odpowiednio. Ponieważ pierwotne pytanie dotyczyło różnicy czasu, nie sądzę, że północ jest wymagana.datetime.today()
jestcombine(date.today(), time())
.datetime
ma obie metody.now()
i.today()
metody, które (jak słusznie zauważyłeś) zwracają (prawie) to samo. Nie madate.now()
metody.date
adatetime
obiekty nie są wymienne. Użycie obiektu datetime zamiastdate
obiektu może powodować subtelne błędy; Nie widzę żadnego powodu,datetime.today()
aby istnieć, jeśli jest to prawie duplikatdatetime.now()
.timezone.now()
zamiast,datetime.now()
ponieważ użyje UTC automatycznie, jeśliUSE_TZ = True
.timezone
znajduje się wdjango.utils.timezone
, dokumentacja: docs.djangoproject.com/en/1.11/topics/i18n/timezonesUzyskaj aktualny czas w określonej strefie czasowej:
źródło
datetime.datetime(2016, 11, 5, 9, 43, 45, tzinfo=pytz.timezone('US/Pacific'))
i sprawdzić, czy tego się spodziewanoW Pythonie 3 standardowa biblioteka znacznie ułatwia określenie UTC jako strefy czasowej:
Jeśli potrzebujesz rozwiązania, które korzysta tylko ze standardowej biblioteki i działa zarówno w Pythonie 2, jak i Pythonie 3, zobacz odpowiedź jfs .
Jeśli potrzebujesz lokalnej strefy czasowej, a nie UTC, zobacz odpowiedź Mihai Capotă
źródło
Oto rozwiązanie stdlib, które działa zarówno na Pythonie 2, jak i 3:
gdzie
today
jest świadoma instancja daty i godziny reprezentująca początek dnia (północ) w UTC iutc
jest obiektem tzinfo ( przykład z dokumentacji ):Powiązane: porównanie wydajności kilku sposobów uzyskania północy (początek dnia) dla danego czasu UTC . Uwaga: bardziej skomplikowane jest uzyskanie północy dla strefy czasowej z nieokreślonym przesunięciem UTC .
źródło
Inna metoda konstruowania obiektu typu data-godzina uwzględniającego strefę czasową reprezentującego bieżący czas:
źródło
pytz.utc
ipytz.UTC
oba są zdefiniowane (i są takie same)replace()
strefa czasowa jest na ogół podatna na błędy w większości innych zastosowań, natomiastlocalize()
ing jest preferowanym sposobem przypisywania strefy czasowej do naiwnych znaczników czasu..localize()
metoda zawiedzie w przypadku niejednoznacznych czasów lokalnych (dane wejściowe inne niż utc). W takich przypadkach odpowiedź @ philfreo.now(pytz_timezone)
nadal działa..now(pytz_timezone)
robi dokładnie to samo colocalize(utcnow)
- najpierw generuje bieżący czas w UTC, a następnie przypisuje mu strefę czasową: „<...> W tym przypadku wynik jest równoważny ztz.fromutc(datetime.utcnow().replace(tzinfo=tz))
”. Obie odpowiedzi są poprawne i działają zawsze.pytz
poprzez OLSON db powinien wiedzieć, jak przekonwertować ją na dowolną strefę czasową na świecie. Uświadomienie sobie jakiejkolwiek innej naiwnej (innej niż utc) strefy czasowej jest trudne z powodu niejednoznaczności podczas zmian czasu letniego. To nie jest problem.localize
(podanieis_dst
wartości powoduje, że działa ona na dowolną datę). To nieodłączny problem praktyki oszczędzania światła dziennego.Jednowarstwowy korzystający tylko ze standardowej biblioteki działa począwszy od Python 3.3. Możesz uzyskać lokalny
datetime
obiekt rozpoznający strefę czasową, używającastimezone
(zgodnie z sugestią johnchen902 ):źródło
datetime.now()
można wywoływać bez żadnych argumentów i zwracać poprawny wynik lokalny (datetime
zakłada się, że naiwni znajdują się w lokalnej strefie czasowej).Jeśli używasz Django , możesz ustawić daty nieobsługujące TZ (tylko UTC ).
Skomentuj następujący wiersz w pliku settings.py:
źródło
pytz to biblioteka Python, która umożliwia dokładne obliczenia stref czasowych między platformami przy użyciu Python 2.3 lub nowszego.
Z stdlib nie jest to możliwe.
Zobacz podobne pytanie na temat SO .
źródło
Oto jeden ze sposobów na wygenerowanie go za pomocą stdlib:
data będzie przechowywać lokalną datę i przesunięcie względem UTC , a nie datę w strefie czasowej UTC, więc możesz użyć tego rozwiązania, jeśli chcesz określić, w której strefie czasowej jest generowana data . W tym przykładzie i w mojej lokalnej strefie czasowej:
Kluczem jest dodanie
%z
dyrektywy do reprezentacji FORMAT, aby wskazać przesunięcie UTC wygenerowanej struktury czasu. Inne formaty reprezentacji można znaleźć w dokumentach modułu datetimeJeśli potrzebujesz datę w strefie czasowej UTC, można zastąpić time.localtime () z time.gmtime ()
Edytować
Działa to tylko na python3 . Dyrektywa z nie jest dostępna dla kodu _strptime.py w Pythonie 2
źródło
Użyj dateutil zgodnie z opisem w Python datetime.datetime.now (), który jest świadomy strefy czasowej :
źródło
tzlocal()
funkcja jest nadal jednym z najprostszych rozwiązań i zdecydowanie powinna zostać tutaj wymieniona.Uzyskiwanie daty uwzględniającej strefę czasową
utc
strefę czasową strefie czasowej wystarczy, aby odejmowanie dat działało.Ale jeśli chcesz mieć datę uwzględniającą strefę czasową w bieżącej strefie czasowej,
tzlocal
możesz wybrać:PS
dateutil
ma podobną funkcję (dateutil.tz.tzlocal
). Ale pomimo udostępnienia nazwy ma ona zupełnie inną bazę kodu, co, jak zauważył JF Sebastian, może dawać błędne wyniki.źródło
Oto rozwiązanie wykorzystujące czytelną strefę czasową, które działa z Today ():
Możesz wyświetlić wszystkie strefy czasowe w następujący sposób:
źródło
Szczególnie w strefach czasowych poza UTC:
Jedyną strefą czasową, która ma własną metodę, jest
timezone.utc
strefa czasowa z dowolnym przesunięciem UTC, jeśli jest to konieczne, używająctimedelta
&timezone
i wymuszając użycie.replace
.Używanie
timezone(timedelta(hours=n))
jako strefy czasowej jest tutaj prawdziwą srebrną kulą i ma wiele innych przydatnych aplikacji.źródło
Jeśli otrzymujesz aktualną godzinę i datę w Pythonie, a następnie zaimportuj datę i godzinę, spakuj pakiet Pytz w Pythonie po tym, jak otrzymasz aktualną datę i godzinę, jak ..
źródło
Inną, moim zdaniem lepszą, alternatywą jest użycie
Pendulum
zamiastpytz
. Rozważ następujący prosty kod:Aby zainstalować Wahadło i przejrzeć ich dokumentację, przejdź tutaj . Ma mnóstwo opcji (takich jak prosta obsługa formatu ISO8601, RFC3339 i wiele innych formatów), lepszą wydajność i zwykle daje prostszy kod.
źródło
Użyj strefy czasowej, jak pokazano poniżej, aby ustawić datę i godzinę uwzględniającą strefę czasową. Wartość domyślna to UTC:
źródło
Tyler z „howchoo” napisał naprawdę świetny artykuł, który pomógł mi lepiej zrozumieć obiekty Datetime, link poniżej
Praca z Datetime
Zasadniczo właśnie dodałem następujący tekst na końcu obu moich obiektów datetime
Przykład:
źródło
wypróbuj pnp_datetime , cały czas używany i zwracany jest w strefie czasowej i nie spowoduje żadnych problemów naiwnych i świadomych przesunięcia.
źródło
Należy podkreślić, że od Python 3.6 potrzebujesz tylko standardowej biblioteki lib, aby uzyskać obiekt datetime rozpoznający strefę czasową, który reprezentuje czas lokalny (ustawienie twojego systemu operacyjnego). Korzystanie z astimezonu ()
(patrz komentarz @ johnchen902).
źródło