اگر با تاریخ و زمان در پروژه های پایتونی کار می کنید، کتابخانه Pendulum یکی از بهترین انتخاب ها برای ساده کردن مدیریت مناطق زمانی، پارس رشته ها، فرمت دهی و انجام محاسبات دقیق زمانی است. با این ابزار می توانید زمان های آگاه از منطقه زمانی بسازید، تبدیل های مطمئن انجام دهید و از خطاهای رایج مثل تفاوت ساعت تابستانی دوری کنید.

شروع سریع و نصب

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

  1. نصب پکیج با ابزار بسته بندی پایتون
  2. ایجاد زمان اکنون با منطقه زمانی مشخص
  3. نمایش زمان در قالب دلخواه
# 1) نصب
pip install pendulum

# 2) استفاده پایه
import pendulum

now_tehran = pendulum.now('Asia/Tehran')
print(now_tehran.to_datetime_string())   # مثل 2026-07-19 10:35:12

# 3) فرمت دهی خوانا
print(now_tehran.format('YYYY-MM-DD HH:mm ZZ'))  # 2026-07-19 10:35 +0430

کار با مناطق زمانی و تبدیل های مطمئن

یکی از چالش های همیشگی پروژه های بین المللی، هماهنگی زمان بین کاربران مختلف است. با DateTime های آگاه از منطقه زمانی، تبدیل ها بدون از دست رفتن اطلاعات انجام می شود و اختلاف ساعت تابستانی به شکل خودکار مدیریت می گردد.

import pendulum

tehran = pendulum.now('Asia/Tehran')
new_york = tehran.in_timezone('America/New_York')

print(tehran.to_datetime_string())   # زمان تهران
print(new_york.to_datetime_string()) # زمان نیویورک

# ساخت زمان مشخص با منطقه زمانی
deadline_tehran = pendulum.datetime(2026, 8, 1, 9, 0, tz='Asia/Tehran')
deadline_utc = deadline_tehran.in_timezone('UTC')

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

پارس رشته های تاریخ و فرمت دهی خروجی

تاریخ ها در ورودی های متنوعی وارد می شوند. با توابع parse و from_format می توانید رشته ها را با کنترل دقیق بخوانید و با format یا متدهای میانبر آن ها را نمایش دهید.

import pendulum

# پارس آزاد که ISO 8601 را به خوبی می خواند
dt_iso = pendulum.parse('2024-12-31T23:59:00Z')  # آگاه از UTC

# پارس با الگو و منطقه زمانی مشخص
dt_tehran = pendulum.from_format(
    '2024-12-31 23:59',
    'YYYY-MM-DD HH:mm',
    tz='Asia/Tehran',
    strict=True
)

# قالب های کاربردی
print(dt_tehran.to_date_string())       # 2024-12-31
print(dt_tehran.to_time_string())       # 23:59:00
print(dt_tehran.to_datetime_string())   # 2024-12-31 23:59:00
print(dt_tehran.to_iso8601_string())    # 2024-12-31T23:59:00+03:30
print(dt_tehran.format('ddd, DD MMM YYYY HH:mm ZZ'))  # قالب سفارشی

در ورودی های غیر استاندارد، از strict=True استفاده کنید تا سریع تر از خطاها باخبر شوید. این کار جلوی پذیرش داده های ناقص یا مبهم را می گیرد.

مدت زمان ها و دوره ها؛ تفاوت مهم Duration و Period

Duration نشان دهنده طول ثابت زمان است و با واحدهای ثانیه تا روز به شکل یکنواخت کار می کند. Period فاصله بین دو تاریخ را به شکل تقویمی می سنجد و مفاهیمی مثل ماه و سال را با واقعیت تقویمی سازگار نگه می دارد.

import pendulum

dt = pendulum.datetime(2024, 1, 31, tz='UTC')

# اضافه کردن طول زمان ثابت
delta = pendulum.duration(days=2, hours=5)
print((dt + delta).to_datetime_string())  # 2024-02-02 05:00:00

# افزودن یک ماه تقویمی
one_month_later = dt.add(months=1)
print(one_month_later.to_datetime_string())  # 2024-02-29 00:00:00 (سال کبیسه)

# محاسبه اختلاف
start = pendulum.datetime(2024, 1, 1, tz='UTC')
end = pendulum.datetime(2024, 3, 15, tz='UTC')
period = end - start  # همان Period
print(period.in_days())   # تعداد روزها
print(start.diff(end).in_weeks())  # تعداد هفته ها

برای نمایش کاربر پسند اختلاف زمان، از diff_for_humans استفاده کنید. این متد برای اعلان ها و گزارش های پویا بسیار مفید است.

import pendulum
past = pendulum.now('UTC').subtract(hours=3, minutes=20)
print(past.diff_for_humans())                 # 3 hours ago
print(past.diff_for_humans(locale='fr'))      # il y a 3 heures

کارهای روزمره: شروع و پایان بازه ها، روزهای آینده

