مدیریت تاریخ و زمان از چالشهای رایج برنامهنویسی است. ثبت دقیق زمان تراکنشها در برنامههای مالی، لاگگیری رویدادها و بررسی دورههای زمانی مشخص برای تغییر کلمه عبور کاربران در وباپلیکیشنها به مدیریت تاریخ و زمان نیاز دارند. پایتون این نیاز را با ماژول توکار datetime برطرف میکند.
آشنایی با کتابخانه datetime در پایتون از مباحث کاربردی مسیر آموزش پایتون برای ساخت برنامههای واقعی است. این ماژول کلاسها و متدهای متنوعی دارد که برنامهنویسان با آنها اشیاء زمانی میسازند، اجزای تاریخ را استخراج و رشتهها را قالببندی میکنند. انجام محاسبات ریاضی روی زمان و مدیریت مناطق زمانی نیز از امکانات آن است.
نحوه فراخوانی و کلاسهای اصلی ماژول datetime در پایتون
پیش از نوشتن کد برای کار با تاریخ و زمان در پایتون، باید ساختار داخلی ماژول datetime و روش درست فراخوانی آن را بشناسید تا هنگام نمونهسازی از کلاسها با خطا یا ابهام روبهرو نشوید.
ایمپورت کردن ماژول و کلاسها بدون سردرگمی
ماژول datetime بخشی از کتابخانه استاندارد پایتون است.
هنگام استفاده از دستور import در پایتون برای این کتابخانه، همنام بودن ماژول (datetime) با یکی از کلاسهای اصلی آن (datetime) گاهی ابهام ایجاد میکند. اگر ماژول را بهصورت معمولی ایمپورت کنید، ناچارید عبارتی تکرارشونده مانند datetime.datetime.now() بنویسید.
در مثالهای مستندات رسمی پایتون، برای جلوگیری از اشتباه گرفتن نام ماژول و کلاس، از کلمه کلیدی as استفاده شده و نام ماژول به dt تغییر یافته است. میتوانید فقط کلاسهای مورد نیاز خود را هم مستقیماً ایمپورت کنید:
# روش اول: ایمپورت کل ماژول با نام مستعار (پیشنهاد مستندات پایتون)
import datetime as dt
current_time = dt.datetime.now()
# روش دوم: ایمپورت مستقیم کلاسهای مورد نیاز از درون ماژول
from datetime import date, time, datetime, timedelta
کلاسهای درون کتابخانه datetime
این ماژول ثابتهای کاربردی زیر را دارد:

- MINYEAR: کوچکترین عدد مجاز برای سال در اشیاء تاریخ یا زمان.
- MAXYEAR: بزرگترین عدد مجاز برای سال که برابر با ۹۹۹۹ است.
- UTC: نام مستعار شیء منطقه زمانی ساعت هماهنگ جهانی (datetime.timezone.utc) که از نسخه ۳.۱۱ اضافه شده است.
۶ کلاس اصلی این کتابخانه نیز دادههای زمانی را مدیریت میکنند:
- کلاس date: تاریخ تقویمی، شامل سال، ماه و روز، را بدون اطلاعات ساعت نگه میدارد و مدیریت میکند.
- کلاس time: زمان در روز، شامل ساعت، دقیقه، ثانیه، میکروثانیه و منطقه زمانی، را مستقل از یک روز خاص نمایش میدهد.
- کلاس datetime: ترکیبی از دو کلاس date و time است و تاریخ و ساعت را همزمان نگه میدارد.
- کلاس timedelta: یک بازه زمانی را نمایش میدهد و اختلاف بین دو شیء date یا datetime را با دقت میکروثانیه محاسبه میکند.
- کلاس tzinfo: یک کلاس پایه انتزاعی (Abstract) برای ساخت اشیاء اطلاعات منطقه زمانی و ساعت تابستانی است.
- کلاس timezone: کلاسی است که tzinfo را بهصورت یک فاصله زمانی (Offset) ثابت از زمان جهانی UTC پیادهسازی میکند.
اشیاء ساختهشده از این کلاسها تغییرناپذیر (Immutable) هستند؛ یعنی پس از ساخته شدن، مقدار درونی آنها تغییر نمیکند. انواع date، datetime، time و timezone ویژگی Hashable نیز دارند و میتوان از آنها بهعنوان کلید در دیکشنری در پایتون استفاده کرد.
دریافت تاریخ و زمان فعلی (سریعترین روش)
برای دریافت تاریخ و ساعت لحظهای سیستم محلی خود، از متد now() در کلاس datetime استفاده کنید. خروجی این متد شامل سال، ماه، روز، ساعت، دقیقه، ثانیه و میکروثانیه است:
import datetime as dt
current_datetime = dt.datetime.now()
print(current_datetime)
خروجی:
2026-08-13 05:35:28.162136
اگر به ساعت نیازی ندارید و فقط تاریخ محلی امروز را میخواهید، متد کلاسی today() از کلاس date را فراخوانی کنید:
from datetime import date
current_date = date.today()
print(current_date)
خروجی:
2025-07-26
کلاس date؛ ساخت و مدیریت تاریخ
کلاس date برای کار با تاریخهای تقویمی طراحی شده است و اطلاعات ساعت یا منطقه زمانی را در خود نگه نمیدارد.
ساخت تاریخ دلخواه و استخراج سال، ماه و روز
برای ساخت یک شیء تاریخ دلخواه، سه آرگومان عدد صحیح شامل سال، ماه (۱ تا ۱۲) و روز را به سازنده date(year, month, day) بدهید. وارد کردن عددی خارج از محدوده تقویم، مثلاً ماه ۱۳، خطای ValueError ایجاد میکند.

