2011-08-25 7 views
8

Estoy escribiendo una prueba para un programa que se utilizará en múltiples configuraciones regionales. Mientras se ejecuta la prueba en alemán, me dieron el error¿Por qué Python almacena cadenas de formato de tiempo en alemán y español (y otras?) Como% T en el módulo de configuración regional?

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python2.7/_strptime.py", line 454, in _strptime_time 
    return _strptime(data_string, format)[0] 
    File "/usr/local/lib/python2.7/_strptime.py", line 317, in _strptime 
    (bad_directive, format)) 
ValueError: 'T' is a bad directive in format '%T' 

de excavación en esto, he descubierto que el uso de locale.nl_langinfo(locale.T_FMT) mientras que en alemán o español (y potencialmente otros idiomas) produce la cadena de formato '%T'. Esto no se reconoce en el time module.

La documentación en locale en python.org no menciona nada acerca de devolver '%T'. La única referencia a '%T' que pude encontrar en cualquier lugar es en respuesta a a separate StackOverflow question. De esa publicación y contexto, asumo que '%T' es una abreviatura de '%H:%M:%S'.

Mi pregunta es, ¿Cómo se gestionan los lugares para los que locale volverá '%T' por su cadena de formato sin hacer algo como

if fmt_str == '%T': 
    fmt_str = '%H:%M:%S' 

para manejar esos casos?

+1

+1 Muy raro. ¿Un módulo estándar se equivoca incondicionalmente, con un mensaje de error sucksy, simplemente debido a un cambio de configuración regional? – delnan

+0

El problema parece ser que los dos módulos simplemente no se comunican entre sí y 'locale' comenzó a usar la taquigrafía que' time' no reconoce. Lo cual es muy extraño, porque se supone que ambos deben cumplir con el estándar 'date' de Unix; 'locale' hace mientras' time' aparentemente no. – Staunch

+0

No es que mi entorno local admita '% T', es que' locale' usa '% T' como la abreviatura de'% H:% M:% S' pero 'time' no.Las abreviaturas en 'locale' coinciden con los formatos de la función' date' de Unix (para verlos, escribe 'date --h' en una línea de comando), pero' time' usa una lista de abreviaturas reducida. Para el registro, '% X' funcionaría, pero eso no es lo que' local' devuelve. – Staunch

Respuesta

1

Ésta es una respuesta totalmente insatisfactoria, pero esta es la respuesta de todos modos:

La razón locale y time.strptime no jugar bien juntos es porque los formatos locale no fueron escritos para time.strptime. Fueron escritos para time.strftime, para producir los formatos de fecha/hora necesarios, no para analizarlos.

Como time.strptime se escribió para ser independiente de la plataforma, no acepta tantas directivas como locale da; time.strftime debe ser capaz de convertir todo lo que se le arroje, por lo que acepta cualquier directiva definida por la plataforma.

Así que, no, no hay una manera más fácil de hacer que time y locale cooperen de la manera que yo quiero.

0

Realmente veo que estás usando strptime, no strftime. Y la documentación para strptime menciona:

Solo se admiten las directivas especificadas en la documentación. Debido a que strftime() se implementa por plataforma, a veces puede ofrecer más directivas que las enumeradas. Pero strptime() es independiente de cualquier plataforma y, por lo tanto, no necesariamente admite todas las directivas disponibles que no están documentadas como compatibles.

Como sugirió here, puede utilizar un motor más potente analizador fecha, como dateutil

>> import dateutil.parser 
>> dateutil.parser.parse("Thu Sep 25 10:36:28 2003") 
datetime.datetime(2003, 9, 25, 10, 36, 28) 
+0

Desafortunadamente, 'dateutil' no es un módulo estándar, o al menos no está instalado en las computadoras de mi lugar de trabajo. :( – Staunch

+0

entonces, dado que strptime solo admite especificadores de formato ansi, debe convertir todos los no estándar (que pueda). Puede usar las listas de la documentación de strftime en su plataforma, como: http: //linux.die. net/man/3/strftime (y use un dict en lugar de 'if's) –

+0

, pero la mejor opción podría ser almacenar todas las fechas como unixtimestamps y solo convertir con strftime cuando necesite mostrarlas –

Cuestiones relacionadas