2010-07-25 5 views
39

Mam obiekt datetime Pythona, który chciałbym przekonwertować na UTC. Planuję wydrukować go w formacie RFC 2822, aby umieścić nagłówek HTTP, ale nie jestem pewien, czy ma to znaczenie dla tego pytania. Znalazłem trochę informacji na tej stronie o przekształcaniu obiektów czasu i wygląda to w ten sposób prostszy, ale tym razem naprawdę chcę użyć obiektów datetime, ponieważ używam timedeltas, aby je dostosować:Jak mogę przekonwertować obiekt datetime Pythona na UTC?

Próbowałem czegoś takiego:

from datetime import datetime, timedelta 

now = datetime.now() 
fiveMinutesLater = datetime.now() + timedelta(minutes=5) 
fiveMinutesLaterUtc = ??? 

Wygląda na to, że nic w module czasu lub datetime nie pomoże. Wygląda na to, że mogę to zrobić, przekazując obiekt datetime przez 3 lub 4 funkcje, ale zastanawiam się, czy istnieje prostszy sposób.

Wolałbym nie używać modułów stron trzecich, ale mogę, jeśli jest to jedyny rozsądny wybór.

+0

związane z tytułem: [Jak zmienić czas lokalny na UTC w języku Python?] (Http://stackoverflow.com/q/79797/4279) – jfs

+0

ciąg: http://stackoverflow.com/questions/79797/how-do-i-convert-local-time-to-utc-in-python –

Odpowiedz

28
from datetime import datetime, timedelta 
datetime.utcnow() + timedelta(minutes=5) 
2

Można użyć metody formatdate w module email.Utils jak następuje

>>> from email.Utils import formatdate 
>>> print formatdate() 
Sun, 25 Jul 2010 04:02:52 -0000 

Powyższy czas data w formacie RFC 2822. Domyślnie zwraca czas UTC, ale w przypadku, gdy potrzebujesz czasu lokalnego, możesz wywołać formatdate (localtime = True).

Aby uzyskać więcej informacji na temat sprawdzenia http://docs.python.org/library/email.mime.html#module-email.util

+1

nie będzie działać w Pythonie 3; można zamiast tego używać [e-maili] (lowecase) (http://stackoverflow.com/a/29296267/4279) – jfs

9

najpierw trzeba się upewnić, że datetime jest obiektem stref czasowych świadomy poprzez ustawienie jej tzinfo użytkownika:

http://docs.python.org/library/datetime.html#datetime.tzinfo

Następnie można użyć funkcji .astimezone() Aby go przekonwertować:

http://docs.python.org/library/datetime.html#datetime.datetime.astimezone

+1

Zgodnie z dokumentami, muszę wymyślić podklasę klasy tzinfo, aby wymyślić z obiektem, który mogę przekazać do funkcji "teraz", aby poinformować o strefie czasowej mojego serwera. Wydaje się to dość skomplikowane. Czy ktoś wie prostszy sposób? Jeśli znajdę prostszy sposób, opublikuję go tutaj. –

+7

@ mikez302 - Zajrzyj do modułu pytz. Jest to efektywnie baza danych definicji datone.tzinfo stref czasowych dla wszystkich popularnych stref czasowych. –

+0

@ EliasZamaria: aby uzyskać lokalną strefę czasową jako obiekt 'pytz' tzinfo, można [użyć' tzlocal.get_localzone() '] (http://stackoverflow.com/q/13218506/4279) – jfs

2

znalazłem sposób na objęcie aktualny czas należy dodać obiekt timedelta do niego, konwertować wynik do UTC, a wyjście jest w RFC 2822:

time.strftime("%a, %d-%b-%Y %H:%M:%S GMT", 
    time.gmtime(time.time() + datetime.timedelta(minutes=5).seconds)) 

To nie dokładnie odpowiedzieć na moje pytanie, ale jestem umieszczenie go tutaj, ponieważ może pomóc komuś innemu w mojej sytuacji.

EDYCJA: Chciałbym dodać, że ta sztuczka działa tylko wtedy, gdy timedelta jest mniejsza niż jeden dzień. Jeśli chcesz czegoś, co działa z dowolną wartością timedelta, możesz użyć timedelta.total_seconds() (dla Pythona 2.7 i późniejszych) lub z 86400*timedelta.days + timedelta.seconds. Tak naprawdę nie próbowałem tego, więc nie jestem w 100% pewien, czy to zadziała.

+0

uwaga:'% b' może być zależny od lokalizacji. [Zamiast tego użyj adresu email.utils.formatdate] (http://stackoverflow.com/a/29296267/4279). Niepowiązane: '86400 * timedelta.days + timedelta.seconds' zawsze działa, jeśli potrzebujesz obsługi Pythona 2.6+ i nie przejmujesz się mikrosekundami. – jfs

6

Dla tych, którzy skończyło się tutaj szuka sposobu, aby przekształcić obiekt DateTime UTC sekund od UNIX epoki:

import time 
import datetime 

t = datetime.datetime.now() 
utc_seconds = time.mktime(t.timetuple()) 
+4

To nie jest dokładne, od mktime doc: Konwertuj krotkę czasu w czasie lokalnym na sekundy od Epoki. –

+1

to nie jest odpowiedź na pytanie zadawane przez PO. :( – sneak

+0

uwaga: czas lokalny może być niejednoznaczny (np. Podczas "cofania" przejścia DST) i jest 50%, że 'mktime()' może zwracać błędną wartość.Jest również nie działa, jeśli lokalna strefa czasowa miała/będzie miała różne przesunięcia utc w przeszłości/przyszłości (wiele stref czasowych nie) * i * C 'mktime()' nie korzysta z bazy danych tz (np. w systemie Windows) .Przenośne rozwiązanie do konwersji naiwnego obiektu datetime reprezentującego czas lokalny do UTC jest [użyj 'tzlocal.get_localzone()', aby uzyskać lokalną strefę czasową jako 'pytz' obiekt tzinfo] (http://stackoverflow.com/q/13218506/4279) – jfs

2

przekonwertować UTC z ciągiem Data:

from time import mktime 
from datetime import datetime 

mktime(datetime.utctimetuple(datetime.strptime("20110830_1117","%Y%m%d_%H%M"))) 
+1

To nie zadziała --- mktime używa lokalnej strefy czasowej Zobacz http://stackoverflow.com/questions/2956886/python-calendar-timegm-vs-time-mktime – teu

1

rozwiązanie z fantastyczne :

>>> import datetime 
>>> import delorean 
>>> dt = datetime.datetime.now() 
>>> dl = delorean.Delorean(dt, timezone='US/Pacific') 
>>> dl.shift('UTC') 
Delorean(datetime=2015-03-27 03:12:42.674591+00:00, timezone=UTC) 

>>> dl.shift('UTC').datetime 
datetime.datetime(2015, 3, 27, 3, 12, 42, 674591, tzinfo=<UTC>) 

>>> dl.shift('EST').datetime 
datetime.datetime(2015, 3, 26, 22, 12, 42, 674591, tzinfo=<StaticTzInfo 'EST'>) 

pozwala przesunąć datetime różnych strefach czasowych łatwo

+1

Nie ufałbym temu zbyt wiele, biorąc pod uwagę, że [autor delorean nie rozumie różnicy między '.now()' i '.now (tz)'] (https://github.com/myusuf3/delorean/pull/46). – jfs

0

Oto rozwiązanie stdlib (bez modułów 3rd-Party), który działa zarówno Python 2 i 3.

Aby uzyskać aktualny czas UTC w RFC 2822 Format:

>>> from email.utils import formatdate 
>>> formatdate(usegmt=True) 
'Fri, 27 Mar 2015 08:29:20 GMT' 

Aby uzyskać czas UTC 5 minut w przyszłość:

#!/usr/bin/env python 
import time 
from email.utils import formatdate 

print(formatdate(time.time() + 300, usegmt=True)) # 5 minutes into the future 
# -> Fri, 27 Mar 2015 08:34:20 GMT