# `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

La ruta por defecto `TZPATH` incluye varias ubicaciones comunes de despliegue para la base de datos de zonas horarias (excepto en Windows, donde no hay ubicaciones «conocidas» para los datos de zonas horarias). En los sistemas POSIX, los distribuidores posteriores y aquellos que construyen Python desde el código fuente que saben dónde se despliegan los datos de zona horaria de su sistema pueden cambiar la ruta de zona horaria por defecto especificando la opción de compilación `TZPATH` (o, más probablemente, la bandera `configure` `--with-tzpath`), que debe ser una cadena delimitada por `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.