2010-07-25 18 views
39

Ho un oggetto datetime python che vorrei convertire in UTC. Sto pianificando di inviarlo in formato RFC 2822 per inserire un'intestazione HTTP, ma non sono sicuro che questo sia importante per questa domanda. Ho trovato alcune informazioni su questo sito sulla conversione degli oggetti temporali, e sembra più semplice in questo modo, ma questa volta voglio davvero usare gli oggetti datetime, perché sto usando i timedelt per regolarli:Come posso convertire un oggetto datetime Python in UTC?

Ho provato qualcosa del genere:

from datetime import datetime, timedelta 

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

Nulla nel tempo o nel modulo datetime sembra che possa aiutarmi. Sembra che possa essere in grado di farlo passando l'oggetto datetime tramite 3 o 4 funzioni, ma mi chiedo se c'è un modo più semplice.

Preferirei non utilizzare moduli di terze parti, ma potrei farlo se fosse l'unica scelta ragionevole.

+0

relativo al titolo: [Come convertire l'ora locale in UTC in Python?] (Http://stackoverflow.com/q/79797/4279) – jfs

+0

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

risposta

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

È possibile utilizzare il metodo FormatoData nel modulo email.Utils come segue

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

Quanto sopra è data e ora in formato RFC 2822. Per impostazione predefinita restituisce l'ora UTC, ma nel caso sia necessario l'ora locale è possibile chiamare formatdate (localtime = True).

Per ulteriori informazioni fare controllare http://docs.python.org/library/email.mime.html#module-email.util

+1

non funzionerà in Python 3; potresti [usare 'email.utils' (lowecase) invece] (http://stackoverflow.com/a/29296267/4279) – jfs

9

prima cosa è necessario assicurarsi che il datetime è un oggetto fuso orario-aware impostando il suo tzinfo membro:

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

è possibile utilizzare la funzione .astimezone() per convertirlo:

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

+1

Secondo i documenti, ho bisogno di creare una sottoclasse della classe tzinfo per venire con un oggetto che posso passare alla funzione "now" per renderlo consapevole del fuso orario del mio server. Sembra un po 'complicato. Qualcuno sa un modo più semplice? Se trovo un modo più semplice, lo posterò qui. –

+7

@ mikez302 - Esamina il modulo pytz. È efficacemente un database delle definizioni del fuso orario datetime.tzinfo per tutti i fusi orari comuni. –

+0

@EliasZamaria: per ottenere il fuso orario locale come oggetto 'pytz' tzinfo, è possibile [usare' tzlocal.get_localzone() '] (http://stackoverflow.com/q/13218506/4279) – jfs

2

Ho trovato un modo per prendere il tempo corrente, aggiungere un oggetto timedelta ad esso, convertire il risultato in UTC, e l'uscita è nella RFC 2822:

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

Questo non ha esattamente risposto alla mia domanda, ma io sono metterlo qui perché potrebbe aiutare qualcun altro nella mia situazione.

MODIFICA: Vorrei aggiungere che questo trucco funziona solo se timedelta è inferiore a un giorno. Se si desidera qualcosa che funzioni con qualsiasi valore di timedelta, è possibile utilizzare timedelta.total_seconds() (per Python 2.7 e versioni successive) o con 86400*timedelta.days + timedelta.seconds. In realtà non ho provato questo quindi non sono sicuro al 100% se funzionerà.

+0

nota:'% b' può essere dipendente dalla locale. [Usa invece email.utils.formatdate] (http://stackoverflow.com/a/29296267/4279). Non correlato: '86400 * timedelta.days + timedelta.seconds' funziona sempre se hai bisogno di supportare Python 2.6+ e non ti preoccupi dei microsecondi. – jfs

6

Per chi ha finito qui in cerca di un modo per convertire un oggetto datetime di secondi UTC dal UNIX epoca:

import time 
import datetime 

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

Questo non è accurato, da mktime doc: converti una tupla temporale in ora locale in secondi da Epoch. –

+1

questa non è la risposta alla domanda che l'OP ha posto. :( – sneak

+0

nota: ora locale forse ambigua (ad es. Durante una transizione DST "fallback") e c'è il 50% che 'mktime()' può restituire un valore errato. Inoltre fallisce se il fuso orario locale ha/avrà un offset utc diverso nel passato/futuro (molti fusi orari fanno) * e * C 'mktime()' non usa il database tz (ad esempio, su Windows) .La soluzione portatile per convertire un oggetto datetime ingenuo che rappresenta l'ora locale in UTC è per [usare 'tzlocal.get_localzone()' per ottenere il fuso orario locale come 'pytz' tzinfo object] (http://stackoverflow.com/q/13218506/4279) – jfs

2

Per convertire in UTC da una stringa data:

from time import mktime 
from datetime import datetime 

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

Questo non funzionerà --- mktime usa il fuso orario locale Vedi http://stackoverflow.com/questions/2956886/python-calendar-timegm-vs-time-mktime – teu

1

soluzione con fantasticoDelorean lib:

>>> 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'>) 

permette di spostare datetime tra i diversi fusi orari facilmente

+1

Non mi fiderei troppo, dato che [l'autore di 'delorean' non capisce la differenza tra '.now()' e '.now (tz)'] (https://github.com/myusuf3/delorean/pull/46). – jfs

0

Ecco una soluzione stdlib (nessun modulo 3rd-party), che funziona sia su Python 2 e 3.

Per ottenere l'ora UTC corrente in RFC 2822 formato:

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

per ottenere il tempo UTC 5 minuti nel futuro:

#!/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 
Problemi correlati