zoneinfo --- پشتیبانی از منطقه‌های زمانی IANA

اضافه شده در نسخه‌ی 3.9.

کد منبع: Lib/zoneinfo


ماژول zoneinfo یک پیاده‌سازی عینی منطقه زمانی را برای پشتیبانی از پایگاه داده‌ی منطقه زمانی IANA، همان‌گونه که در ابتدا در PEP 615 مشخص شده است، فراهم می‌کند. به‌طور پیش‌فرض، zoneinfo در صورت در دسترس بودن، از داده‌های منطقه زمانی سیستم استفاده می‌کند؛ اگر داده‌های منطقه زمانی سیستم در دسترس نباشد، کتابخانه به‌عنوان جایگزین از بسته‌ی شخص اول tzdata موجود در PyPI استفاده خواهد کرد.

همچنین ملاحظه نمائید

ماژول: datetime

انواع time و datetime را فراهم می‌کند که کلاس ZoneInfo برای استفاده با آن‌ها طراحی شده است.

بسته tzdata

بسته‌ی شخص اول که توسط توسعه‌دهندگان اصلی CPython نگهداری می‌شود تا داده‌های منطقه‌ی زمانی را از طریق PyPI فراهم کند.

دسترس‌پذیری: not WASI.

این ماژول روی WebAssembly کار نمی‌کند یا در دسترس نیست. برای اطلاعات بیشتر، سکوهای WebAssembly را ببینید.

استفاده از ZoneInfo

ZoneInfo یک پیاده‌سازی مشخص از کلاس پایه انتزاعی datetime.tzinfo است و برای اتصال به tzinfo در نظر گرفته شده است، چه از طریق سازنده، چه از طریق متد datetime.replace یا datetime.astimezone:

>>> from zoneinfo import ZoneInfo
>>> import datetime as dt

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

>>> when.tzname()
'PDT'

اشیای datetime ساخته‌شده به این روش، با محاسبات datetime سازگار هستند و تغییرهای ساعت تابستانی را بدون هیچ‌گونه مداخله‌ی بیشتر مدیریت می‌کنند:

>>> when_add = when + dt.timedelta(days=1)

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

>>> when_add.tzname()
'PST'

این مناطق زمانی همچنین از ویژگی fold معرفی‌شده در PEP 495 پشتیبانی می‌کنند. در طول انتقال‌های آفست که موجب ایجاد زمان‌های مبهم می‌شوند (مانند انتقال از ساعت تابستانی به ساعت استاندارد)، هنگامی که fold=0 باشد از آفست پیش از انتقال استفاده می‌شود، و هنگامی که fold=1 باشد از آفست پس از انتقال استفاده می‌شود؛ برای مثال:

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

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

هنگام تبدیل از یک منطقه زمانی دیگر، fold به مقدار صحیح تنظیم خواهد شد:

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

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

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

منابع داده

ماژول zoneinfo داده‌های منطقه زمانی را مستقیماً ارائه نمی‌دهد و در عوض، در صورت دسترسی‌پذیری، اطلاعات منطقه زمانی را از پایگاه داده‌ی منطقه زمانی سیستم یا بسته‌ی شخص اول PyPI یعنی tzdata دریافت می‌کند. برخی سیستم‌ها، از جمله به‌ویژه سیستم‌های ویندوزی، پایگاه داده‌ی IANA را در دسترس ندارند، بنابراین برای پروژه‌هایی که سازگاری بین‌سکویی را هدف قرار می‌دهند و به داده‌های منطقه زمانی نیاز دارند، توصیه می‌شود وابستگی به tzdata را اعلام کنید. اگر هیچ‌کدام از داده‌های سیستمی و tzdata در دسترس نباشند، همه فراخوانی‌های ZoneInfo استثنای ZoneInfoNotFoundError را پرتاب می‌کنند.

پیکربندی منابع داده

هنگامی که ZoneInfo(key) فراخوانی می‌شود، سازنده ابتدا در پوشه‌های مشخص‌شده در TZPATH به دنبال پرونده‌ای می‌گردد که با key مطابقت داشته باشد، و در صورت شکست، به دنبال موردی منطبق در بسته‌ی tzdata می‌گردد. این رفتار را می‌توان به سه روش پیکربندی کرد:

  1. در صورتی که به‌طور دیگری مشخص نشده باشد، مقدار پیش‌فرض TZPATH را می‌توان در زمان کامپایل پیکربندی کرد.

  2. TZPATH را می‌توان با استفاده از یک متغیر محیطی پیکربندی کرد.

  3. در ران‌تایم، می‌توان مسیر جستجو را با استفاده از تابع reset_tzpath() تغییر داد.

