example create change biblioteca python linux datetime timezone localtime

create - timedelta python example



Obtener el nombre de Olson TZ para la zona horaria local? (11)

¿Cómo obtengo el nombre de la zona horaria de Olson (como Australia/Sydney ) correspondiente al valor dado por la llamada de localtime de C?

Este es el valor anulado a través de TZ , mediante la vinculación simbólica /etc/localtime , o la configuración de una variable TIMEZONE en los archivos de configuración del sistema relacionados con la hora.


Aquí hay otra posibilidad, usando PyICU en PyICU lugar; que está funcionando para mis propósitos:

>>> from PyICU import ICUtzinfo >>> from datetime import datetime >>> datetime(2012, 1, 1, 12, 30, 18).replace(tzinfo=ICUtzinfo.getDefault()).isoformat() ''2012-01-01T12:30:18-05:00'' >>> datetime(2012, 6, 1, 12, 30, 18).replace(tzinfo=ICUtzinfo.getDefault()).isoformat() ''2012-06-01T12:30:18-04:00''

Aquí se están interpretando los tiempos de datos niave (como serían devueltos por una consulta de base de datos) en la zona horaria local.


Cambié el script de tcurvelo para encontrar la forma correcta de zona horaria (Continente /..../ Ciudad), en la mayoría de los casos, pero devolverlos todos si falla

#!/usr/bin/env python from hashlib import sha224 import os from os import listdir from os.path import join, isfile, isdir infoDir = ''/usr/share/zoneinfo/'' def get_current_olsonname(): result = [] tzfile_digest = sha224(open(''/etc/localtime'').read()).hexdigest() test_match = lambda filepath: sha224(open(filepath).read()).hexdigest() == tzfile_digest def walk_over(dirpath): for root, dirs, filenames in os.walk(dirpath): for fname in filenames: fpath = join(root, fname) if test_match(fpath): result.append(tuple(root.split(''/'')[4:]+[fname])) for dname in listdir(infoDir): if dname in (''posix'', ''right'', ''SystemV'', ''Etc''): continue dpath = join(infoDir, dname) if not isdir(dpath): continue walk_over(dpath) if not result: walk_over(join(infoDir)) return result if __name__ == ''__main__'': print get_current_olsonname()


Creo que lo mejor es ir a través de todas las zonas horarias de pytz y verificar cuál coincide con la zona horaria local, cada objeto de zona horaria pytz contiene información sobre utcoffset y tzname como CDT, EST. La misma información sobre la hora local se puede obtener de time.timezone/altzone y time.tzname , y creo que es suficiente para hacer coincidir correctamente la zona horaria local en la base de datos pytz, por ejemplo

import time import pytz import datetime local_names = [] if time.daylight: local_offset = time.altzone localtz = time.tzname[1] else: local_offset = time.timezone localtz = time.tzname[0] local_offset = datetime.timedelta(seconds=-local_offset) for name in pytz.all_timezones: timezone = pytz.timezone(name) if not hasattr(timezone, ''_tzinfos''): continue#skip, if some timezone doesn''t have info # go thru tzinfo and see if short name like EDT and offset matches for (utcoffset, daylight, tzname), _ in timezone._tzinfos.iteritems(): if utcoffset == local_offset and tzname == localtz: local_names.append(name) print local_names

salida:

[''America / Atikokan'', ''America / Bahia_Banderas'', ''America / Bahia_Banderas'', ''America / Belize'', ''America / Cambridge_Bay'', ''America / Cancun'', ''America / Chicago'', ''America / Chihuahua'', '' America / Coral_Harbour '','' America / Costa_Rica '','' America / El_Salvador '','' America / Fort_Wayne '','' America / Guatemala '','' America / Indiana / Indianapolis '','' America / Indiana / Knox '','' America / Indiana / Marengo '','' America / Indiana / Marengo '','' America / Indiana / Petersburg '','' America / Indiana / Tell_City '','' America / Indiana / Vevay '','' America / Indiana / Vincennes '','' America / Indiana / Winamac '' , ''America / Indianapolis'', ''America / Iqaluit'', ''America / Kentucky / Louisville'', ''America / Kentucky / Louisville'', ''America / Kentucky / Monticello'', ''America / Knox_IN'', ''America / Louisville'', '' America / Louisville '','' America / Managua '','' America / Matamoros '','' America / Menominee '','' America / Merida '','' America / Mexico_City '','' America / Monterrey '','' America / North_Dakota / Beulah '','' America / North_Dakota / Center '','' America / North_Dakota / New_Salem '','' America / Ojinaga '','' America / Pangnirtung '','' Am erica / Rainy_River '','' America / Rankin_Inlet '','' America / Resolute '','' America / Resolute '','' America / Tegucigalpa '','' America / Winnipeg '','' CST6CDT '','' Canada / Central '','' Mexico / General '' , ''US / Central'', ''US / East-Indiana'', ''US / Indiana-Starke'']

En producción, puede crear dicho mapeo de antemano y guardarlo en lugar de iterarlo siempre.

Prueba de script después de cambiar la zona horaria:

$ exportación TZ = ''Australia / Sydney''
$ python get_tz_names.py
[''Antarctica / Macquarie'', ''Australia / ACT'', ''Australia / Brisbane'', ''Australia / Canberra'', ''Australia / Currie'', ''Australia / Hobart'', ''Australia / Lindeman'', ''Australia / Melbourne'', '' Australia / NSW '','' Australia / Queensland '','' Australia / Sydney '','' Australia / Tasmania '','' Australia / Victoria '']


El módulo tzlocal para Python está dirigido exactamente a este problema. Produce resultados consistentes tanto en Linux como en Windows, convirtiendo correctamente las identificaciones de zona horaria de Windows a Olson usando las asignaciones de CLDR.


Esto es una especie de trampa, lo sé, ¿pero obtener de ''/etc/localtime'' no funciona para usted? Como siguiendo

>>> import os >>> ''/''.join(os.readlink(''/etc/localtime'').split(''/'')[-2:]) ''Australia/Sydney''

Espero eso ayude.

Edición : Me gustó la idea de @ AH, en caso de que ''/etc/localtime'' no sea un enlace simbólico. Traduciendo eso a Python:

#!/usr/bin/env python from hashlib import sha224 import os def get_current_olsonname(): tzfile = open(''/etc/localtime'') tzfile_digest = sha224(tzfile.read()).hexdigest() tzfile.close() for root, dirs, filenames in os.walk("/usr/share/zoneinfo/"): for filename in filenames: fullname = os.path.join(root, filename) f = open(fullname) digest = sha224(f.read()).hexdigest() if digest == tzfile_digest: return ''/''.join((fullname.split(''/''))[-2:]) f.close() return None if __name__ == ''__main__'': print get_current_olsonname()


Esto le dará el nombre de la zona horaria, de acuerdo con lo que está en la variable TZ, o el archivo de hora local si no está configurado:

#! /usr/bin/env python import time time.tzset print time.tzname


Prefiero seguir un poco mejor que hurgando en los valores de _xxx

import time, pytz, os cur_name=time.tzname cur_TZ=os.environ.get("TZ") def is_current(name): os.environ["TZ"]=name time.tzset() return time.tzname==cur_name print "Possible choices:", filter(is_current, pytz.all_timezones) # optional tz restore if cur_TZ is None: del os.environ["TZ"] else: os.environ["TZ"]=cur_TZ time.tzset()


Si la evaluación de /etc/localtime está bien para usted, el siguiente truco podría funcionar, después de traducirlo a Python:

> md5sum /etc/localtime abcdefabcdefabcdefabcdefabcdefab /etc/localtime > find /usr/share/zoneinfo -type f |xargs md5sum | grep abcdefabcdefabcdefabcdefabcdefab abcdefabcdefabcdefabcdefabcdefab /usr/share/zoneinfo/Europe/London abcdefabcdefabcdefabcdefabcdefab /usr/share/zoneinfo/posix/Europe/London ...

Los duplicados podrían filtrarse usando solo los nombres de región oficiales "Europa", "América" ​​... Si todavía hay duplicados, puede tomar el nombre más corto :-)


