zoneinfo — Поддержка часовых поясов IANA

Added in version 3.9.

Источник: Lib/zoneinfo


Модуль zoneinfo предоставляет конкретную реализацию часового пояса для поддержки базы данных часовых поясов IANA, как изначально указано в PEP 615. По умолчанию zoneinfo использует системные данные о часовом поясе, если они доступны; если системные данные о часовом поясе недоступны, библиотека переходит к использованию стороннего пакета tzdata, доступного на PyPI.

См.также

Модуль: datetime

Предоставляет типы time и datetime, для работы с которыми предназначен класс ZoneInfo.

Пакет tzdata

Сторонний пакет, поддерживаемый разработчиками ядра CPython для предоставления данных о часовых поясах через PyPI.

Availability: не WASI.

Этот модуль не работает или недоступен на WebAssembly. Дополнительную информацию см. в разделе Платформы WebAssembly.

Используя ZoneInfo

ZoneInfo является конкретной реализацией абстрактного базового класса datetime.tzinfo и предназначен для присоединения к tzinfo, либо через конструктор, либо через метод datetime.replace, либо через 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'

Времена дат, построенные таким образом, совместимы с арифметикой времени дат и справляются с переходом на летнее время без дополнительного вмешательства:

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

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

>>> dt_add.tzname()
'PST'

Эти часовые пояса также поддерживают атрибут fold, введенный в PEP 495. При переходах со смещением, которые вызывают неоднозначное время (например, переход с летнего на стандартное время), используется смещение до перехода, когда fold=0, и смещение после перехода, когда fold=1, например:

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

При конвертации из другого часового пояса сложение будет установлено на правильное значение:

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

Источники данных

Модуль zoneinfo не предоставляет данные о часовом поясе напрямую, а берет информацию о часовом поясе из системной базы данных часовых поясов или из стороннего PyPI-пакета tzdata, если он доступен. Некоторые системы, включая, в частности, Windows, не имеют базы данных IANA, поэтому для проектов, нацеленных на кросс-платформенную совместимость и требующих данных о часовых поясах, рекомендуется объявить зависимость от tzdata. Если ни системные данные, ни tzdata недоступны, все вызовы ZoneInfo будут вызывать ZoneInfoNotFoundError.

Настройка источников данных

При вызове ZoneInfo(key) конструктор сначала ищет в каталогах, указанных в TZPATH, файл, соответствующий key, а в случае неудачи ищет соответствие в пакете tzdata. Это поведение можно настроить тремя способами:

  1. По умолчанию TZPATH, если не указано иное, может быть настроено на compile time.

  2. TZPATH можно настроить с помощью an environment variable.

  3. При значении runtime путь поиска может быть изменен с помощью функции reset_tzpath().

Конфигурация во время компиляции

По умолчанию TZPATH включает в себя несколько общих мест развертывания базы данных часовых поясов (за исключением Windows, где нет «известных» мест для данных часовых поясов). В POSIX-системах распространители и те, кто собирает Python из исходников и знает, где развернуты данные о часовых поясах в их системе, могут изменить путь к часовому поясу по умолчанию, указав опцию компиляции TZPATH (или, что более вероятно, configure flag --with-tzpath), которая должна представлять собой строку, разделенную os.pathsep.

На всех платформах настроенное значение доступно как клавиша TZPATH в sysconfig.get_config_var().

Конфигурация среды

При инициализации TZPATH (либо во время импорта, либо при вызове reset_tzpath() без аргументов) модуль zoneinfo будет использовать переменную окружения PYTHONTZPATH, если она существует, для задания пути поиска.

PYTHONTZPATH

Это разделенная os.pathsep-строка, содержащая путь поиска часового пояса. Он должен состоять только из абсолютных, а не относительных путей. Относительные компоненты, указанные в PYTHONTZPATH, не будут использоваться, но в остальном поведение при указании относительного пути определяется реализацией; CPython будет поднимать InvalidTZPathWarning, но другие реализации могут молча игнорировать ошибочный компонент или поднимать исключение.

Чтобы настроить систему на игнорирование системных данных и использование вместо них пакета tzdata, установите PYTHONTZPATH="".

Конфигурация времени выполнения

