sumar - Cómo analizar una fecha/hora de RFC 2822 en un horario de Python?
restar fechas con python (6)
El problema es que Parsedate ignorará el desplazamiento.
Haz esto en su lugar:
from email.utils import parsedate_tz
print parsedate_tz(''Fri, 15 May 2009 17:58:28 +0700'')
Tengo una fecha del formulario especificado por RFC 2822, por ejemplo Fri, 15 May 2009 17:58:28 +0000
, como una cadena. ¿Existe una manera rápida y / o estándar de obtenerlo como objeto datetime
en Python 2.5? Traté de producir una cadena de formato strptime, pero el especificador de zona horaria +0000 confunde al analizador.
Hay una función de email.util en email.util . Analiza todas las fechas válidas de RFC 2822 y algunos casos especiales.
Me gustaría detallar las respuestas anteriores. email.utils.parsedate
y email.utils.parsedate_tz
devuelven tuplas, dado que el OP necesita un objeto datetime.datetime
, voy a agregar estos ejemplos para completar:
from email.utils import parsedate
from datetime import datetime
import time
t = parsedate(''Sun, 14 Jul 2013 20:14:30 -0000'')
d1 = datetime.fromtimestamp(time.mktime(t))
O:
d2 = datetime.datetime(*t[:6])
Tenga en cuenta que d1
y d2
son objetos navideños de fecha y hora, no hay información de zona horaria almacenada. Si necesita objetos de fecha y hora, compruebe el tzinfo
datetime()
arg.
Alternativamente, puede usar el módulo dateutil
Parece que Python 3.3 en adelante tiene un nuevo método parsedate_to_datetime
en email.utils que se encarga de los pasos intermedios:
email.utils.parsedate_to_datetime (date)
El inverso de format_datetime (). Realiza la misma función que parsedate (), pero en caso de éxito devuelve una fecha y hora. Si la fecha de entrada tiene una zona horaria de -0000, la fecha y hora será inocente, y si la fecha se ajusta a las RFC representará una hora en UTC pero sin indicación de la zona horaria de origen real del mensaje, la fecha viene de. Si la fecha de entrada tiene alguna otra compensación válida de la zona horaria, la fecha y hora será una fecha de atención con la correspondiente zona horaria tzinfo.
Nuevo en la versión 3.3.
http://python.readthedocs.org/en/latest/library/email.util.html#email.utils.parsedate_to_datetime
email.utils.parsedate_tz(date)
es la función a usar. Las siguientes son algunas variaciones.
Correo electrónico cadena de fecha / hora ( RFC 5322 , RFC 2822 , RFC 1123 ) a la marca de tiempo de Unix en segundos flotantes:
import email.utils
import calendar
def email_time_to_timestamp(s):
tt = email.utils.parsedate_tz(s)
if tt is None: return None
return calendar.timegm(tt) - tt[9]
import time
print(time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(email_time_to_timestamp("Wed, 04 Jan 2017 09:55:45 -0800"))))
# 2017-01-04T17:55:45Z
Asegúrese de no utilizar mktime
(que interpreta time_struct en la hora local de su computadora, no UTC); use timegm
o mktime_tz
en mktime_tz
lugar (pero tenga cuidado con la advertencia de mktime_tz
en el siguiente párrafo).
Si está seguro de que tiene la versión 2.7.4, 3.2.4, 3.3 o más reciente de python, puede usar mktime_tz lugar de calendar.timegm(tt) - tt[9]
. Antes de eso, mktime_tz
daba tiempos incorrectos cuando se invocaba durante la transición de ahorro de luz diurna de caída de la zona horaria local ( error 14653 ).
Gracias a @ jf-sebastian por advertencias sobre mktime y mktime_tz .
Cadena de fecha y hora de correo electrónico ( RFC 5322 , RFC 2822 , RFC 1123 ) a datetime
"enterada" en Python 3.3:
En python 3.3 y email.utils.parsedate_to_datetime
posteriores, use email.utils.parsedate_to_datetime
, que devuelve un datetime
con el offset de zona original:
import email.utils
email.utils.parsedate_to_datetime(s)
print(email.utils.parsedate_to_datetime("Wed, 04 Jan 2017 09:55:45 -0800").isoformat())
# 2017-01-04T09:55:45-08:00
Advertencia: esto lanzará ValueError
si el tiempo cae en un segundo email.utils.parsedate_to_datetime("Sat, 31 Dec 2016 15:59:60 -0800")
por ejemplo, email.utils.parsedate_to_datetime("Sat, 31 Dec 2016 15:59:60 -0800")
.
Cadena de fecha y hora de correo electrónico ( RFC 5322 , RFC 2822 , RFC 1123 ) a datetime
y datetime
"enterada" en la zona UTC:
Esto solo se convierte en timestamp y luego en UTC datetime
:
import email.utils
import calendar
import datetime
def email_time_to_utc_datetime(s):
tt = email.utils.parsedate_tz(s)
if tt is None: return None
timestamp = calendar.timegm(tt) - tt[9]
return datetime.datetime.utcfromtimestamp(timestamp)
print(email_time_to_utc_datetime("Wed, 04 Jan 2017 09:55:45 -0800").isoformat())
# 2017-01-04T17:55:45
Cadena de fecha y hora de correo electrónico ( RFC 5322 , RFC 2822 , RFC 1123 ) a datetime
y datetime
"consciente" de python con desplazamiento original:
Antes de Python 3.2, Python no incluía las implementaciones de tzinfo, por lo que aquí un ejemplo con dateutil.tz.tzoffset
( pip install dateutil
):
import email.utils
import datetime
import dateutil.tz
def email_time_to_datetime(s):
tt = email.utils.parsedate_tz(s)
if tt is None: return None
tz = dateutil.tz.tzoffset("UTC%+02d%02d"%(tt[9]//60//60, tt[9]//60%60), tt[9])
return datetime.datetime(*tt[:5]+(min(tt[5], 59),), tzinfo=tz)
print(email_time_to_datetime("Wed, 04 Jan 2017 09:55:45 -0800").isoformat())
# 2017-01-04T09:55:45-08:00
Si está utilizando Python 3.2, puede usar la implementación tzinfo
incorporada datetime.timezone
: tz = datetime.timezone(datetime.timedelta(seconds=tt[9]))
lugar de la fecha de terceros del dateutil.tz.tzoffset
.
Gracias a @ jf-sebastian nuevamente por la nota sobre la fijación del segundo intercalar .
from email.utils import parsedate
print parsedate(''Fri, 15 May 2009 17:58:28 +0000'')