zoneinfo — Soporte de zona horaria IANA

Nuevo en la versión 3.9.


El módulo zoneinfo proporciona una implementación concreta de zonas horarias para soportar la base de datos de zonas horarias de IANA tal y como se especificó originalmente en PEP 615. Por defecto, zoneinfo utiliza los datos de zona horaria del sistema si están disponibles; si no hay datos de zona horaria del sistema, la biblioteca volverá a utilizar el paquete de primera parte tzdata disponible en PyPI.

Ver también

Modulo: datetime

Proporciona los tipos time y datetime con los que está diseñada la clase ZoneInfo.

Paquete tzdata

Paquete de origen mantenido por los desarrolladores del núcleo de CPython para suministrar datos de zonas horarias a través de PyPI.

Usando ZoneInfo

ZoneInfo es una implementación concreta de la clase base abstracta datetime.tzinfo, y está pensada para ser adjuntada a tzinfo, bien a través del constructor, del método datetime.replace o de datetime.astimezone:

>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime, timedelta

>>> dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("America/Los_Angeles"))
>>> print(dt)
2020-10-31 12:00:00-07:00

>>> dt.tzname()
'PDT'

Las fechas construidas de esta manera son compatibles con la aritmética de fechas y manejan las transiciones del horario de verano sin ninguna otra intervención:

>>> dt_add = dt + timedelta(days=1)

>>> print(dt_add)
2020-11-01 12:00:00-08:00

>>> dt_add.tzname()
'PST'

Estas zonas horarias también soportan el atributo fold introducido en PEP 495. Durante las transiciones de desfase que inducen tiempos ambiguos (como una transición de horario de verano a horario estándar), se utiliza el desfase de antes de la transición cuando fold=0, y el desfase después de la transición cuando fold=1, por ejemplo:

>>> dt = datetime(2020, 11, 1, 1, tzinfo=ZoneInfo("America/Los_Angeles"))
>>> print(dt)
2020-11-01 01:00:00-07:00

>>> print(dt.replace(fold=1))
2020-11-01 01:00:00-08:00

Al convertir desde otra zona horaria, el pliegue se ajustará al valor correcto:

>>> from datetime import timezone
>>> LOS_ANGELES = ZoneInfo("America/Los_Angeles")
>>> dt_utc = datetime(2020, 11, 1, 8, tzinfo=timezone.utc)

>>> # Before the PDT -> PST transition
>>> print(dt_utc.astimezone(LOS_ANGELES))
2020-11-01 01:00:00-07:00

>>> # After the PDT -> PST transition
>>> print((dt_utc + timedelta(hours=1)).astimezone(LOS_ANGELES))
2020-11-01 01:00:00-08:00

Fuentes de datos

El módulo zoneinfo no proporciona directamente los datos de la zona horaria, y en su lugar extrae la información de la zona horaria de la base de datos de la zona horaria del sistema o del paquete de PyPI tzdata, si está disponible. Algunos sistemas, incluyendo notablemente los sistemas Windows, no tienen una base de datos IANA disponible, por lo que para los proyectos que tienen como objetivo la compatibilidad entre plataformas que requieren datos de zona horaria, se recomienda declarar una dependencia de tzdata. Si no están disponibles ni los datos del sistema ni los de tzdata, todas las llamadas a ZoneInfo lanzarán un ZoneInfoNotFoundError.

Configurando los orígenes de datos

Cuando se llama a ZoneInfo(key), el constructor busca primero en los directorios especificados en TZPATH un archivo que coincida con key, y en caso de fallo busca una coincidencia en el paquete tzdata. Este comportamiento puede configurarse de tres maneras:

  1. El TZPATH por defecto cuando no se especifica otra cosa puede configurarse en tiempo de compilación.

  2. TZPATH puede configurarse utilizando una variable de entorno.

  3. En runtime, la ruta de búsqueda puede ser manipulada usando la función reset_tzpath().

Configuración en tiempo de compilación

The default TZPATH includes several common deployment locations for the time zone database (except on Windows, where there are no «well-known» locations for time zone data). On POSIX systems, downstream distributors and those building Python from source who know where their system time zone data is deployed may change the default time zone path by specifying the compile-time option TZPATH (or, more likely, the configure flag --with-tzpath), which should be a string delimited by os.pathsep.

En todas las plataformas, el valor configurado está disponible como la clave TZPATH en sysconfig.get_config_var().

Configuración del entorno

Cuando se inicializa TZPATH (ya sea en el momento de la importación o cuando se llama a reset_tzpath() sin argumentos), el módulo zoneinfo utilizará la variable de entorno PYTHONTZPATH, si existe, para establecer la ruta de búsqueda.

PYTHONTZPATH

Se trata de una cadena separada por os.pathsep que contiene la ruta de búsqueda de la zona horaria a utilizar. Debe consistir sólo en rutas absolutas y no relativas. Los componentes relativos especificados en PYTHONTZPATH no se utilizarán, pero por lo demás el comportamiento cuando se especifica una ruta relativa es definido por la implementación; CPython lanzará InvalidTZPathWarning, pero otras implementaciones son libres de ignorar silenciosamente el componente erróneo o lanzar una excepción.