Путь поиска TZ также может быть настроен во время выполнения с помощью функции reset_tzpath(). Обычно это нежелательная операция, хотя ее целесообразно использовать в тестовых функциях, которые требуют использования определенного пути поиска часовых поясов (или требуют отключения доступа к системным часовым поясам).

Класс ZoneInfo

class zoneinfo.ZoneInfo(key)

Конкретный подкласс datetime.tzinfo, представляющий часовой пояс IANA, заданный строкой key. Вызовы первичного конструктора всегда будут возвращать объекты, которые сравниваются одинаково; иначе говоря, если кэш не будет аннулирован через ZoneInfo.clear_cache(), для всех значений key следующее утверждение всегда будет истинным:

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

key должен быть в виде относительного, нормализованного POSIX-пути, без ссылок верхнего уровня. Конструктор вызовет ошибку ValueError, если передан несоответствующий ключ.

Если файл, соответствующий key, не найден, конструктор выдает сообщение ZoneInfoNotFoundError.

Класс ZoneInfo имеет два альтернативных конструктора:

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

Конструирует объект ZoneInfo из файлоподобного объекта, возвращающего байты (например, файл, открытый в двоичном режиме, или объект io.BytesIO). В отличие от основного конструктора, этот всегда создает новый объект.

Параметр key задает имя зоны для целей __str__() и __repr__().

Объекты, созданные с помощью этого конструктора, не могут быть замаринованы (см. pickling).

classmethod ZoneInfo.no_cache(key)

Альтернативный конструктор, который обходит кэш конструктора. Он идентичен основному конструктору, но при каждом вызове возвращает новый объект. Скорее всего, он будет полезен для тестирования или демонстрации, но его также можно использовать для создания системы с другой стратегией аннулирования кэша.

Объекты, созданные с помощью этого конструктора, также будут обходить кэш процесса десериализации при распаковке.

Осторожно

Использование этого конструктора может неожиданным образом изменить семантику ваших дат, поэтому используйте его только в том случае, если вы уверены, что это необходимо.

Также доступны следующие методы класса:

classmethod ZoneInfo.clear_cache(*, only_keys=None)

Метод для аннулирования кэша класса ZoneInfo. Если аргументы не переданы, все кэши аннулируются, и при следующем вызове первичного конструктора для каждого ключа будет возвращен новый экземпляр.

Если в параметре only_keys передано итеративное множество имен ключей, то из кэша будут удалены только указанные ключи. Ключи, переданные в only_keys, но не найденные в кэше, игнорируются.

Предупреждение

Вызов этой функции может неожиданным образом изменить семантику времен дат, использующих ZoneInfo; это изменяет состояние модуля и, таким образом, может иметь широкий спектр последствий. Используйте ее только в том случае, если вы знаете, что это необходимо.

Класс имеет один атрибут:

ZoneInfo.key

Это доступное только для чтения значение attribute, которое возвращает переданное конструктору значение key, которое должно быть ключом поиска в базе данных часовых поясов IANA (например, America/New_York, Europe/Paris или Asia/Tokyo).

Для зон, созданных из файла без указания параметра key, это значение будет равно None.

Примечание

Несмотря на то, что предоставление этих значений конечным пользователям является довольно распространенной практикой, они предназначены в качестве первичных ключей для представления соответствующих зон и не обязательно являются элементами, ориентированными на пользователя. Для получения более удобных для пользователя строк из этих ключей можно использовать такие проекты, как CLDR (Unicode Common Locale Data Repository).

Представления строк

Строковое представление, возвращаемое при вызове str на объекте ZoneInfo, по умолчанию использует атрибут ZoneInfo.key (см. примечание об использовании в документации по атрибутам):

>>> 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]'

Для объектов, созданных из файла без указания параметра key, str возвращается к вызову repr(). Значение repr в ZoneInfo определяется реализацией и не обязательно стабильно в разных версиях, но оно гарантированно не является допустимым ключом ZoneInfo.

Сериализация Pickle

Вместо того чтобы сериализовать все данные перехода, объекты ZoneInfo сериализуются по ключу, а объекты ZoneInfo, созданные из файлов (даже те, для которых указано значение key), не могут быть травлеными.