Un problema es que hay varios "nombres bonitos", como "Australia / Sydney", que apuntan a la misma zona horaria (por ejemplo, CST).

Por lo tanto, deberá obtener todos los nombres posibles para la zona horaria local y luego seleccionar el nombre que desee.

Por ejemplo: para Australia, hay 5 zonas horarias, pero muchos más identificadores de zona horaria:

"Australia/Lord_Howe", "Australia/Hobart", "Australia/Currie", "Australia/Melbourne", "Australia/Sydney", "Australia/Broken_Hill", "Australia/Brisbane", "Australia/Lindeman", "Australia/Adelaide", "Australia/Darwin", "Australia/Perth", "Australia/Eucla"

debe comprobar si hay una biblioteca que contenga TZinfo , para manejar la API de zona horaria.

Por ejemplo: para Python, verifique la biblioteca pytz :

http://pytz.sourceforge.net/

y

http://pypi.python.org/pypi/pytz/

En Python puedes hacer:

from pytz import timezone import pytz In [56]: pytz.country_timezones(''AU'') Out[56]: [u''Australia/Lord_Howe'', u''Australia/Hobart'', u''Australia/Currie'', u''Australia/Melbourne'', u''Australia/Sydney'', u''Australia/Broken_Hill'', u''Australia/Brisbane'', u''Australia/Lindeman'', u''Australia/Adelaide'', u''Australia/Darwin'', u''Australia/Perth'', u''Australia/Eucla'']

pero la API para Python parece ser bastante limitada, por ejemplo, no parece tener una llamada como todos los nombres de zona de all_linked_zone_names de Ruby, que pueden encontrar todos los nombres de sinónimos para una zona horaria determinada.


Instalar pytz

import pytz import time #import locale import urllib2 yourOlsonTZ = None #yourCountryCode = locale.getdefaultlocale()[0].split(''_'')[1] yourCountryCode = urllib2.urlopen(''http://api.hostip.info/country.php'').read() for olsonTZ in [pytz.timezone(olsonTZ) for olsonTZ in pytz.all_timezones]: if (olsonTZ._tzname in time.tzname) and (str(olsonTZ) in pytz.country_timezones[yourCountryCode]): yourOlsonTZ = olsonTZ break print yourOlsonTZ

Este código tomará la mejor decisión de adivinar en su Zona horaria de Olson tanto en su Nombre de zona horaria (según el módulo de time de Python) como en su Código de país (según el módulo de locale del proyecto hostip.info , que hace referencia a su dirección IP). y te geolocaliza en consecuencia).

Por ejemplo, simplemente hacer coincidir los Nombres de la zona del tiempo podría resultar en America/Moncton , America/Montreal o America/New_York para EST (GMT-5). Si su país es los EE. UU., Sin embargo, limitará la respuesta a America/New_York .

Sin embargo, si su país es Canadá, el guión simplemente tomará como valor predeterminado el resultado canadiense más alto ( America/Moncton ). Si hay una manera de refinar esto aún más, no dude en dejar sugerencias en los comentarios.


Este proyecto de JavaScript intenta resolver el mismo problema en el lado del cliente del navegador. Funciona jugando "veinte preguntas" con la configuración regional, solicitando el desplazamiento UTC de ciertos tiempos pasados ​​(para probar los límites del horario de verano, etc.) y usar esos resultados para deducir cuál debe ser la zona horaria local. Lamentablemente, no conozco ningún paquete Python equivalente, por lo que si alguien quisiera usar esta solución, tendría que ser portado a Python.

Si bien esta fórmula requerirá la actualización cada vez (en el peor de los casos) la base de datos TZ se actualizará, una combinación de este algoritmo y la solución propuesta por Anurag Uniyal (manteniendo solo las posibilidades devueltas por ambos métodos) me parece la forma más segura de calcular la eficacia. zona horaria local. Siempre que haya alguna diferencia entre el desplazamiento UTC de al menos una hora local en cualquiera de las dos zonas horarias, este sistema puede elegir correctamente entre ellas.