Para que el sistema ignore los datos del sistema y utilice el paquete tzdata en su lugar, establezca PYTHONTZPATH="".

Configuración de tiempo de ejecución

La ruta de búsqueda de TZ también puede configurarse en tiempo de ejecución mediante la función reset_tzpath(). Por lo general, esta operación no es aconsejable, aunque es razonable utilizarla en funciones de prueba que requieran el uso de una ruta de zona horaria específica (o que requieran deshabilitar el acceso a las zonas horarias del sistema).

La clase ZoneInfo

class zoneinfo.ZoneInfo(key)

Una subclase concreta de datetime.tzinfo que representa una zona horaria IANA especificada por la cadena key. Las llamadas al constructor primario siempre devolverán objetos que se comparan de forma idéntica; dicho de otro modo, salvo la invalidación de la caché mediante ZoneInfo.clear_cache(), para todos los valores de key, la siguiente afirmación siempre será verdadera:

a = ZoneInfo(key)
b = ZoneInfo(key)
assert a is b

La key debe tener la forma de una ruta POSIX relativa y normalizada, sin referencias de nivel superior. El constructor lanzará ValueError si se pasa una clave no conforme.

Si no se encuentra ningún archivo que coincida con la clave, el constructor lanzará ZoneInfoNotFoundError.

La clase ZoneInfo tiene dos constructores alternativos:

classmethod ZoneInfo.from_file(fobj, /, key=None)

Construye un objeto ZoneInfo a partir de un objeto tipo archivo que retorna bytes (por ejemplo, un archivo abierto en modo binario o un objeto io.BytesIO). A diferencia del constructor primario, éste siempre construye un nuevo objeto.

El parámetro key establece el nombre de la zona a efectos de __str__() y __repr__().

Los objetos creados a través de este constructor no pueden ser serializados (ver pickling).

classmethod ZoneInfo.no_cache(key)

Un constructor alternativo que omite la caché del constructor. Es idéntico al constructor principal, pero retorna un nuevo objeto en cada llamada. Es muy probable que esto sea útil para propósitos de prueba o demostración, pero también se puede utilizar para crear un sistema con una estrategia de invalidación de caché diferente.

Los objetos creados a través de este constructor también pasarán por encima de la caché de un proceso de deserialización cuando sean deserializados.

Prudencia

El uso de este constructor puede cambiar la semántica de tus datetimes de manera sorprendente, sólo úsalo si sabes que lo necesitas.

También están disponibles los siguientes métodos de clase:

classmethod ZoneInfo.clear_cache(*, only_keys=None)

Un método para invalidar la caché de la clase ZoneInfo. Si no se pasan argumentos, se invalidan todas las cachés y la siguiente llamada al constructor primario de cada clave devolverá una nueva instancia.

Si se pasa un iterable de nombres de claves al parámetro only_keys, sólo se eliminarán de la caché las claves especificadas. Las claves pasadas a only_keys pero que no se encuentran en la caché se ignoran.

Advertencia

La invocación de esta función puede cambiar la semántica de las fechas utilizando ZoneInfo de forma sorprendente; esto modifica el estado global del proceso y por lo tanto puede tener efectos de gran alcance. Utilícela sólo si sabe que lo necesita.

La clase tiene un atributo:

ZoneInfo.key

