2010-08-15 13 views
9

En un proyecto de Python en el que estoy trabajando, me gustaría poder obtener un nombre de zona horaria "legible por humanos" del formulario America/New_York, correspondiente a la zona horaria local del sistema, para mostrar al usuario . Cada pieza de código que he visto que accede a información de zona horaria solo devuelve un desplazamiento numérico (-0400) o un código de letra (EDT) o, a veces, ambos. ¿Hay alguna biblioteca de Python que pueda acceder a esta información, o, si no es así, convertir el código de desplazamiento/letra en un nombre legible para el ser humano?¿Cómo puedo obtener un nombre de zona horaria legible para humanos en Python?

Si hay más de un nombre legible por humanos correspondiente a una zona horaria en particular, una lista de resultados posibles o cualquiera de ellos está bien, y si no hay un nombre legible por humanos que corresponda a la zona horaria actual, Tomaré una excepción o None o [] o lo que sea.

+2

necesita tener cuidado con la forma de usar esto, creo. solo un ejemplo: cuando en Europa/Roma pasamos de CEST a CET en octubre de 2010, se registraron tanto '2010-10-31T02: 30: 00CEST' como' 2010-10-31T02: 30: 00CET', uno equivalente a '2010-10-31T00: 30: 00UTC' y el otro a' 2010-10-31T01: 30: 00UTC'. '2010-10-31T02: 30: 00 Europe/Rome' sería ambiguo. – mariotomo

Respuesta

8

http://pytz.sourceforge.net/ pueden ser de ayuda. Si nada más, puede obtener una lista de todas las zonas horarias y luego repetir hasta encontrar una que coincida con su desplazamiento.

+3

Iterar de nuevo no es una mala idea. Me gustaría iterar a través de todos ellos una vez y crear un archivo 'shelve' o simplemente almacenar un' dict' en un módulo o algo escrito por el código de la letra. Entonces puedes enviar el 'dict' con la aplicación y no tener que realizar la búsqueda dos veces. Ni siquiera tendrías que enviar 'pytz' en ese caso: podrías usarlo en el script que construye el' dict' – aaronasterling

+1

Sí. Es algo que funciona bien con solo el cálculo previo (o incluso simplemente compilarlo en el inicio, no toma * tanto * si solo lo haces una vez por ejecución). – Amber

+1

[el módulo 'tzlocal' puede encontrar el objeto' pytz' tzinfo que corresponde a la zona horaria local] (http://stackoverflow.com/a/35086646/4279) – jfs

1

Salida python-dateutil

py> from dateutil.tz import * 
py> ny = gettz('America/New York') 
py> ny._filename 
'/usr/share/zoneinfo/America/New_York' 
py> ny._filename.split('/', 4)[-1] 
'America/New_York' 
+0

Pero eso no me ayuda si tengo un objeto 'tzinfo' que no se obtuvo de' dateutil.tz.gettz' - por ejemplo, uno de 'pytz' - o si acabo de llamar a' gettz() ' en cuyo caso, el nombre del archivo es '/ etc/localtime'). (Todavía aprecio la información) –

+0

Bueno, ¿de dónde vienen estos objetos de zona horaria? Puede almacenar el nombre de la zona horaria - el argumento de cadena a 'gettz' - y reconstituir las zonas horarias usando ese argumento y' gettz'. Supongo que estoy asumiendo ciertos casos de uso, por ejemplo, almacenar una hora y la cadena de zona horaria asociada en una base de datos. Nunca utilizaría 'gettz' solo para obtener la zona horaria local, pero también en mi caso el usuario sería una persona detrás de un navegador web. –

9

A continuación se genera un mapeo defaultdict compensaciones de zona horaria (por ejemplo, '-0400') y abreviaturas (por ejemplo, 'EDT') a los nombres de zona horaria geográficas comunes (por ejemplo, 'América/New_York') .

import os 
import dateutil.tz as dtz 
import pytz 
import datetime as dt 
import collections 

result=collections.defaultdict(list) 
for name in pytz.common_timezones: 
    timezone=dtz.gettz(name) 
    now=dt.datetime.now(timezone) 
    offset=now.strftime('%z') 
    abbrev=now.strftime('%Z') 
    result[offset].append(name) 
    result[abbrev].append(name)  
print(result) 

Obsérvese que las abreviaturas de zona horaria pueden tener vastly different meanings. Por ejemplo, 'EST' podría significar Eastern Summer Time (UTC + 10) en Australia, o Eastern Standard Time (UTC-5) en América del Norte.

Además, los desplazamientos y las abreviaturas pueden cambiar para las regiones que usan la hora estándar de luz natural. Así que guardar el dict estático puede no proporcionar el nombre correcto de la zona horaria los 365 días del año.

3

Si solo quieres literalmente lo que pediste, "el nombre de la zona horaria del formulario America/New_York, correspondiente al sistema de zona horaria local", y si solo te preocupa Linux (y similares), entonces esto debería hacer trabajo:

import os 
import os.path 
import sys 

def main(argv): 
    tzname = os.environ.get('TZ') 
    if tzname: 
    print tzname 
    elif os.path.exists('/etc/timezone'): 
    print file('/etc/timezone').read() 
    else: 
    sys.exit(1) 

if __name__ == '__main__': 
    main(sys.argv) 

por supuesto que sería mejor tener una biblioteca que encapsula esto de una manera más limpia, y que tal vez se encarga de los otros casos que usted menciona en comentarios como que ya tiene un objeto tzinfo. Creo que se puede hacer eso con pytz mencionado por Amber, pero no es obvio para mí lo ...

4

me gustaría ser capaz de obtener un nombre de zona horaria "legible" de la forma de América/New_York, correspondiente a la zona horaria local del sistema, para mostrar al usuario.

Hay tzlocal module que devuelve un objeto pytz tzinfo que se corresponde con el sistema de zona horaria local:

#!/usr/bin/env python 
import tzlocal # $ pip install tzlocal 

print(tzlocal.get_localzone().zone) # display "human-readable" name (tzid) 
# -> Europe/Moscow 

Para responder a la pregunta del título (para la gente de Google), podría utilizar %Z%z para imprimir la información de zona horaria local:

#!/usr/bin/env python 
import time 

print(time.strftime('%Z%z')) 
# -> MSK+0300 

imprime la zona horaria actual abreviatura y el desplazamiento UTC correspondiente a su zona horaria local.

Cuestiones relacionadas