پیکربندی زمان کامپایل

TZPATH پیش‌فرض شامل چندین محل استقرار رایج برای پایگاه داده‌ی منطقه‌ی زمانی است (به‌جز در ویندوز، که هیچ محل «شناخته‌شده»ای برای داده‌های منطقه‌ی زمانی وجود ندارد). در سیستم‌های POSIX، توزیع‌کنندگان پایین‌دستی و کسانی که پایتون را از سورس می‌سازند و می‌دانند داده‌های منطقه‌ی زمانی سیستمشان کجا مستقر شده است، می‌توانند مسیر منطقه‌ی زمانی پیش‌فرض را با مشخص کردن گزینه‌ی زمان کامپایل 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(file_obj, /, key=None)

یک شیء ZoneInfo را از یک شیء شبه‌پرونده که بایت برمی‌گرداند می‌سازد (مثلاً پرونده‌ای که در حالت دودویی باز شده است یا یک شیء io.BytesIO). برخلاف سازنده‌ی اصلی، این همیشه یک شیء جدید می‌سازد.

پارامتر key نام منطقه را برای اهداف __str__() و __repr__() تنظیم می‌کند.

اشیای ایجادشده از طریق این سازنده را نمی‌توان پیکل کرد (به pickling مراجعه کنید).

اگر داده‌ی خوانده‌شده از file_obj یک پرونده TZif معتبر نباشد، استثنای ValueError پرتاب می‌شود.

classmethod ZoneInfo.no_cache(key)

سازنده جایگزینی که نهانگاه سازنده را دور می‌زند. این سازنده با سازنده اصلی یکسان است، اما در هر فراخوانی یک شیء جدید برمی‌گرداند. این به احتمال زیاد برای آزمون یا اهداف نمایشی مفید است، اما می‌توان از آن برای ایجاد سیستمی با راهبرد متفاوت برای ابطال نهانگاه نیز استفاده کرد.

اشیایی که از طریق این سازنده ایجاد می‌شوند، هنگام بازگردانی از pickle نیز نهانگاه یک فرایند سریال‌زدایی را دور می‌زنند.

ملاحظه

استفاده از این سازنده ممکن است معنای datetimeهای شما را به‌شکل‌های غافلگیرکننده‌ای تغییر دهد؛ فقط در صورتی از آن استفاده کنید که می‌دانید به آن نیاز دارید.

متدهای کلاس زیر نیز در دسترس هستند:

classmethod ZoneInfo.clear_cache(*, only_keys=None)

متدی برای نامعتبر کردن نهانگاه در کلاس ZoneInfo. اگر هیچ آرگومانی ارسال نشود، همه نهانگاه‌ها نامعتبر می‌شوند و فراخوانی بعدی سازنده اصلی برای هر کلید، یک نمونه جدید را برمی‌گرداند.

اگر یک پیمایش‌پذیر از نام‌های کلید به پارامتر only_keys ارسال شود، فقط کلیدهای مشخص‌شده از نهانگاه حذف می‌شوند. کلیدهایی که به only_keys ارسال شده‌اند اما در نهانگاه یافت نمی‌شوند، نادیده گرفته می‌شوند.

هشدار

فراخوانی این تابع ممکن است معناشناسی datetimeهایی که از ZoneInfo استفاده می‌کنند را به‌شکل‌های غیرمنتظره‌ای تغییر دهد؛ این کار وضعیت ماژول را تغییر می‌دهد و بنابراین ممکن است اثرات گسترده‌ای داشته باشد. تنها در صورتی از آن استفاده کنید که می‌دانید به آن نیاز دارید.

این کلاس یک ویژگی دارد:

ZoneInfo.key

این یک ویژگی فقط‌خواندنی است که مقدار 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'

>>> when = dt.datetime(2020, 4, 1, 3, 15, tzinfo=zone)
>>> f"{when.isoformat()} [{when.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 رشته‌ای حاوی یک پیکل ساخته‌شده از 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(file_obj, /, key=None): هنگامی که از یک پرونده ساخته شود، شیء ZoneInfo در هنگام پیکل‌کردن یک استثنا پرتاب می‌کند. اگر کاربر نهایی بخواهد یک ZoneInfo ساخته‌شده از یک پرونده را پیکل کند، توصیه می‌شود که از یک نوع پوششی یا یک تابع سریال‌سازی سفارشی استفاده کند: یا با سریال‌سازی بر اساس کلید یا با ذخیره‌ی محتوای شیء پرونده و سریال‌سازی آن.

