example change biblioteca python datetime time timezone utc

change - Python: Calcula la zona horaria local



set timezone to datetime python (13)

para comparar las marcas de tiempo UTC de un archivo de registro con marcas de tiempo locales.

Es difícil encontrar el nombre de Olson TZ para una zona horaria local de una manera portátil. Afortunadamente, no lo necesita para realizar la comparación.

tzlocal módulo tzlocal devuelve una zona horaria pytz correspondiente a la zona horaria local:

from datetime import datetime import pytz # $ pip install pytz from tzlocal import get_localzone # $ pip install tzlocal tz = get_localzone() local_dt = tz.localize(datetime(2010, 4, 27, 12, 0, 0, 0), is_dst=None) utc_dt = local_dt.astimezone(pytz.utc) #NOTE: utc.normalize() is unnecessary here

A diferencia de otras soluciones presentadas hasta ahora, el código anterior evita los siguientes problemas:

  • la hora local puede ser ambigua , es decir, una comparación precisa podría ser imposible para algunos momentos locales
  • utc offset puede ser diferente para el mismo nombre de zona horaria local para las fechas del pasado. Algunas bibliotecas que admiten objetos datetime con dateutil zona horaria (p. Ej., dateutil ) no lo tienen en cuenta

Nota: para obtener el objeto datetime compatible con la zona horaria de un objeto datetime ingenuo, debe usar * :

local_dt = tz.localize(datetime(2010, 4, 27, 12, 0, 0, 0), is_dst=None)

en lugar de:

#XXX fails for some timezones local_dt = datetime(2010, 4, 27, 12, 0, 0, 0, tzinfo=tz)

* is_dst=None fuerza una excepción si la hora local dada es ambigua o inexistente.

Si está seguro de que todas las marcas de tiempo locales usan el mismo desplazamiento de utc (actual) para la zona horaria local, entonces podría realizar la comparación utilizando solo stdlib:

# convert a naive datetime object that represents time in local timezone to epoch time timestamp1 = (datetime(2010, 4, 27, 12, 0, 0, 0) - datetime.fromtimestamp(0)).total_seconds() # convert a naive datetime object that represents time in UTC to epoch time timestamp2 = (datetime(2010, 4, 27, 9, 0) - datetime.utcfromtimestamp(0)).total_seconds()

timestamp1 y timestamp2 se pueden comparar directamente.

Nota:

  • timestamp1 fórmula timestamp1 funciona solo si el desplazamiento UTC en época ( datetime.fromtimestamp(0) ) es el mismo que ahora
  • fromtimestamp() crea un objeto naive datetime en la zona horaria local actual
  • utcfromtimestamp() crea un objeto naive datetime en UTC.

Quiero comparar las marcas de tiempo UTC de un archivo de registro con marcas de tiempo locales. Al crear el objeto local de datetime , utilizo algo como:

>>> local_time=datetime.datetime(2010, 4, 27, 12, 0, 0, 0, tzinfo=pytz.timezone(''Israel''))

Quiero encontrar una herramienta automática que reemplace el tzinfo=pytz.timezone(''Israel'') con la zona horaria local actual.

¿Algunas ideas?


Aquí hay una versión un poco más concisa de la solución de @ vbem:

from datetime import datetime as dt dt.utcnow().astimezone().tzinfo

La única diferencia sustancial es que reemplacé datetime.datetime.now(datetime.timezone.utc) con datetime.datetime.utcnow() . Para abreviar, también di alias datetime.datetime como dt .

Para mis propósitos, quiero el desplazamiento UTC en segundos. Esto es lo que parece:

dt.utcnow().astimezone().utcoffset().total_seconds()


En Python 3.x, la zona horaria local puede averiguarse así:

import datetime LOCAL_TIMEZONE = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo

Es un uso complicado del code de datetime y datetime .


En función de la respuesta anterior de Thoku, aquí hay una respuesta que resuelve la zona horaria a la media hora más cercana (que es relevante para algunas zonas horarias, por ejemplo, en Australia del Sur):

from datetime import datetime round((round((datetime.now()-datetime.utcnow()).total_seconds())/1800)/2)


En primer lugar, tenga en cuenta que la pregunta presenta una inicialización incorrecta de un objeto datetime consciente:

>>> local_time=datetime.datetime(2010, 4, 27, 12, 0, 0, 0, ... tzinfo=pytz.timezone(''Israel''))

crea una instancia inválida Uno puede ver el problema calculando el desplazamiento UTC del objeto resultante:

>>> print(local_time.utcoffset()) 2:21:00

(Tenga en cuenta el resultado que es una fracción impar de una hora).

Para inicializar un datetime con conocimiento utilizando pytz uno debe usar el método localize() siguiente manera:

>>> local_time=pytz.timezone(''Israel'').localize(datetime.datetime(2010, 4, 27, 12)) >>> print(local_time.utcoffset()) 3:00:00

Ahora, si necesita una zona horaria pytz local como el nuevo tzinfo, debe usar el paquete tzlocal como otros han explicado, pero si todo lo que necesita es una instancia con un desplazamiento y abreviación de zona horaria local correctos y luego con Python 3.3, puede llame al método astimezone() sin argumentos para convertir una instancia de datetime conocida en su zona horaria local:

