2010-07-22 20 views
101

Tengo un archivo de volcado CSV de una copia de seguridad de Blackberry IPD, creado usando IPDDump. Las cadenas de fecha/hora en que aquí se ven algo como esto (donde EST es una zona horaria de Australia):Python strptime() y zonas horarias?

Tue Jun 22 07:46:22 EST 2010 

tengo que ser capaz de analizar esta fecha en Python. Al principio, traté de usar la función strptime() desde 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 objeto datetime que regresa no parece tener ninguna tzinfo asociados a ella.

Yo ya había leído sobre this page que aparentemente datetime.strptime silenciosamente descarta tzinfo, sin embargo, he comprobado la documentación, y no puedo encontrar nada a tal efecto documentado here.

He podido obtener la fecha analizada utilizando una biblioteca de Python de otro fabricante, dateutil, sin embargo, todavía tengo curiosidad por saber cómo estaba usando el strptime() incorporado incorrectamente. ¿Hay alguna manera de obtener strptime() para jugar bien con los husos horarios?

+1

¿No puedes ... convertir todas las fechas a GMT? – Robus

+1

@Robus: Hmm, tenía la esperanza de hacerlo, pero suponía que strftime/datetime podría hacer eso de alguna manera.De cualquier manera, necesito almacenar/analizar el hecho de que los datos de fecha y hora están en la zona horaria EST, o en cualquier zona horaria que me ocurran. La secuencia de comandos debe poder analizar las fechas genéricas con la información de la zona horaria (por ejemplo, ETC podría ser cualquier otra zona horaria). – victorhooi

+3

EST también es una abreviatura de zona horaria de EE. UU. (De manera similar, BST es una abreviatura de la zona horaria del Reino Unido y de Brasil). Dichas abreviaturas son intrínsecamente ambiguas. Use compensaciones relativas a UTC/GMT en su lugar. (Si necesita admitir abreviaturas, debe hacer que el mapeo dependa de la configuración regional y eso es un agujero sucio). –

Respuesta

26

El datetime module documentation dice:

Return a datetime corresponding to date_string, parsed according to format. This is equivalent to datetime(*(time.strptime(date_string, format)[0:6])) .

Ver que [0:6]? Eso te lleva a (year, month, day, hour, minute, second). Nada más. Sin mención de zonas horarias.

Curiosamente, [Win XP SP2, Python 2.6, 2.7] pasando su ejemplo a time.strptime no funciona, pero si quita el "% Z" y el "EST" funciona. También funciona "UTC" o "GMT" en lugar de "EST". "PST" y "MEZ" no funcionan. Misterioso.

+2

Error relacionado de Python: [% Z en strptime no coincide con EST y otros] (http://bugs.python.org/issue22377) – jfs

276

Recomiendo usar python-dateutil. Su analizador ha podido analizar cada formato de fecha que he lanzado hasta el momento.

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

y así sucesivamente. No se trata de tonterías de formato strptime() ... solo ponle una fecha y hace lo correcto.

Actualización: Oops. Perdí en tu pregunta original que mencionaste que usaste dateutil, disculpa por eso. Pero espero que esta respuesta siga siendo útil para otras personas que tropiezan con esta pregunta cuando tienen preguntas para analizar la fecha y ver la utilidad de ese módulo.

+5

Un millón y un upvotes para esta increíble clase. Gracias por compartir. –

+1

+1 ¡esta respuesta ha demostrado ser realmente útil! Gracias :-) – nemesisdesign

+0

Dado que muchas personas tienden a usar python-dateutil, me gustaría señalarnos una limitación de esa lib. '>>> parser.parse (" Jue, 25 de septiembre de 2003 10: 49: 41,123 -0300 ") Traceback (última llamada más reciente): Archivo" ", línea 1, en Archivo"/Users/wanghq /awscli/lib/python2.7/site-packages/dateutil/parser.py ", línea 748, en el análisis return DEFAULTPARSER.parse (timestr, ** kwargs) Archivo"/Users/wanghq/awscli/lib/python2 .7/site-packages/dateutil/parser.py ", línea 310, en el parse res, skipped_tokens = self._parse (timestr, ** kwargs) TypeError: el objeto 'NoneType' no es iterable' – wanghq

6

Su cadena de tiempo es similar al formato de hora en rfc 2822 (date format in email, http headers). Usted podría analizarlo utilizando sólo 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) 

Ver soluciones que producen objetos de fecha y hora de zona horaria consciente de las diferentes versiones de Python: parsing date with timezone from an email.

En este formato, EST is semantically equivalent to -0500. Aunque, en general, a timezone abbreviation is not enough, to identify a timezone uniquely.

Cuestiones relacionadas