1:mod:`zoneinfo` --- IANA time zone support 2========================================== 3 4.. module:: zoneinfo 5 :synopsis: IANA time zone support 6 7.. versionadded:: 3.9 8 9.. moduleauthor:: Paul Ganssle <paul@ganssle.io> 10.. sectionauthor:: Paul Ganssle <paul@ganssle.io> 11 12-------------- 13 14The :mod:`zoneinfo` module provides a concrete time zone implementation to 15support the IANA time zone database as originally specified in :pep:`615`. By 16default, :mod:`zoneinfo` uses the system's time zone data if available; if no 17system time zone data is available, the library will fall back to using the 18first-party `tzdata`_ package available on PyPI. 19 20.. seealso:: 21 22 Module: :mod:`datetime` 23 Provides the :class:`~datetime.time` and :class:`~datetime.datetime` 24 types with which the :class:`ZoneInfo` class is designed to be used. 25 26 Package `tzdata`_ 27 First-party package maintained by the CPython core developers to supply 28 time zone data via PyPI. 29 30 31Using ``ZoneInfo`` 32------------------ 33 34:class:`ZoneInfo` is a concrete implementation of the :class:`datetime.tzinfo` 35abstract base class, and is intended to be attached to ``tzinfo``, either via 36the constructor, the :meth:`datetime.replace <datetime.datetime.replace>` 37method or :meth:`datetime.astimezone <datetime.datetime.astimezone>`:: 38 39 >>> from zoneinfo import ZoneInfo 40 >>> from datetime import datetime, timedelta 41 42 >>> dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("America/Los_Angeles")) 43 >>> print(dt) 44 2020-10-31 12:00:00-07:00 45 46 >>> dt.tzname() 47 'PDT' 48 49Datetimes constructed in this way are compatible with datetime arithmetic and 50handle daylight saving time transitions with no further intervention:: 51 52 >>> dt_add = dt + timedelta(days=1) 53 54 >>> print(dt_add) 55 2020-11-01 12:00:00-08:00 56 57 >>> dt_add.tzname() 58 'PST' 59 60These time zones also support the :attr:`~datetime.datetime.fold` attribute 61introduced in :pep:`495`. During offset transitions which induce ambiguous 62times (such as a daylight saving time to standard time transition), the offset 63from *before* the transition is used when ``fold=0``, and the offset *after* 64the transition is used when ``fold=1``, for example:: 65 66 >>> dt = datetime(2020, 11, 1, 1, tzinfo=ZoneInfo("America/Los_Angeles")) 67 >>> print(dt) 68 2020-11-01 01:00:00-07:00 69 70 >>> print(dt.replace(fold=1)) 71 2020-11-01 01:00:00-08:00 72 73When converting from another time zone, the fold will be set to the correct 74value:: 75 76 >>> from datetime import timezone 77 >>> LOS_ANGELES = ZoneInfo("America/Los_Angeles") 78 >>> dt_utc = datetime(2020, 11, 1, 8, tzinfo=timezone.utc) 79 80 >>> # Before the PDT -> PST transition 81 >>> print(dt_utc.astimezone(LOS_ANGELES)) 82 2020-11-01 01:00:00-07:00 83 84 >>> # After the PDT -> PST transition 85 >>> print((dt_utc + timedelta(hours=1)).astimezone(LOS_ANGELES)) 86 2020-11-01 01:00:00-08:00 87 88Data sources 89------------ 90 91The ``zoneinfo`` module does not directly provide time zone data, and instead 92pulls time zone information from the system time zone database or the 93first-party PyPI package `tzdata`_, if available. Some systems, including 94notably Windows systems, do not have an IANA database available, and so for 95projects targeting cross-platform compatibility that require time zone data, it 96is recommended to declare a dependency on tzdata. If neither system data nor 97tzdata are available, all calls to :class:`ZoneInfo` will raise 98:exc:`ZoneInfoNotFoundError`. 99 100.. _zoneinfo_data_configuration: 101 102Configuring the data sources 103**************************** 104 105When ``ZoneInfo(key)`` is called, the constructor first searches the 106directories specified in :data:`TZPATH` for a file matching ``key``, and on 107failure looks for a match in the tzdata package. This behavior can be 108configured in three ways: 109 1101. The default :data:`TZPATH` when not otherwise specified can be configured at 111 :ref:`compile time <zoneinfo_data_compile_time_config>`. 1122. :data:`TZPATH` can be configured using :ref:`an environment variable 113 <zoneinfo_data_environment_var>`. 1143. At :ref:`runtime <zoneinfo_data_runtime_config>`, the search path can be 115 manipulated using the :func:`reset_tzpath` function. 116 117.. _zoneinfo_data_compile_time_config: 118 119Compile-time configuration 120^^^^^^^^^^^^^^^^^^^^^^^^^^ 121 122The default :data:`TZPATH` includes several common deployment locations for the 123time zone database (except on Windows, where there are no "well-known" 124locations for time zone data). On POSIX systems, downstream distributors and 125those building Python from source who know where their system 126time zone data is deployed may change the default time zone path by specifying 127the compile-time option ``TZPATH`` (or, more likely, the :option:`configure 128flag --with-tzpath <--with-tzpath>`), which should be a string delimited by 129:data:`os.pathsep`. 130 131On all platforms, the configured value is available as the ``TZPATH`` key in 132:func:`sysconfig.get_config_var`. 133 134.. _zoneinfo_data_environment_var: 135 136Environment configuration 137^^^^^^^^^^^^^^^^^^^^^^^^^ 138 139When initializing :data:`TZPATH` (either at import time or whenever 140:func:`reset_tzpath` is called with no arguments), the ``zoneinfo`` module will 141use the environment variable ``PYTHONTZPATH``, if it exists, to set the search 142path. 143 144.. envvar:: PYTHONTZPATH 145 146 This is an :data:`os.pathsep`-separated string containing the time zone 147 search path to use. It must consist of only absolute rather than relative 148 paths. Relative components specified in ``PYTHONTZPATH`` will not be used, 149 but otherwise the behavior when a relative path is specified is 150 implementation-defined; CPython will raise :exc:`InvalidTZPathWarning`, but 151 other implementations are free to silently ignore the erroneous component 152 or raise an exception. 153 154To set the system to ignore the system data and use the tzdata package 155instead, set ``PYTHONTZPATH=""``. 156 157.. _zoneinfo_data_runtime_config: 158 159Runtime configuration 160^^^^^^^^^^^^^^^^^^^^^ 161 162The TZ search path can also be configured at runtime using the 163:func:`reset_tzpath` function. This is generally not an advisable operation, 164though it is reasonable to use it in test functions that require the use of a 165specific time zone path (or require disabling access to the system time zones). 166 167 168The ``ZoneInfo`` class 169---------------------- 170 171.. class:: ZoneInfo(key) 172 173 A concrete :class:`datetime.tzinfo` subclass that represents an IANA time 174 zone specified by the string ``key``. Calls to the primary constructor will 175 always return objects that compare identically; put another way, barring 176 cache invalidation via :meth:`ZoneInfo.clear_cache`, for all values of 177 ``key``, the following assertion will always be true: 178 179 .. code-block:: python 180 181 a = ZoneInfo(key) 182 b = ZoneInfo(key) 183 assert a is b 184 185 ``key`` must be in the form of a relative, normalized POSIX path, with no 186 up-level references. The constructor will raise :exc:`ValueError` if a 187 non-conforming key is passed. 188 189 If no file matching ``key`` is found, the constructor will raise 190 :exc:`ZoneInfoNotFoundError`. 191 192 193The ``ZoneInfo`` class has two alternate constructors: 194 195.. classmethod:: ZoneInfo.from_file(fobj, /, key=None) 196 197 Constructs a ``ZoneInfo`` object from a file-like object returning bytes 198 (e.g. a file opened in binary mode or an :class:`io.BytesIO` object). 199 Unlike the primary constructor, this always constructs a new object. 200 201 The ``key`` parameter sets the name of the zone for the purposes of 202 :py:meth:`~object.__str__` and :py:meth:`~object.__repr__`. 203 204 Objects created via this constructor cannot be pickled (see `pickling`_). 205 206.. classmethod:: ZoneInfo.no_cache(key) 207 208 An alternate constructor that bypasses the constructor's cache. It is 209 identical to the primary constructor, but returns a new object on each 210 call. This is most likely to be useful for testing or demonstration 211 purposes, but it can also be used to create a system with a different cache 212 invalidation strategy. 213 214 Objects created via this constructor will also bypass the cache of a 215 deserializing process when unpickled. 216 217 .. TODO: Add "See `cache_behavior`_" reference when that section is ready. 218 219 .. caution:: 220 221 Using this constructor may change the semantics of your datetimes in 222 surprising ways, only use it if you know that you need to. 223 224The following class methods are also available: 225 226.. classmethod:: ZoneInfo.clear_cache(*, only_keys=None) 227 228 A method for invalidating the cache on the ``ZoneInfo`` class. If no 229 arguments are passed, all caches are invalidated and the next call to 230 the primary constructor for each key will return a new instance. 231 232 If an iterable of key names is passed to the ``only_keys`` parameter, only 233 the specified keys will be removed from the cache. Keys passed to 234 ``only_keys`` but not found in the cache are ignored. 235 236 .. TODO: Add "See `cache_behavior`_" reference when that section is ready. 237 238 .. warning:: 239 240 Invoking this function may change the semantics of datetimes using 241 ``ZoneInfo`` in surprising ways; this modifies process-wide global state 242 and thus may have wide-ranging effects. Only use it if you know that you 243 need to. 244 245The class has one attribute: 246 247.. attribute:: ZoneInfo.key 248 249 This is a read-only :term:`attribute` that returns the value of ``key`` 250 passed to the constructor, which should be a lookup key in the IANA time 251 zone database (e.g. ``America/New_York``, ``Europe/Paris`` or 252 ``Asia/Tokyo``). 253 254 For zones constructed from file without specifying a ``key`` parameter, 255 this will be set to ``None``. 256 257 .. note:: 258 259 Although it is a somewhat common practice to expose these to end users, 260 these values are designed to be primary keys for representing the 261 relevant zones and not necessarily user-facing elements. Projects like 262 CLDR (the Unicode Common Locale Data Repository) can be used to get 263 more user-friendly strings from these keys. 264 265String representations 266********************** 267 268The string representation returned when calling :py:class:`str` on a 269:class:`ZoneInfo` object defaults to using the :attr:`ZoneInfo.key` attribute (see 270the note on usage in the attribute documentation):: 271 272 >>> zone = ZoneInfo("Pacific/Kwajalein") 273 >>> str(zone) 274 'Pacific/Kwajalein' 275 276 >>> dt = datetime(2020, 4, 1, 3, 15, tzinfo=zone) 277 >>> f"{dt.isoformat()} [{dt.tzinfo}]" 278 '2020-04-01T03:15:00+12:00 [Pacific/Kwajalein]' 279 280For objects constructed from a file without specifying a ``key`` parameter, 281``str`` falls back to calling :func:`repr`. ``ZoneInfo``'s ``repr`` is 282implementation-defined and not necessarily stable between versions, but it is 283guaranteed not to be a valid ``ZoneInfo`` key. 284 285.. _pickling: 286 287Pickle serialization 288******************** 289 290Rather than serializing all transition data, ``ZoneInfo`` objects are 291serialized by key, and ``ZoneInfo`` objects constructed from files (even those 292with a value for ``key`` specified) cannot be pickled. 293 294The behavior of a ``ZoneInfo`` file depends on how it was constructed: 295 2961. ``ZoneInfo(key)``: When constructed with the primary constructor, a 297 ``ZoneInfo`` object is serialized by key, and when deserialized, the 298 deserializing process uses the primary and thus it is expected that these 299 are expected to be the same object as other references to the same time 300 zone. For example, if ``europe_berlin_pkl`` is a string containing a pickle 301 constructed from ``ZoneInfo("Europe/Berlin")``, one would expect the 302 following behavior: 303 304 .. code-block:: pycon 305 306 >>> a = ZoneInfo("Europe/Berlin") 307 >>> b = pickle.loads(europe_berlin_pkl) 308 >>> a is b 309 True 310 3112. ``ZoneInfo.no_cache(key)``: When constructed from the cache-bypassing 312 constructor, the ``ZoneInfo`` object is also serialized by key, but when 313 deserialized, the deserializing process uses the cache bypassing 314 constructor. If ``europe_berlin_pkl_nc`` is a string containing a pickle 315 constructed from ``ZoneInfo.no_cache("Europe/Berlin")``, one would expect 316 the following behavior: 317 318 .. code-block:: pycon 319 320 >>> a = ZoneInfo("Europe/Berlin") 321 >>> b = pickle.loads(europe_berlin_pkl_nc) 322 >>> a is b 323 False 324 3253. ``ZoneInfo.from_file(fobj, /, key=None)``: When constructed from a file, the 326 ``ZoneInfo`` object raises an exception on pickling. If an end user wants to 327 pickle a ``ZoneInfo`` constructed from a file, it is recommended that they 328 use a wrapper type or a custom serialization function: either serializing by 329 key or storing the contents of the file object and serializing that. 330 331This method of serialization requires that the time zone data for the required 332key be available on both the serializing and deserializing side, similar to the 333way that references to classes and functions are expected to exist in both the 334serializing and deserializing environments. It also means that no guarantees 335are made about the consistency of results when unpickling a ``ZoneInfo`` 336pickled in an environment with a different version of the time zone data. 337 338Functions 339--------- 340 341.. function:: available_timezones() 342 343 Get a set containing all the valid keys for IANA time zones available 344 anywhere on the time zone path. This is recalculated on every call to the 345 function. 346 347 This function only includes canonical zone names and does not include 348 "special" zones such as those under the ``posix/`` and ``right/`` 349 directories, or the ``posixrules`` zone. 350 351 .. caution:: 352 353 This function may open a large number of files, as the best way to 354 determine if a file on the time zone path is a valid time zone is to 355 read the "magic string" at the beginning. 356 357 .. note:: 358 359 These values are not designed to be exposed to end-users; for user 360 facing elements, applications should use something like CLDR (the 361 Unicode Common Locale Data Repository) to get more user-friendly 362 strings. See also the cautionary note on :attr:`ZoneInfo.key`. 363 364.. function:: reset_tzpath(to=None) 365 366 Sets or resets the time zone search path (:data:`TZPATH`) for the module. 367 When called with no arguments, :data:`TZPATH` is set to the default value. 368 369 Calling ``reset_tzpath`` will not invalidate the :class:`ZoneInfo` cache, 370 and so calls to the primary ``ZoneInfo`` constructor will only use the new 371 ``TZPATH`` in the case of a cache miss. 372 373 The ``to`` parameter must be a :term:`sequence` of strings or 374 :class:`os.PathLike` and not a string, all of which must be absolute paths. 375 :exc:`ValueError` will be raised if something other than an absolute path 376 is passed. 377 378Globals 379------- 380 381.. data:: TZPATH 382 383 A read-only sequence representing the time zone search path -- when 384 constructing a ``ZoneInfo`` from a key, the key is joined to each entry in 385 the ``TZPATH``, and the first file found is used. 386 387 ``TZPATH`` may contain only absolute paths, never relative paths, 388 regardless of how it is configured. 389 390 The object that ``zoneinfo.TZPATH`` points to may change in response to a 391 call to :func:`reset_tzpath`, so it is recommended to use 392 ``zoneinfo.TZPATH`` rather than importing ``TZPATH`` from ``zoneinfo`` or 393 assigning a long-lived variable to ``zoneinfo.TZPATH``. 394 395 For more information on configuring the time zone search path, see 396 :ref:`zoneinfo_data_configuration`. 397 398Exceptions and warnings 399----------------------- 400 401.. exception:: ZoneInfoNotFoundError 402 403 Raised when construction of a :class:`ZoneInfo` object fails because the 404 specified key could not be found on the system. This is a subclass of 405 :exc:`KeyError`. 406 407.. exception:: InvalidTZPathWarning 408 409 Raised when :envvar:`PYTHONTZPATH` contains an invalid component that will 410 be filtered out, such as a relative path. 411 412.. Links and references: 413 414.. _tzdata: https://pypi.org/project/tzdata/ 415