python - mexico - timezones wiki
¿Cómo obtener la configuración de zona horaria del sistema y pasarla a pytz.timezone? (4)
Podemos usar time.tzname
obtener un nombre de zona horaria local, pero ese nombre no es compatible con pytz.timezone
.
De hecho, el nombre devuelto por time.tzname
es ambiguo. Este método devuelve (''CST'', ''CST'')
en mi sistema, pero ''CST'' puede indicar cuatro zonas horarias:
- Zona horaria central (América del Norte): observada en la zona horaria central de América del Norte
- Hora estándar de China
- Hora estándar de Chungyuan: el término "hora estándar de Chungyuan" ahora se usa raramente en Taiwán
- Hora estándar central de Australia (ACST)
No sé si esto es útil para ti o no, pero creo que responde a tu problema más general:
si tiene una fecha que se encuentra en una zona horaria ambigua, como CST
, simple-date (Python 3.2+ solamente, lo siento) puede automatizar la búsqueda y le permite hacer cosas como preferir ciertos países.
por ejemplo:
>>> SimpleDate(''2013-07-04 18:53 CST'')
Traceback [...
simpledate.AmbiguousTimezone: 3 distinct timezones found: <DstTzInfo ''Australia/Broken_Hill'' CST+9:30:00 STD>; <DstTzInfo ''America/Regina'' LMT-1 day, 17:01:00 STD>; <DstTzInfo ''Asia/Harbin'' LMT+8:27:00 STD> (timezones=(''CST'',), datetime=datetime.datetime(2013, 7, 4, 18, 53), is_dst=False, country=None, unsafe=False)
>>> SimpleDate(''2013-07-04 18:53 CST'', country=''CN'')
SimpleDate(''2013-07-04 18:53 CST'')
>>> SimpleDate(''2013-07-04 18:53 CST'', country=''CN'').utc
SimpleDate(''2013-07-04 10:53 UTC'', tz=''UTC'')
observe cómo, al especificar un país, reduce el rango de valores posibles lo suficiente para permitir la conversión a UTC.
se implementa haciendo una búsqueda sobre las zonas horarias en PyTZ:
>>> SimpleDate(''2013-07-04 18:53 CST'', country=''CN'', debug=True)
...
PyTzFactory: Have country code CN
PyTzFactory: Country code CN has 5 timezones
PyTzFactory: Expanded country codes to 5 timezones
PyTzFactory: Expanding (''CST'',)
PyTzFactory: Name lookup failed for CST
PyTzFactory: Found CST using Asia/Shanghai
PyTzFactory: Found CST using Asia/Harbin
PyTzFactory: Found CST using Asia/Chongqing
PyTzFactory: Found CST using Asia/Urumqi
PyTzFactory: Found CST using Asia/Kashgar
PyTzFactory: Expanded timezone to 5 timezones
PyTzFactory: New offset 8:00:00 for Asia/Shanghai
PyTzFactory: Known offset 8:00:00 for Asia/Harbin
PyTzFactory: Known offset 8:00:00 for Asia/Chongqing
PyTzFactory: Known offset 8:00:00 for Asia/Urumqi
PyTzFactory: Known offset 8:00:00 for Asia/Kashgar
PyTzFactory: Have 1 distinct timezone(s)
PyTzFactory: Found Asia/Shanghai
...
SimpleDate(''2013-07-04 18:53 CST'')
finalmente, para responder la pregunta directamente, también ajusta tzlocal, como se menciona en otra respuesta aquí, por lo que automáticamente hará lo que esperas si no le das una zona horaria. por ejemplo, yo vivo en chile, entonces
>>> SimpleDate()
SimpleDate(''2013-07-04 19:21:25.757222 CLT'', tz=''America/Santiago'')
>>> SimpleDate().tzinfo
<DstTzInfo ''America/Santiago'' CLT-1 day, 20:00:00 STD>
da la zona horaria de mi localidad (ambigua o no).
Un método muy simple para resolver esta pregunta:
import time
def localTzname():
offsetHour = time.timezone / 3600
return ''Etc/GMT%+d'' % offsetHour
Actualización : @MartijnPieters dijo ''Esto no funcionará con horario de verano / verano''. Entonces, ¿qué hay de esta versión?
import time
def localTzname():
if time.daylight:
offsetHour = time.altzone / 3600
else:
offsetHour = time.timezone / 3600
return ''Etc/GMT%+d'' % offsetHour
Use la función python-dateutil
paquete python-dateutil
:
from dateutil.tz import tzlocal
localtimezone = tzlocal()
Internamente, esta es una clase que usa time.timezone
y time.altzone
(switching basado en time.daylight
), pero crea un objeto de zona horaria adecuado a partir de eso.
pytz
esto en lugar de una pytz
horaria pytz
.
La alternativa es leer en cambio la zona horaria configurada actualmente del sistema operativo, pero esto difiere ampliamente del sistema operativo al sistema operativo. En Mac OS X necesita leer la salida de systemsetup -gettimezone
:
$ systemsetup -gettimezone
Time Zone: Europe/Copenhagen
En los sistemas Debian y Ubuntu, puede leer /etc/timezone
:
$ cat /etc/timezone
Europe/Oslo
En los sistemas RedHat y Directed, deberá leerlo desde /etc/sysconfig/clock
:
$ grep ZONE /etc/sysconfig/clock
ZONE="Europe/Oslo"
tzlocal
módulo tzlocal devuelve el objeto de pytz tzinfo correspondiente a la zona horaria local:
import time
from datetime import datetime
import pytz # $ pip install pytz
from tzlocal import get_localzone # $ pip install tzlocal
# get local timezone
local_tz = get_localzone()
# test it
# utc_now, now = datetime.utcnow(), datetime.now()
ts = time.time()
utc_now, now = datetime.utcfromtimestamp(ts), datetime.fromtimestamp(ts)
local_now = utc_now.replace(tzinfo=pytz.utc).astimezone(local_tz) # utc -> local
assert local_now.replace(tzinfo=None) == now
Funciona incluso durante las transiciones de horario de verano cuando la hora local puede ser ambigua.
local_tz
también funciona para fechas pasadas, incluso si el desplazamiento utc para la zona horaria local era diferente en ese momento. dateutil.tz.tzlocal()
solución basada en dateutil.tz.tzlocal()
falla en este caso, por ejemplo, en la zona horaria de Europa / Moscú (ejemplo de 2013):
>>> import os, time
>>> os.environ[''TZ''] = ''Europe/Moscow''
>>> time.tzset()
>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>> from tzlocal import get_localzone
>>> dateutil_tz = tzlocal()
>>> tzlocal_tz = get_localzone()
>>> datetime.fromtimestamp(0, dateutil_tz)
datetime.datetime(1970, 1, 1, 4, 0, tzinfo=tzlocal())
>>> datetime.fromtimestamp(0, tzlocal_tz)
datetime.datetime(1970, 1, 1, 3, 0, tzinfo=<DstTzInfo ''Europe/Moscow'' MSK+3:00:00 STD>)
dateutil devuelve el desplazamiento UTC + 4 incorrecto en lugar del UTC + 3 correcto el 1970-01-01.
Para aquellos que chocan con esto en 2017 dateutil.tz.tzlocal()
todavía está roto. El ejemplo anterior funciona ahora porque el desplazamiento utf actual es UTC + 3 en Moscú (que por accidente es igual al desplazamiento utc desde 1970). Para demostrar el error, podemos elegir una fecha cuando utc offset es UTC + 4:
>>> import os, time
>>> os.environ[''TZ''] = ''Europe/Moscow''
>>> time.tzset()
>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>> from tzlocal import get_localzone
>>> dateutil_tz = tzlocal()
>>> tzlocal_tz = get_localzone()
>>> ts = datetime(2014, 6,1).timestamp() # get date in 2014 when gmtoff=14400 in Moscow
>>> datetime.fromtimestamp(ts, dateutil_tz)
datetime.datetime(2014, 5, 31, 23, 0, tzinfo=tzlocal())
>>> datetime.fromtimestamp(ts, tzlocal_tz)
datetime.datetime(2014, 6, 1, 0, 0, tzinfo=<DstTzInfo ''Europe/Moscow'' MSK+4:00:00 STD>)
dateutil devuelve el desplazamiento UTC + 3 incorrecto en lugar del UTC + 4 correcto el 2014-06-01.