پس از ساخت شیء تاریخ، با صفتهای .year، .month و .day میتوانید به اجزای آن دسترسی پیدا کنید. برای یافتن روز هفته نیز متد weekday() با بازه ۰ (دوشنبه) تا ۶ (یکشنبه) و متد isoweekday() با بازه ۱ (دوشنبه) تا ۷ (یکشنبه) در دسترس هستند:
from datetime import date
# ساخت یک تاریخ مشخص
custom_date = date(2026, 8, 13)
print("Full Date:", custom_date)
# استخراج اجزای تاریخ
print("Year:", custom_date.year)
print("Month:", custom_date.month)
print("Day:", custom_date.day)
# دریافت ایندکس روز هفته
print("Weekday Index (0-6):", custom_date.weekday())
print("ISO Weekday (1-7):", custom_date.isoweekday())
خروجی:
Full Date: 2026-08-13
Year: 2026
Month: 8
Day: 13
Weekday Index (0-6): 3
ISO Weekday (1-7): 4
تبدیل Timestamp به تاریخ
متد fromtimestamp() یک POSIX timestamp (مانند مقداری که time.time() برمیگرداند) را به شیء تاریخ محلی تبدیل میکند:
from datetime import date
timestamp_date = date.fromtimestamp(1887639468)
print(timestamp_date)
خروجی:
2029-10-25
جدول زیر متدهای کاربردی کلاس date و کاربرد هرکدام را نشان میدهد:
| متد | کاربرد |
|---|---|
| today() | تاریخ محلی فعلی را برمیگرداند. |
| fromtimestamp() | یک عدد Timestamp را به شیء تاریخ تبدیل میکند. |
| isoformat() | شیء تاریخ را به یک رشته با فرمت استاندارد YYYY-MM-DD تبدیل میکند. |
| fromisoformat() | یک رشته با فرمت استاندارد ISO را به شیء date تبدیل میکند. |
| replace() | یک شیء تاریخ جدید با تغییر مقادیر انتخابی (سال، ماه یا روز) برمیگرداند. |
| weekday() | روز هفته را بهصورت عدد صحیح بین ۰ (دوشنبه) تا ۶ (یکشنبه) برمیگرداند. |
| isoweekday() | روز هفته را بهصورت عدد صحیح بین ۱ (دوشنبه) تا ۷ (یکشنبه) برمیگرداند. |
کلاس time؛ کار با زمان مستقل از تاریخ
کلاس time زمان را در شبانهروز، بدون وابستگی به یک تاریخ خاص، نمایش میدهد. در سازنده این کلاس میتوانید مقادیر hour، minute، second، microsecond و tzinfo را مشخص کنید.
مثال زیر ساخت شیء زمان و استخراج ویژگیهای .hour، .minute، .second و .microsecond را نشان میدهد:
from datetime import time
# ساخت شیء زمان با مقداردهی ساعت، دقیقه و ثانیه
t = time(11, 34, 56)
print("Time:", t)
print("hour =", t.hour)
print("minute =", t.minute)
print("second =", t.second)
print("microsecond =", t.microsecond)
خروجی:
Time: 11:34:56
hour = 11
minute = 34
second = 56
microsecond = 0
برای تبدیل شیء time به رشته متنی با فرمت استاندارد ISO، متد isoformat() را فراخوانی کنید:
from datetime import time
t = time(12, 24, 36)
time_str = t.isoformat()
print(time_str)
print(type(time_str))
خروجی:
12:24:36
<class 'str'>
کلاس datetime؛ ترکیب تاریخ و ساعت
وقتی میخواهید تاریخ و ساعت یک رویداد را همزمان در یک متغیر ذخیره و پردازش کنید، از کلاس datetime استفاده کنید. سازنده این کلاس ساختار زیر را دارد:

datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
سه آرگومان اول این سازنده (year, month, day) اجباری هستند. سایر آرگومانها اختیاریاند و مقدار پیشفرض صفر دارند؛ مقدار پیشفرض tzinfo نیز None است. مانند کلاس تاریخ، وارد کردن عددی خارج از محدوده مجاز، مثلاً ساعت ۲۵ یا دقیقه ۶۵، خطای ValueError تولید میکند.
from datetime import datetime
# ساخت شیء datetime
dt_obj = datetime(2017, 11, 28, 23, 55, 59, 342380)
print("Full datetime:", dt_obj)
# استخراج اجزا و timestamp
print("Year:", dt_obj.year)
print("Month:", dt_obj.month)
print("Hour:", dt_obj.hour)
print("Date part only:", dt_obj.date())
print("Time part only:", dt_obj.time())
print("Timestamp:", dt_obj.timestamp())
خروجی:
Full datetime: 2017-11-28 23:55:59.342380
Year: 2017
Month: 11
Hour: 23
Date part only: 2017-11-28
Time part only: 23:55:59.342380
Timestamp: 1511913359.34238
جدول زیر مهمترین متدهای کلاس datetime را نشان میدهد:
| نام متد | کاربرد |
|---|---|
| now() | تاریخ و زمان محلی فعلی را برمیگرداند. |
| today() | تاریخ و زمان محلی کنونی را برمیگرداند. |
| fromtimestamp() | یک عدد Timestamp را به شیء datetime تبدیل میکند. |
| timestamp() | مقدار POSIX timestamp معادل شیء را برمیگرداند. |
| date() | فقط بخش تاریخ (شیء date) را از درون datetime استخراج میکند. |
| time() | فقط بخش ساعت (شیء time) را استخراج میکند. |
| replace() | یک شیء datetime جدید با مقادیر جایگزینشده برمیگرداند. |
| isoformat() | تاریخ و زمان را به رشته استاندارد ISO ۸۶۰۱ (مانند ۲۰۲۶-۰۸-13T10:۳۰:۰۰) تبدیل میکند. |
تسلط بر این متدها و اشیاء datetime، پیشنیاز اصلی مدیریت سریهای زمانی و تحلیل داده است.
کلاس timedelta؛ محاسبه اختلاف بین دو تاریخ و زمان
کلاس timedelta در پایتون یک بازه یا مدت زمان را نمایش میدهد و برای انجام محاسبات ریاضی روی تاریخ و ساعت به کار میرود.
جمع و تفریق تاریخها
سازنده این کلاس تمام واحدهای زمانی را بهصورت اختیاری و با مقدار پیشفرض صفر میپذیرد:
timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
آرگومانها میتوانند عدد صحیح یا اعشاری (Float)، مثبت یا منفی باشند. اگر دو شیء date یا دو شیء datetime را از هم کم کنید، خروجی یک شیء از نوع timedelta خواهد بود. همچنین میتوانید یک timedelta را به تاریخ اضافه یا از آن کم کنید تا تاریخ جدیدی در آینده یا گذشته به دست آید:
import datetime as dt
# ۱. محاسبه اختلاف بین دو تاریخ
start_date = dt.date(2026, 8, 13)
end_date = dt.date(2026, 8, 20)
difference = end_date - start_date
print("Difference:", difference)
print("Type:", type(difference))
# ۲. جلو بردن زمان با جمع کردن timedelta
current_dt = dt.datetime(2026, 8, 13, 10, 30)
future_dt = current_dt + dt.timedelta(days=5, hours=3)
print("Future Datetime:", future_dt)
# ۳. ضرب و تقسیم timedelta در اعداد صحیح
duration = dt.timedelta(hours=2)
print("Multiplied by 3:", duration * 3)
print("Divided by 2:", duration // 2)
خروجی:
Difference: 7 days, 0:00:00
Type: <class 'datetime.timedelta'>
Future Datetime: 2026-08-18 13:30:00
Multiplied by 3: 6:00:00
Divided by 2: 1:00:00
نحوه ذخیرهسازی داخلی و تفاوت seconds با total_seconds
پایتون در ساختار داخلی timedelta فقط سه واحد days، seconds و microseconds را ذخیره میکند. هر آرگومان دیگری که به آن بدهید، به این سه واحد تبدیل و نرمالسازی (Normalized) میشود. هر هفته به ۷ روز، هر ساعت به ۳۶۰۰ ثانیه، هر دقیقه به ۶۰ ثانیه و هر میلیثانیه به ۱۰۰۰ میکروثانیه تبدیل میشود. مقادیر این سه واحد محدودههای مشخصی دارند:

- میکروثانیهها همیشه در بازه ۰ <= microseconds < ۱۰۰۰۰۰۰ قرار میگیرند.
- ثانیهها همیشه در بازه ۰ <= seconds < ۳۶۰۰*۲۴ (تعداد ثانیههای یک شبانهروز کامل) تنظیم میشوند.
- روزها بین -۹۹۹۹۹۹۹۹۹ تا ۹۹۹۹۹۹۹۹۹ قرار میگیرند.
import datetime as dt
delta = dt.timedelta(
days=50,
seconds=27,
microseconds=10,
milliseconds=29000,
minutes=5,
hours=8,
weeks=2
)
print(repr(delta))
خروجی:
datetime.timedelta(days=64, seconds=29156, microseconds=10)
این نرمالسازی ثانیهها و میکروثانیهها را غیرمنفی نگه میدارد؛ به همین دلیل، نمایش مقادیر منفی timedelta در نگاه اول کمی غیرمعمول به نظر میرسد. برای مثال، timedelta(hours=-۵) بهصورت ۱ روز منفی بهعلاوه ۱۹ ساعت (۶۸۴۰۰ ثانیه) نرمالسازی میشود:
import datetime as dt
neg_delta = dt.timedelta(hours=-5)
print(repr(neg_delta))
خروجی:
datetime.timedelta(days=-1, seconds=68400)
یکی از باگهای رایج این است که برنامهنویسان برای به دست آوردن کل ثانیههای یک بازه زمانی، به اشتباه از صفت .seconds به جای متد .total_seconds() استفاده میکنند. صفت .seconds فقط ثانیههای نرمالسازیشده در همان روز را برمیگرداند، اما متد .total_seconds() کل بازه زمانی را به ثانیه برمیگرداند:
import datetime as dt
duration = dt.timedelta(seconds=11235813)
# صفتها فقط مقادیر نرمالسازیشده را نشان میدهند
print("Days attribute:", duration.days)
print("Seconds attribute:", duration.seconds)
# متد total_seconds کل زمان را به ثانیه برمیگرداند
print("Total seconds:", duration.total_seconds())
خروجی:
Days attribute: 130
Seconds attribute: 3813
Total seconds: 11235813.0
ثبت زمان دقیق رویدادها و محاسبه فواصل زمانی با timedelta، پایه اصلی نوشتن اسکریپتهای زمانبندی و خودکارسازی وظایف است.
فرمتدهی و تبدیل تاریخ و رشته به یکدیگر
شیوه نوشتن تاریخ در مناطق و سازمانهای مختلف یکسان نیست. مثلاً در آمریکا فرمت mm/dd/yyyy رایج است، اما در انگلستان از فرمت dd/mm/yyyy استفاده میشود. ماژول datetime برای مدیریت نمایش تاریخ و تبدیل رشته در پایتون به اشیاء زمانی، دو متد strftime() و strptime() دارد.
برای اشتباه نگرفتن نام این دو متد، تفاوت کار آنها را به خاطر بسپارید:
- متد strftime شیء تاریخ را فرمتدهی و به رشته تبدیل میکند.
- متد strptime رشته متنی را تجزیه و به شیء تاریخ تبدیل میکند.
تبدیل تاریخ به رشته با متد strftime()
میتوانید متد strftime() را روی اشیاء date، time و datetime فراخوانی کنید. این متد یک رشته فرمت میگیرد و تاریخ را با قالب دلخواه شما بهصورت رشته (str) برمیگرداند:

import datetime as dt
now = dt.datetime(2018, 12, 26, 4, 34, 52)
# فرمت ساعت
t = now.strftime("%H:%M:%S")
print("time:", t)
# فرمت رایج آمریکا (ماه/روز/سال)
s1 = now.strftime("%m/%d/%Y, %H:%M:%S")
print("s1:", s1)
# فرمت رایج انگلستان (روز/ماه/سال)
s2 = now.strftime("%d/%m/%Y, %H:%M:%S")
print("s2:", s2)
print("Output type:", type(s1))
خروجی:
time: 04:34:52
s1: 12/26/2018, 04:34:52
s2: 26/12/2018, 04:34:52
Output type: <class 'str'>
جدول کدهای فرمتدهی تاریخ و زمان
جدول زیر چند کد فرمتدهی را نشان میدهد که در مثالهای مستندات برای متدهای strftime و strptime به کار رفتهاند:
| کد فرمت | توضیح | مثال خروجی |
|---|---|---|
| %Y | سال به صورت کامل (۴ رقمی) | 2002, 2006 |
| %y | سال به صورت کوتاه (۲ رقمی) | 02, 06 |
| %m | شماره ماه | 03, 11 |
| %B | نام ماه به انگلیسی | March, November |
| %d | روز ماه | 11, 21 |
| %A | نام روز هفته به انگلیسی | Monday, Tuesday |
| %H | ساعت | 16 |
| %I | ساعت (همراه با AM/PM) | 04 |
| %p | نمایشگر AM/PM | PM |
| %M | دقیقه | 30 |
تبدیل رشته به تاریخ با متد strptime()
وقتی تاریخ را از ورودی کاربر، فایل متنی یا در مسیر آموزش پایگاه داده میخوانید، نوع داده آن رشته (str) است. برای انجام محاسبات زمانی، این رشته را با متد strptime() به شیء datetime تبدیل کنید. این متد دو آرگومان میگیرد: رشته حاوی تاریخ و الگوی فرمت. الگو باید با ساختار رشته ورودی مطابقت داشته باشد:
from datetime import datetime
date_string = "21/11/06 16:30"
date_object = datetime.strptime(date_string, "%d/%m/%y %H:%M")
print("date_object =", date_object)
print("Type =", type(date_object))
خروجی:
date_object = 2006-11-21 16:30:00
Type = <class 'datetime.datetime'>
مدیریت منطقه زمانی (Timezone) در پایتون
اگر پروژهای با کاربران جهانی توسعه میدهید، ساعت کامپیوتر محلی بهتنهایی کافی نیست و باید منطقه زمانی (Timezone) را در اشیاء زمانی لحاظ کنید.
تفاوت اشیاء Naive و Aware
در مستندات پایتون، اشیاء تاریخ و زمان بر اساس داشتن یا نداشتن اطلاعات منطقه زمانی به دو دسته تقسیم میشوند:
- اشیاء ساده (Naive): اطلاعات منطقه زمانی ندارند. اشیاء ساختهشده با کلاس date همیشه Naive هستند.
- اشیاء آگاه (Aware): اطلاعات منطقه زمانی دارند. اشیاء datetime و time صفتی به نام tzinfo دارند؛ اگر متد utcoffset() آنها مقدار None برنگرداند، آن شیء Aware است و در غیر این صورت Naive است. تمایز بین Aware و Naive برای اشیاء timedelta کاربردی ندارد.
تنظیم منطقه زمانی با کلاس timezone و کتابخانه pytz
ماژول datetime کلاسی به نام timezone دارد که زیرکلاس tzinfo است. این کلاس میتواند مناطق زمانی را بهصورت یک فاصله ثابت (Offset) از ساعت جهانی UTC تعریف کند:

from datetime import datetime, timezone, timedelta
# تعریف یک منطقه زمانی با فاصله ثابت +5:30 از UTC
ist_tz = timezone(timedelta(hours=5, minutes=30), "IST")
# ساخت شیء datetime آگاه از منطقه زمانی
aware_dt = datetime(2026, 8, 13, 10, 30, tzinfo=ist_tz)
print(aware_dt)
print("Timezone Name:", aware_dt.tzname())
print("UTC Offset:", aware_dt.utcoffset())
خروجی:
2026-08-13 10:30:00+05:30
Timezone Name: IST
UTC Offset: 5:30:00
اشیاء کلاس timezone را نمیتوان برای نمایش اطلاعات منطقه زمانی در مکانهایی به کار برد که در روزهای مختلف سال از آفستهای متفاوت استفاده میکنند یا تغییرات تاریخی در زمان رسمی داشتهاند. برای استفاده از پایگاه داده مناطق زمانی IANA، معروف به پایگاه داده Olson، در پایتون، مستندات رسمی ماژول zoneinfo را توصیه میکند.
تمرین عملی؛ محاسبه تعداد روزهای سپریشده از عمر
با ترکیب مفاهیمی که بررسی میکنیم، شامل کلاس date، متد strptime، تفریق تاریخها و صفت .days از شیء timedelta، برنامهای مینویسیم که یک تاریخ مقصد را از ورودی دریافت کند. برنامه تعداد روزهای زندگی فرد را از تاریخ تولدش تا آن تاریخ محاسبه میکند:

import datetime as dt
# ۱. تعریف تاریخ تولد فرد با کلاس date
birth_date = dt.date(1982, 2, 14)
# ۲. دریافت تاریخ مقصد از کاربر به صورت رشته
input_str = input('Enter your Date (e.g. 1990.05.11): ')
# ۳. تبدیل رشته ورودی به شیء datetime با متد strptime
target_datetime = dt.datetime.strptime(input_str, "%Y.%m.%d")
# ۴. استخراج بخش تاریخ با date()، تفریق از تاریخ تولد و گرفتن تعداد روزها
days_lived = (target_datetime.date() - birth_date).days
# ۵. بررسی شرطی برای اطمینان از اینکه تاریخ واردشده بعد از تاریخ تولد است
if days_lived <= 0:
print('You were not born on this date.')
else:
print(f"It's been {days_lived} days from your date of birth to input date")
خروجی برنامه به ازای ورودی ۲۰۲۰.۰۶.۱۶:
Enter your Date (e.g. 1990.05.11): 2020.06.16
It's been 14002 days from your date of birth to input date
خروجی strptime() در این کد یک شیء datetime همراه با ساعت ۰۰:۰۰:۰۰ است و متغیر birth_date از نوع date تعریف شده است. به همین دلیل، ابتدا با متد target_datetime.date() فقط بخش تاریخ را فیلتر میکنیم تا دو طرف عملگر تفریق همنوع باشند. سپس با فراخوانی صفت .days روی حاصل تفریق، تعداد خالص روزها استخراج و در ساختار شرطی if-else بررسی میشود. پیادهسازی چنین مثالهایی با کتابخانههای استاندارد، بخش مهمی از مسیر آموزش برنامهنویسی برای تسلط بر حل مسائل واقعی است.