>>> local_time.astimezone().strftime(''%Y-%m-%d %H:%M %Z %z'') ''2010-04-27 05:00 EDT -0400''


Esta es una forma de obtener la zona horaria local utilizando solo la biblioteca estándar (solo funciona en un entorno * nix):

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

Puede usar esto para crear una pytz horaria de pytz :

>>> import pytz >>> my_tz_name = ''/''.join(os.path.realpath(''/etc/localtime'').split(''/'')[-2:]) >>> my_tz = pytz.timezone(my_tz_name) >>> my_tz <DstTzInfo ''Australia/Sydney'' LMT+10:05:00 STD>

... que luego puede aplicar a una datetime y datetime :

>>> import datetime >>> now = datetime.datetime.now() >>> now datetime.datetime(2014, 9, 3, 9, 23, 24, 139059) >>> now.replace(tzinfo=my_tz) >>> now datetime.datetime(2014, 9, 3, 9, 23, 24, 139059, tzinfo=<DstTzInfo ''Australia/Sydney'' LMT+10:05:00 STD>)


Evitar el módulo no estándar (parece ser un método que falta del módulo datetime):

from datetime import datetime utcOffset_min = int(round((datetime.now() - datetime.utcnow()).total_seconds())) / 60 # round for taking time twice utcOffset_h = utcOffset_min / 60 assert(utcOffset_min == utcOffset_h * 60) # we do not handle 1/2 h timezone offsets print ''Local time offset is %i h to UTC.'' % (utcOffset_h)


Me estaba preguntando lo mismo a mí mismo, y encontré la respuesta en 1:

Eche un vistazo a la sección 8.1.7: el formato "% z" (minúscula, la mayúscula Z también devuelve la zona horaria, pero no en el formato de 4 dígitos, sino en forma de abreviaturas de zona horaria, como en [3]) of strftime devuelve el formulario "+/- 4DIGIT" que es estándar en los encabezados de correo electrónico (consulte la sección 3.3 de RFC 2822, consulte [2], que obsoleta las otras formas de especificar la zona horaria para los encabezados de correo electrónico).

Entonces, si quieres tu zona horaria en este formato, usa:

time.strftime("%z")

[1] http://docs.python.org/2/library/datetime.html

[2] http://tools.ietf.org/html/rfc2822#section-3.3

[3] Abreviaturas de zona horaria: http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations , solo para referencia.


Para cosas simples, se puede usar la siguiente implementación de tzinfo , que consulta el sistema operativo para las compensaciones de zona horaria:

import datetime import time class LocalTZ(datetime.tzinfo): _unixEpochOrdinal = datetime.datetime.utcfromtimestamp(0).toordinal() def dst(self, dt): return datetime.timedelta(0) def utcoffset(self, dt): t = (dt.toordinal() - self._unixEpochOrdinal)*86400 + dt.hour*3600 + dt.minute*60 + dt.second + time.timezone utc = datetime.datetime(*time.gmtime(t)[:6]) local = datetime.datetime(*time.localtime(t)[:6]) return local - utc print datetime.datetime.now(LocalTZ()) print datetime.datetime(2010, 4, 27, 12, 0, 0, tzinfo=LocalTZ()) # If you''re in the EU, the following datetimes are right on the DST change. print datetime.datetime(2013, 3, 31, 0, 59, 59, tzinfo=LocalTZ()) print datetime.datetime(2013, 3, 31, 1, 0, 0, tzinfo=LocalTZ()) print datetime.datetime(2013, 3, 31, 1, 59, 59, tzinfo=LocalTZ()) # The following datetime is invalid, as the clock moves directly from # 01:59:59 standard time to 03:00:00 daylight savings time. print datetime.datetime(2013, 3, 31, 2, 0, 0, tzinfo=LocalTZ()) print datetime.datetime(2013, 10, 27, 0, 59, 59, tzinfo=LocalTZ()) print datetime.datetime(2013, 10, 27, 1, 0, 0, tzinfo=LocalTZ()) print datetime.datetime(2013, 10, 27, 1, 59, 59, tzinfo=LocalTZ()) # The following datetime is ambigous, as 02:00 can be either DST or standard # time. (It is interpreted as standard time.) print datetime.datetime(2013, 10, 27, 2, 0, 0, tzinfo=LocalTZ())


Primero obtener los módulos pytz y tzlocal

pip install pytz tzlocal

entonces

from tzlocal import get_localzone local = get_localzone()

entonces puedes hacer cosas como

from datetime import datetime print(datetime.now(local))



Según la respuesta de JF Sebastian , puede hacer esto con la biblioteca estándar:

import time, datetime local_timezone = datetime.timezone(datetime.timedelta(seconds=-time.timezone))

Probado en 3.4, debería funcionar en 3.4+


tzlocal de dateutil .

El ejemplo del código sigue. Última cadena adecuada para usar en nombres de archivos.

>>> from datetime import datetime >>> from dateutil.tz import tzlocal >>> str(datetime.now(tzlocal())) ''2015-04-01 11:19:47.980883-07:00'' >>> str(datetime.now(tzlocal())).replace('' '',''-'').replace('':'','''').replace(''.'',''-'') ''2015-04-01-111947-981879-0700'' >>>