Se trata de un attribute de sólo lectura que retorna el valor de key pasado al constructor, que debe ser una clave de búsqueda en la base de datos de zonas horarias de la IANA (por ejemplo, America/New_York, Europe/Paris o Asia/Tokyo.

Para las zonas construidas a partir de un archivo sin especificar un parámetro key, se establecerá como None.

Nota

Aunque es una práctica algo común exponerlos a los usuarios finales, estos valores están diseñados para ser claves primarias para representar las zonas relevantes y no necesariamente elementos orientados al usuario. Se pueden utilizar proyectos como CLDR (Unicode Common Locale Data Repository) para obtener cadenas más fáciles de usar a partir de estas claves.

Representaciones de cadenas

La representación de cadena que se retorna al llamar a str sobre un objeto ZoneInfo utiliza por defecto el atributo ZoneInfo.key (ver la nota de uso en la documentación del atributo):

>>> zone = ZoneInfo("Pacific/Kwajalein")
>>> str(zone)
'Pacific/Kwajalein'

>>> dt = datetime(2020, 4, 1, 3, 15, tzinfo=zone)
>>> f"{dt.isoformat()} [{dt.tzinfo}]"
'2020-04-01T03:15:00+12:00 [Pacific/Kwajalein]'

Para los objetos construidos a partir de un fichero sin especificar un parámetro key, str vuelve a llamar a repr`(). El parámetro repr de ZoneInfo está definido por la implementación y no es necesariamente estable entre versiones, pero se garantiza que no es una clave válida de ZoneInfo.Pickled.

Serialización de Pickle

En lugar de serializar todos los datos de transición, los objetos ZoneInfo se serializan por clave, y los objetos ZoneInfo construidos a partir de archivos (incluso los que tienen un valor por key especifico) no pueden ser serializados.

El comportamiento de un archivo ZoneInfo depende de cómo se haya construido:

  1. ZoneInfo(key): Cuando se construye con el constructor primario, un objeto ZoneInfo se serializa por la clave, y cuando se deserializa, el proceso de deserialización utiliza el primario y por lo tanto se espera que estos sean el mismo objeto que otras referencias a la misma zona horaria. Por ejemplo, si europe_berlin_pkl es una cadena que contiene un pickle construido a partir de ZoneInfo("Europe/Berlin"), se esperaría el siguiente comportamiento:

    >>> a = ZoneInfo("Europe/Berlin")
    >>> b = pickle.loads(europe_berlin_pkl)
    >>> a is b
    True
    
  2. ZoneInfo.no_cache(key): Cuando se construye a partir del constructor que evita la caché, el objeto ZoneInfo también se serializa por clave, pero cuando se deserializa, el proceso de deserialización utiliza el constructor que evita la caché. Si europe_berlin_pkl_nc es una cadena que contiene un pickle construido a partir de ZoneInfo.no_cache("Europe/Berlin"), cabría esperar el siguiente comportamiento:

    >>> a = ZoneInfo("Europe/Berlin")
    >>> b = pickle.loads(europe_berlin_pkl_nc)
    >>> a is b
    False
    
  3. ZoneInfo.from_file(fobj, /, key=None): Cuando se construye a partir de un fichero, el objeto ZoneInfo lanza una excepción al ser recogido. Si un usuario final quiere recoger un ZoneInfo construido a partir de un archivo, se recomienda que utilice un tipo de envoltura o una función de serialización personalizada: ya sea serializando por clave o almacenando el contenido del objeto archivo y serializándolo.

Este método de serialización requiere que los datos de la zona horaria para la clave requerida estén disponibles tanto en el lado de serialización como en el de deserialización, de forma similar a como se espera que las referencias a las clases y funciones existan tanto en el entorno de serialización como en el de deserialización. También significa que no se garantiza la consistencia de los resultados cuando se retira un ZoneInfo recogido en un entorno con una versión diferente de los datos de la zona horaria.

Funciones

zoneinfo.available_timezones()

Obtiene un conjunto que contiene todas las claves válidas para las zonas horarias de la IANA disponibles en cualquier lugar de la ruta de zonas horarias. Se recalcula en cada llamada a la función.

Esta función sólo incluye los nombres de zona canónicos y no incluye las zonas «especiales» como las que se encuentran bajo los directorios posix/ y right/, o la zona posixrules.

Prudencia

Esta función puede abrir un gran número de archivos, ya que la mejor manera de determinar si un archivo en la ruta de la zona horaria es una zona horaria válida es leer la «magic string» (cadena mágica) al principio.

Nota

Estos valores no están diseñados para ser expuestos a los usuarios finales; para los elementos de cara al usuario, las aplicaciones deberían utilizar algo como CLDR (el Unicode Common Locale Data Repository) para obtener cadenas más fáciles de usar. Véase también la nota de advertencia sobre ZoneInfo.key.

zoneinfo.reset_tzpath(to=None)

Establece o restablece la ruta de búsqueda de la zona horaria (TZPATH) para el módulo. Cuando se llama sin argumentos, TZPATH se establece en el valor por defecto.

La llamada a reset_tzpath no invalidará la caché de ZoneInfo, por lo que las llamadas al constructor primario de ZoneInfo sólo utilizarán el nuevo TZPATH en caso de que se pierda la caché.

El parámetro to debe ser un sequence de cadenas o os.PathLike y no una cadena, todos los cuales deben ser rutas absolutas. ValueError se lanzará si se pasa algo que no sea una ruta absoluta.

Globales

zoneinfo.TZPATH

Una secuencia de sólo lectura que representa la ruta de búsqueda de zonas horarias – cuando se construye un ZoneInfo a partir de una clave, la clave se une a cada entrada del TZPATH, y se utiliza el primer archivo encontrado.

TZPATH sólo puede contener rutas absolutas, nunca relativas, independientemente de cómo esté configurado.

El objeto al que apunta zoneinfo.TZPATH puede cambiar en respuesta a una llamada a reset_tzpath(), por lo que se recomienda utilizar zoneinfo.TZPATH en lugar de importar TZPATH desde zoneinfo o asignar una variable de larga duración a zoneinfo.TZPATH.

Para más información sobre la configuración de la ruta de búsqueda de zonas horarias, consulte Configurando los orígenes de datos.

Excepciones y advertencias

exception zoneinfo.ZoneInfoNotFoundError

Se lanza cuando la construcción de un objeto ZoneInfo falla porque la clave especificada no puede encontrarse en el sistema. Es una subclase de KeyError.

exception zoneinfo.InvalidTZPathWarning

Se lanza cuando PYTHONTZPATH contiene un componente no válido que será filtrado, como una ruta relativa.