زمان بندی گزارش ها یا استخراج داده ها اغلب به شروع یا پایان بازه ها نیاز دارد. متدهای start_of و end_of این کار را بسیار سرراست می کنند. علاوه بر آن، next و previous پیدا کردن روزهای خاص هفته را ساده می کنند.

import pendulum

now_utc = pendulum.now('UTC')
start_month = now_utc.start_of('month')
end_month = now_utc.end_of('month')

next_monday_9 = now_utc.next(pendulum.MONDAY).set(hour=9, minute=0, second=0)
prev_friday_end = now_utc.previous(pendulum.FRIDAY).end_of('day')

این الگوها در ساختن صف Task ها، تعیین مهلت ارسال سفارش یا زمان بندی اعلان ها سودمند هستند و کد را خواناتر می کنند.

سناریوهای کاربردی در پروژه های واقعی

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

  • نمایش زمان ثبت سفارش به زبان کاربر و ذخیره همان زمان در دیتابیس به صورت UTC
  • ساخت گزارش های روزانه با start_of و end_of بدون نگرانی درباره تغییرات ساعت تابستانی
  • محاسبه مهلت های تقویمی با add یا subtract بر حسب ماه و سال به شکل صحیح
  • تبدیل فایل های لاگ ISO 8601 با parse و فیلتر کردن آن ها بر اساس بازه زمانی

مدیریت اختلاف ساعت تابستانی و تاریخ های مبهم

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

قانون عملی این است که هر زمان ورودی را یا همراه با منطقه زمانی بگیرید یا به محض ورود، آن ها را به یک منطقه مشخص تبدیل کنید. سپس در لحظه نمایش، آن را به منطقه کاربر برگردانید.

مقایسه کوتاه با datetime استاندارد پایتون

هر دو ابزار قابل اعتماد هستند، اما تمرکز این کتابخانه روی تجربه توسعه دهنده و سادگی کارهای سخت زمانی است.

ویژگی تفاوت کلیدی
آگاه از منطقه زمانی به صورت پیش فرض ساخت و تبدیل زمان ها ساده تر و کم خطاتر است
پارس و فرمت دهی خوانا الگوهای واضح و متدهای میانبر متعدد برای ورودی و خروجی
مدت زمان و دوره تفکیک Duration و Period برای نیازهای ثابت و تقویمی
ابزارهای انسانی سازی diff_for_humans و متدهای کمکی برای اعلان ها

الگوی ذخیره سازی و نمایش پیشنهاد شده

یک الگوی پایدار این است که تمام زمان های تجاری را هنگام ذخیره سازی به UTC ببرید و فقط در لایه نمایش آن را به منطقه زمانی کاربر تبدیل کنید. این روش تست و دیباگ را ساده می کند.

# ذخیره سازی
created_at_user = pendulum.now('Asia/Tehran')
created_at_utc = created_at_user.in_timezone('UTC')
save_to_db(created_at_utc.to_iso8601_string())

# بازیابی و نمایش
raw = load_from_db()  # مثلا ISO 8601 در UTC
dt_utc = pendulum.parse(raw)
print(dt_utc.in_timezone('Asia/Tehran').format('YYYY-MM-DD HH:mm'))

بهترین روش ها و خطاهای رایج

رعایت چند نکته ساده کیفیت کد را بالا می برد و ریسک خطاهای زمانی را کاهش می دهد.

  • از زمان های بدون منطقه زمانی دوری کنید. همیشه tz را مشخص کنید.
  • برای ورودی های مبهم از from_format با strict=True استفاده کنید.
  • ماه و سال را با add و subtract تقویمی جابجا کنید، نه با Duration ثابت.
  • الگوی ذخیره سازی بر پایه UTC و نمایش محلی را رعایت کنید.
  • برای بازه های تقویمی از start_of و end_of استفاده کنید تا مرزها دقیق باشند.
  • به جای محاسبات دستی، از in_timezone برای تبدیل های دقیق بهره ببرید.

چرا این کتابخانه انتخاب مناسبی است

ترکیب سادگی، متدهای شفاف و پوشش نیازهای روزمره باعث می شود کتابخانه Pendulum برای اغلب کاربردهای زمانی در پایتون گزینه ای مطمئن باشد. از کارهای کوچک مثل فرمت دهی تا سناریوهای پیچیده چند منطقه ای، ابزارها و الگوهای لازم در دسترس شما است.

جمع بندی

با به کارگیری زمان های آگاه از منطقه زمانی، پارس دقیق ورودی ها، فرمت دهی خوانا و تفکیک مناسب بین Duration و Period می توانید منطق زمانی پروژه را پایدار و قابل پیش بینی نگه دارید. الگوی ذخیره سازی در UTC و تبدیل در لایه نمایش، در کنار متدهای start_of، end_of و in_timezone، مسیر شما را برای ساخت ویژگی های قابل اتکا هموار می کند. نتیجه آن است که کد کوتاه تر، خطاها کمتر و تجربه توسعه دهنده بهتر می شود.