¿Cómo preservar la zona horaria al analizar cadenas de fecha/hora con strptime()?

Resuelto victorhooi asked hace 14 años • 5 respuestas

Tengo un archivo de volcado CSV de una copia de seguridad de IPD de Blackberry, creado con IPDDump. Las cadenas de fecha/hora aquí se ven más o menos así (donde ESThay una zona horaria australiana):

Tue Jun 22 07:46:22 EST 2010

Necesito poder analizar esta fecha en Python. Al principio, intenté utilizar la strptime()función de datettime.

>>> datetime.datetime.strptime('Tue Jun 22 12:10:20 2010 EST', '%a %b %d %H:%M:%S %Y %Z')

Sin embargo, por alguna razón, el datetimeobjeto que regresa no parece tener ningún tzinfoasociado.

Leí en esta página que aparentemente datetime.strptimese descarta en silencio tzinfo, sin embargo, revisé la documentación y no puedo encontrar nada documentado en ese sentido aquí .

¿ Hay alguna manera de strptime()jugar bien con las zonas horarias?

victorhooi avatar Jul 22 '10 09:07 victorhooi
Aceptado

Recomiendo usar python-dateutil . Su analizador ha podido analizar todos los formatos de fecha que le he aplicado hasta ahora.

>>> from dateutil import parser
>>> parser.parse("Tue Jun 22 07:46:22 EST 2010")
datetime.datetime(2010, 6, 22, 7, 46, 22, tzinfo=tzlocal())
>>> parser.parse("Fri, 11 Nov 2011 03:18:09 -0400")
datetime.datetime(2011, 11, 11, 3, 18, 9, tzinfo=tzoffset(None, -14400))
>>> parser.parse("Sun")
datetime.datetime(2011, 12, 18, 0, 0)
>>> parser.parse("10-11-08")
datetime.datetime(2008, 10, 11, 0, 0)

etcétera. No hay que lidiar con strptime()tonterías de formato... simplemente ponle una fecha y hará lo correcto.

Joe Shaw avatar Dec 15 '2011 18:12 Joe Shaw

Dado que strptimedevuelve un objeto de fecha y hora que tiene tzinfoun atributo, simplemente podemos reemplazarlo con la zona horaria deseada.

>>> import datetime

>>> date_time_str = '2018-06-29 08:15:27.243860'
>>> date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S.%f').replace(tzinfo=datetime.timezone.utc)
>>> date_time_obj.tzname()
'UTC'
Surya Teja avatar Sep 21 '2020 08:09 Surya Teja

La datetimedocumentación del módulo dice:

Devuelve una fecha y hora correspondiente a date_string, analizada según el formato. Esto equivale a datetime(*(time.strptime(date_string, format)[0:6])).

Mira eso [0:6]? Eso te atrapa (year, month, day, hour, minute, second). Nada más. No se mencionan zonas horarias.

Curiosamente, [Win XP SP2, Python 2.6, 2.7] pasar su ejemplo time.strptimeno funciona, pero si elimina "%Z" y "EST" sí funciona. También funciona el uso de "UTC" o "GMT" en lugar de "EST". "PST" y "MEZ" no funcionan. Misterioso.

Vale la pena señalar que esto se actualizó a partir de la versión 3.2 y la misma documentación ahora también indica lo siguiente:

Cuando se proporciona la directiva %z al método strptime(), se generará un objeto de fecha y hora consciente. El tzinfo del resultado se establecerá en una instancia de zona horaria.

Tenga en cuenta que esto no funciona con %Z, por lo que el caso es importante. Vea el siguiente ejemplo:

In [1]: from datetime import datetime

In [2]: start_time = datetime.strptime('2018-04-18-17-04-30-AEST','%Y-%m-%d-%H-%M-%S-%Z')

In [3]: print("TZ NAME: {tz}".format(tz=start_time.tzname()))
TZ NAME: None

In [4]: start_time = datetime.strptime('2018-04-18-17-04-30-+1000','%Y-%m-%d-%H-%M-%S-%z')

In [5]: print("TZ NAME: {tz}".format(tz=start_time.tzname()))
TZ NAME: UTC+10:00
John Machin avatar Jul 22 '2010 08:07 John Machin

Su cadena de tiempo es similar al formato de hora en rfc 2822 (formato de fecha en correo electrónico, encabezados http) . Podrías analizarlo usando solo stdlib:

>>> from email.utils import parsedate_tz
>>> parsedate_tz('Tue Jun 22 07:46:22 EST 2010')
(2010, 6, 22, 7, 46, 22, 0, 1, -1, -18000)

Vea soluciones que generan objetos de fecha y hora que reconocen la zona horaria para varias versiones de Python: análisis de la fecha con la zona horaria de un correo electrónico .

En este formato, ESTes semánticamente equivalente a-0500 . Aunque, en general, una abreviatura de zona horaria no es suficiente para identificar una zona horaria de forma única .

jfs avatar Dec 04 '2015 10:12 jfs