Поведение файла ZoneInfo зависит от того, как он был создан:

  1. ZoneInfo(key): При построении с помощью первичного конструктора объект ZoneInfo сериализуется по ключу, а при десериализации используется первичный, и поэтому ожидается, что это будет тот же объект, что и другие ссылки на тот же часовой пояс. Например, если europe_berlin_pkl - это строка, содержащая pickle, построенный из ZoneInfo("Europe/Berlin"), можно ожидать следующего поведения:

    >>> a = ZoneInfo("Europe/Berlin")
    >>> b = pickle.loads(europe_berlin_pkl)
    >>> a is b
    True
    
  2. ZoneInfo.no_cache(key): При создании из конструктора, обходящего кэш, объект ZoneInfo также сериализуется по ключу, но при десериализации используется конструктор, обходящий кэш. Если europe_berlin_pkl_nc - это строка, содержащая pickle, сконструированный из ZoneInfo.no_cache("Europe/Berlin"), можно ожидать следующего поведения:

    >>> a = ZoneInfo("Europe/Berlin")
    >>> b = pickle.loads(europe_berlin_pkl_nc)
    >>> a is b
    False
    
  3. ZoneInfo.from_file(fobj, /, key=None): При создании из файла объект ZoneInfo вызывает исключение при мариновании. Если конечный пользователь хочет замариновать ZoneInfo, созданный из файла, рекомендуется использовать тип-обертку или пользовательскую функцию сериализации: либо сериализацию по ключу, либо хранение содержимого объекта файла и его сериализацию.

Этот метод сериализации требует, чтобы данные о часовом поясе для требуемого ключа были доступны как на стороне сериализации, так и на стороне десериализации, подобно тому, как ссылки на классы и функции должны существовать как в среде сериализации, так и в среде десериализации. Это также означает, что при распаковке ZoneInfo, замаринованного в среде с другой версией данных о часовом поясе, не дается никаких гарантий согласованности результатов.

Функции

zoneinfo.available_timezones()

Получает набор, содержащий все действительные ключи для часовых поясов IANA, доступные в любой точке пути часовых поясов. Этот набор пересчитывается при каждом вызове функции.

Эта функция включает только канонические имена зон и не включает «специальные» зоны, такие как зоны в каталогах posix/ и right/ или зона posixrules.

Осторожно

Эта функция может открыть большое количество файлов, так как лучший способ определить, является ли файл на пути к временной зоне действительной временной зоной, - это прочитать «магическую строку» в начале.

Примечание

Эти значения не предназначены для конечных пользователей; для элементов, с которыми сталкиваются пользователи, приложения должны использовать что-то вроде CLDR (репозиторий данных общей локали Юникода), чтобы получить более удобные для пользователя строки. См. также предостережение по поводу ZoneInfo.key.

zoneinfo.reset_tzpath(to=None)

Устанавливает или сбрасывает путь поиска часового пояса (TZPATH) для модуля. При вызове без аргументов значение TZPATH устанавливается по умолчанию.

Вызов reset_tzpath не аннулирует кэш ZoneInfo, и поэтому вызовы основного конструктора ZoneInfo будут использовать новый TZPATH только в случае пропусков кэша.

Параметр to должен быть sequence из строк или os.PathLike, но не строкой, и все они должны быть абсолютными путями. Если передан путь, отличный от абсолютного, будет выдано сообщение ValueError.

Globals

zoneinfo.TZPATH

Последовательность, доступная только для чтения, представляющая путь поиска временной зоны - при создании ZoneInfo из ключа, ключ присоединяется к каждой записи в TZPATH, и используется первый найденный файл.

TZPATH может содержать только абсолютные пути и никогда относительные, независимо от того, как он настроен.

Объект, на который указывает zoneinfo.TZPATH, может измениться в ответ на вызов reset_tzpath(), поэтому рекомендуется использовать zoneinfo.TZPATH, а не импортировать TZPATH из zoneinfo или присваивать zoneinfo.TZPATH долгоживущую переменную.

Дополнительные сведения о настройке пути поиска часового пояса см. в разделе Настройка источников данных.

Исключения и предупреждения

exception zoneinfo.ZoneInfoNotFoundError

Возникает при неудачном построении объекта ZoneInfo, так как указанный ключ не был найден в системе. Это подкласс KeyError.

exception zoneinfo.InvalidTZPathWarning

Возникает, если PYTHONTZPATH содержит недопустимый компонент, который будет отфильтрован, например, относительный путь.