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

Добавлено в версии 3.9.


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

См.также

Модуль: datetime

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

Пакет tzdata

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

Использование 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 (репозиторий данных общей локали Юникода).

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

Строковое представление, возвращаемое при вызове 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(). Ключ ZoneInfo от repr определяется реализацией и не обязательно стабилен между версиями, но гарантируется, что он не является допустимым ключом 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 (Unicode Common Locale Data Repository) для получения более удобных для пользователя строк. См. также предостережение по поводу 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 содержит недопустимый компонент, который будет отфильтрован, например, относительный путь.

Вернуться на верх