این روش از سریال‌سازی نیاز دارد که داده‌های منطقه‌ی زمانی برای کلید مورد نیاز در هر دو طرف سریال‌سازی و سریال‌زدایی در دسترس باشند، مشابه روشی که انتظار می‌رود ارجاع‌ها به کلاس‌ها و توابع در هر دو محیط سریال‌سازی و سریال‌زدایی وجود داشته باشند. این همچنین به این معناست که هیچ تضمینی درباره‌ی سازگاری نتایج هنگام پیکل‌گشایی یک ZoneInfo که در محیطی با نسخه‌ای متفاوت از داده‌های منطقه‌ی زمانی پیکل‌شده است، داده نمی‌شود.

توابع

zoneinfo.available_timezones()

مجموعه‌ای شامل تمام کلیدهای معتبر برای مناطق زمانی IANA موجود در هر نقطه از مسیر مناطق زمانی دریافت کنید. این مجموعه در هر فراخوانی تابع دوباره محاسبه می‌شود.

این تابع فقط شامل نام‌های کانونیکال منطقه می‌شود و مناطق «ویژه» را شامل نمی‌شود، مانند آن‌هایی که در پوشه‌های posix/ و right/ قرار دارند، یا منطقه posixrules.

ملاحظه

این تابع ممکن است تعداد زیادی پرونده را باز کند، زیرا بهترین راه برای تشخیص اینکه آیا یک پرونده در مسیر منطقه زمانی، یک منطقه زمانی معتبر است، خواندن «رشته جادویی» (magic string) در ابتدای آن است.

توجه

این مقادیر برای ارائه به کاربران نهایی طراحی نشده‌اند؛ برای عناصر رو به کاربر، برنامه‌ها باید برای دریافت رشته‌های کاربرپسندتر از چیزی مانند CLDR (مخزن مشترک داده‌های locale یونیکد) استفاده کنند. همچنین یادداشت هشداردهنده درباره‌ی ZoneInfo.key را ببینید.

zoneinfo.reset_tzpath(to=None)

مسیر جستجوی منطقه‌ی زمانی (TZPATH) را برای ماژول تنظیم یا بازنشانی می‌کند. وقتی بدون آرگومان فراخوانی شود، TZPATH به مقدار پیش‌فرض تنظیم می‌شود.

فراخوانی reset_tzpath نهانگاه ZoneInfo را بی‌اعتبار نمی‌کند، بنابراین فراخوانی‌های سازنده اصلی ZoneInfo تنها در صورتی از TZPATH جدید استفاده خواهند کرد که مورد درخواستی در نهانگاه یافت نشود.

پارامتر to باید یک دنباله از رشته‌ها یا os.PathLike باشد، نه یک رشته، و همه‌ی آن‌ها باید مسیرهای مطلق باشند. اگر چیزی غیر از مسیر مطلق ارسال شود، ValueError پرتاب خواهد شد.

سراسری‌ها

zoneinfo.TZPATH

یک دنباله فقط خواندنی که نشان‌دهنده‌ی مسیر جستجوی منطقه زمانی است -- هنگام ساخت یک ZoneInfo از یک کلید، کلید به هر ورودی در TZPATH پیوست می‌شود، و اولین پرونده یافت‌شده استفاده می‌شود.

TZPATH می‌تواند فقط شامل مسیرهای مطلق باشد و هرگز شامل مسیرهای نسبی نمی‌شود، صرف‌نظر از این‌که چگونه پیکربندی شده باشد.

شیءای که zoneinfo.TZPATH به آن اشاره می‌کند ممکن است در پاسخ به فراخوانی reset_tzpath() تغییر کند، بنابراین توصیه می‌شود به‌جای ایمپورت کردن TZPATH از zoneinfo یا انتساب یک متغیر با طول عمر زیاد به zoneinfo.TZPATH، از zoneinfo.TZPATH استفاده کنید.

برای اطلاعات بیشتر درباره‌ی پیکربندی مسیر جستجوی منطقه زمانی، پیکربندی منابع داده را ببینید.

استثناها و هشدارها

exception zoneinfo.ZoneInfoNotFoundError

زمانی پرتاب می‌شود که ساخت یک شیء ZoneInfo شکست بخورد، زیرا کلید مشخص‌شده در سیستم یافت نشد. این یک زیرکلاس از KeyError است.

exception zoneinfo.InvalidTZPathWarning

هنگامی که PYTHONTZPATH شامل یک کامپوننت نامعتبر باشد که حذف خواهد شد، مانند یک مسیر نسبی، پرتاب می‌شود.