تاریخ و زمان در پایتون با datetime؛ آموزش کامل و پروژه عملی

🗓 آخرین بهروزرسانی:
کار با تاریخ و زمان در بسیاری از برنامهها ضروری است؛ از ثبت زمان ایجاد سفارش و محاسبه مهلت انجام کار تا نمایش ساعت محلی کاربران در کشورهای مختلف. پایتون با ماژول داخلی datetime ابزارهای لازم برای ساخت، قالببندی، مقایسه و محاسبه تاریخها و زمانها را فراهم میکند.
این مطلب، درس پانزدهم از دوره رایگان پایتون سطح متوسط است. در درس قبلی نصب کتابخانه با pip و ساخت محیط مجازی با venv را یاد گرفتیم. در این درس با کلاسهای اصلی date، time، datetime، timedelta و مدیریت منطقه زمانی آشنا میشویم.
ماژول datetime چیست؟
datetime بخشی از کتابخانه استاندارد پایتون است و نیازی به نصب جداگانه ندارد. این ماژول چند کلاس اصلی دارد:
| کلاس | کاربرد | نمونه |
|---|---|---|
date | نگهداری سال، ماه و روز | تاریخ تولد یا سررسید |
time | نگهداری ساعت، دقیقه و ثانیه | ساعت شروع جلسه |
datetime | ترکیب تاریخ و ساعت | زمان ثبت سفارش |
timedelta | نمایش فاصله زمانی | هفت روز یا سه ساعت |
timezone | ساخت منطقه زمانی با اختلاف ثابت | UTC |
میتوانیم کلاسهای موردنیاز را مستقیماً وارد کنیم:
from datetime import date, time, datetime, timedelta, timezoneساخت یک تاریخ با date
برای ساخت یک تاریخ، سال، ماه و روز را به کلاس date میدهیم:
from datetime import date
course_start = date(2026, 7, 20)
print(course_start)
print(course_start.year)
print(course_start.month)
print(course_start.day)خروجی تاریخ بهصورت استاندارد YYYY-MM-DD نمایش داده میشود. اگر تاریخ نامعتبر باشد، پایتون خطای ValueError ایجاد میکند:
from datetime import date
try:
invalid_date = date(2026, 2, 30)
except ValueError as error:
print("Invalid date:", error)دریافت تاریخ امروز
from datetime import date
today = date.today()
print(today)
print("Year:", today.year)
print("Month:", today.month)
print("Day:", today.day)date.today() تاریخ محلی سیستم را برمیگرداند. بنابراین نتیجه آن به ساعت و تنظیمات سیستم اجراکننده وابسته است.
ساخت زمان با time
کلاس time برای نمایش ساعت مستقل از یک روز مشخص استفاده میشود:
from datetime import time
meeting_time = time(14, 30, 45)
print(meeting_time)
print(meeting_time.hour)
print(meeting_time.minute)
print(meeting_time.second)ترتیب ورودیها ساعت، دقیقه، ثانیه و در صورت نیاز میکروثانیه است:
precise_time = time(9, 15, 20, 500000)
print(precise_time)ساخت تاریخ و زمان با datetime
کلاس datetime تاریخ و ساعت را در یک شیء نگه میدارد:
from datetime import datetime
created_at = datetime(2026, 7, 20, 10, 45, 30)
print(created_at)
print(created_at.date())
print(created_at.time())با متدهای date() و time() میتوان قسمت تاریخ و ساعت را جدا کرد.
دریافت تاریخ و زمان فعلی
برای زمان محلی سیستم:
from datetime import datetime
now = datetime.now()
print(now)
print(now.date())
print(now.time())شیء بالا منطقه زمانی ندارد و یک datetime ساده یا naive محسوب میشود. برای برنامههایی که فقط روی یک سیستم و یک منطقه زمانی اجرا میشوند، این مقدار ممکن است کافی باشد؛ اما برای APIها، سرورها و کاربران بینالمللی باید منطقه زمانی را صریح مدیریت کنیم.
تفاوت datetime ساده و آگاه از منطقه زمانی
- Naive datetime: اطلاعاتی درباره منطقه زمانی و اختلاف با UTC ندارد.
- Aware datetime: دارای
tzinfoاست و موقعیت زمانی آن نسبت به UTC مشخص است.
from datetime import datetime, timezone
local_naive = datetime.now()
utc_aware = datetime.now(timezone.utc)
print(local_naive)
print(local_naive.tzinfo)
print(utc_aware)
print(utc_aware.tzinfo)برای ثبت زمان رخدادها در برنامههای واقعی، ذخیره زمان بهصورت UTC آگاه از منطقه زمانی انتخاب مطمئنتری است:
from datetime import datetime, timezone
created_at = datetime.now(timezone.utc)
print(created_at)از datetime.utcnow() برای کد جدید استفاده نکنید؛ زیرا یک مقدار UTC بدون اطلاعات منطقه زمانی برمیگرداند. روش پیشنهادی، datetime.now(timezone.utc) است.
قالببندی تاریخ با strftime
متد strftime() یک شیء تاریخ یا زمان را به رشته تبدیل میکند:
from datetime import datetime
now = datetime.now()
print(now.strftime("%Y-%m-%d"))
print(now.strftime("%H:%M:%S"))
print(now.strftime("%Y-%m-%d %H:%M"))
print(now.strftime("%A, %d %B %Y"))| کد | معنی | نمونه |
|---|---|---|
%Y | سال چهاررقمی | 2026 |
%m | ماه دو رقمی | 07 |
%d | روز دو رقمی | 20 |
%H | ساعت 24 ساعته | 18 |
%M | دقیقه | 35 |
%S | ثانیه | 09 |
%A | نام کامل روز هفته | Monday |
%B | نام کامل ماه | July |
نام روزها و ماهها به تنظیمات locale سیستم وابسته است. برای تولید خروجی فارسی پایدار، بهتر است نامها را با یک نگاشت مشخص در برنامه مدیریت کنید.
تبدیل رشته به datetime با strptime
متد strptime() برعکس strftime() عمل میکند و رشته را براساس قالب مشخص به شیء datetime تبدیل میکند:
from datetime import datetime
text = "2026-07-20 18:30"
parsed = datetime.strptime(text, "%Y-%m-%d %H:%M")
print(parsed)
print(type(parsed))قالب باید دقیقاً با رشته ورودی هماهنگ باشد. برای مدیریت ورودی نامعتبر:
from datetime import datetime
user_input = "2026-13-40"
try:
selected_date = datetime.strptime(user_input, "%Y-%m-%d")
print(selected_date)
except ValueError:
print("فرمت یا مقدار تاریخ نامعتبر است.")هنگام تجزیه تاریخ، بهتر است سال را همیشه در رشته و قالب قرار دهید تا رفتار تاریخهای کبیسه مبهم نباشد.
فرمت استاندارد ISO 8601
برای ذخیره یا تبادل تاریخ و زمان میان برنامهها، قالب ISO 8601 انتخاب رایجی است. متد isoformat() شیء را به رشته استاندارد تبدیل میکند:
from datetime import datetime, timezone
now_utc = datetime.now(timezone.utc)
iso_text = now_utc.isoformat(timespec="seconds")
print(iso_text)برای تبدیل رشته ISO به شیء datetime:
from datetime import datetime
text = "2026-07-20T10:30:00+00:00"
value = datetime.fromisoformat(text)
print(value)
print(value.tzinfo)در برنامههای جدید، برای رشتههای ISO سازگار استفاده از fromisoformat() سادهتر و خواناتر از تعریف قالب دستی است.
محاسبه فاصله زمانی با timedelta
timedelta یک مدتزمان را نمایش میدهد و میتواند شامل هفته، روز، ساعت، دقیقه، ثانیه و میکروثانیه باشد:
from datetime import datetime, timedelta
now = datetime.now()
next_week = now + timedelta(weeks=1)
three_hours_ago = now - timedelta(hours=3)
print(next_week)
print(three_hours_ago)محاسبه تاریخ سررسید
from datetime import date, timedelta
start_date = date(2026, 7, 20)
deadline = start_date + timedelta(days=14)
print("Start:", start_date)
print("Deadline:", deadline)فاصله میان دو تاریخ
from datetime import date
start = date(2026, 7, 1)
end = date(2026, 7, 20)
difference = end - start
print(difference)
print(difference.days)اجزای timedelta
یک timedelta سه بخش ذخیرهشده اصلی دارد: روز، ثانیه و میکروثانیه. برای دریافت کل ثانیهها از total_seconds() استفاده کنید:
from datetime import timedelta
duration = timedelta(days=2, hours=5, minutes=30)
print(duration.days)
print(duration.seconds)
print(duration.total_seconds())ویژگی seconds فقط بخش باقیمانده ثانیه در روز را نشان میدهد؛ برای کل مدت همیشه total_seconds() مناسبتر است.
مقایسه تاریخها و زمانها
شیءهای سازگار تاریخ و زمان را میتوان با عملگرهای مقایسهای بررسی کرد:
from datetime import datetime
now = datetime.now()
deadline = datetime(2026, 12, 31, 23, 59)
if now < deadline:
print("Deadline has not passed.")
elif now == deadline:
print("Deadline is now.")
else:
print("Deadline has passed.")یک datetime بدون منطقه زمانی را مستقیماً با datetime آگاه از منطقه زمانی مقایسه نکنید. پیش از مقایسه، هر دو مقدار را به یک مدل زمانی سازگار تبدیل کنید.
تغییر بخشی از تاریخ با replace
اشیای datetime تغییرناپذیر هستند. متد replace() یک شیء جدید با مقادیر تغییرکرده میسازد:
from datetime import datetime
original = datetime(2026, 7, 20, 10, 30)
updated = original.replace(hour=18, minute=0)
print(original)
print(updated)توجه کنید که replace() عملیات زمانی انجام نمیدهد؛ فقط بخشهای مشخصشده را جایگزین میکند. برای افزودن دو ساعت باید از timedelta استفاده کنید.
ترکیب date و time
from datetime import date, time, datetime
selected_date = date(2026, 8, 1)
selected_time = time(9, 30)
appointment = datetime.combine(selected_date, selected_time)
print(appointment)روز هفته و شماره هفته
from datetime import date
today = date.today()
print(today.weekday())
print(today.isoweekday())
print(today.isocalendar())weekday(): دوشنبه صفر و یکشنبه شش است.isoweekday(): دوشنبه یک و یکشنبه هفت است.isocalendar(): سال ISO، شماره هفته و روز هفته را برمیگرداند.
timestamp چیست؟
timestamp تعداد ثانیههای گذشته از مبدأ زمانی یونیکس را نمایش میدهد. تبدیل datetime به timestamp:
from datetime import datetime, timezone
value = datetime.now(timezone.utc)
timestamp = value.timestamp()
print(timestamp)تبدیل timestamp به datetime آگاه از UTC:
from datetime import datetime, timezone
timestamp = 1784543400
value = datetime.fromtimestamp(timestamp, tz=timezone.utc)
print(value)کار با منطقه زمانی توسط zoneinfo
برای مناطق زمانی واقعی مانند استانبول، تهران یا نیویورک، اختلاف ثابت کافی نیست؛ زیرا قوانین ساعت تابستانی و تغییرات تاریخی ممکن است متفاوت باشند. ماژول داخلی zoneinfo از پایگاه مناطق زمانی IANA استفاده میکند.
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
utc_time = datetime.now(timezone.utc)
istanbul_time = utc_time.astimezone(ZoneInfo("Europe/Istanbul"))
tehran_time = utc_time.astimezone(ZoneInfo("Asia/Tehran"))
print("UTC:", utc_time)
print("Istanbul:", istanbul_time)
print("Tehran:", tehran_time)در بعضی سیستمها، اگر داده منطقه زمانی نصب نباشد، میتوان بسته رسمی tzdata را در محیط مجازی پروژه نصب کرد:
python -m pip install tzdataتبدیل زمان محلی به UTC
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
local_time = datetime(
2026, 7, 20, 14, 30,
tzinfo=ZoneInfo("Europe/Istanbul")
)
utc_time = local_time.astimezone(timezone.utc)
print("Local:", local_time)
print("UTC:", utc_time)در برنامههای بینالمللی، زمان رخداد را معمولاً به UTC ذخیره و هنگام نمایش به منطقه زمانی کاربر تبدیل میکنند.
پروژه عملی: مدیریت مهلت انجام کار
در این پروژه، کاربر تاریخ سررسید را وارد میکند و برنامه تعداد روز و ساعت باقیمانده را محاسبه میکند:
from datetime import datetime, timezone
DATE_FORMAT = "%Y-%m-%d %H:%M"
user_input = input(
"Deadline in UTC (YYYY-MM-DD HH:MM): "
).strip()
try:
deadline_naive = datetime.strptime(user_input, DATE_FORMAT)
deadline = deadline_naive.replace(tzinfo=timezone.utc)
now = datetime.now(timezone.utc)
remaining = deadline - now
if remaining.total_seconds() <= 0:
print("The deadline has passed.")
else:
total_seconds = int(remaining.total_seconds())
days, rest = divmod(total_seconds, 86400)
hours, rest = divmod(rest, 3600)
minutes, seconds = divmod(rest, 60)
print(f"Days: {days}")
print(f"Hours: {hours}")
print(f"Minutes: {minutes}")
print(f"Seconds: {seconds}")
except ValueError:
print("Invalid date. Use YYYY-MM-DD HH:MM.")در این پروژه، زمان ورودی صریحاً UTC در نظر گرفته شده است. در یک برنامه واقعی بهتر است منطقه زمانی ورودی نیز از کاربر دریافت یا از تنظیمات حساب او مشخص شود.
تمرینهای درس
- تاریخ تولد را دریافت و تعداد روزهای گذشته از آن را محاسبه کنید.
- تاریخ امروز و تاریخ هفت، سی و نود روز آینده را نمایش دهید.
- رشته
2026-12-25 18:45را به datetime تبدیل و با قالب دیگری چاپ کنید. - یک زمان UTC را به مناطق زمانی استانبول و تهران تبدیل کنید.
- برنامهای بسازید که مشخص کند تاریخ واردشده در گذشته، امروز یا آینده است.
- پروژه مدیریت مهلت را توسعه دهید و منطقه زمانی کاربر را نیز دریافت کنید.
اشتباهات رایج
- مقایسه datetime ساده با datetime آگاه از منطقه زمانی
- استفاده از
utcnow()بهجای ساخت زمان UTC آگاه - اشتباهگرفتن
strftimeباstrptime - استفاده از
timedelta.secondsبهعنوان کل ثانیهها - ذخیره زمان محلی بدون ثبت منطقه زمانی
- استفاده از اختلاف ثابت برای منطقهای که قوانین زمانی متغیر دارد
- نادیدهگرفتن ورودی نامعتبر و خطای
ValueError - فرضکردن اینکه نام ماه و روز در همه سیستمها یکسان نمایش داده میشود
جمعبندی
در این درس با کلاسهای اصلی ماژول datetime آشنا شدیم، تاریخ و زمان ساختیم، مقادیر فعلی را دریافت کردیم، رشتهها را با strftime و strptime تبدیل کردیم و محاسبات زمانی را با timedelta انجام دادیم.
همچنین تفاوت datetime ساده و آگاه از منطقه زمانی، ذخیره زمان در UTC، تبدیل مناطق زمانی با zoneinfo و فرمت ISO 8601 را بررسی کردیم. در درس بعدی، وارد برنامهنویسی شیگرا میشویم و مفاهیم Class و Object را یاد میگیریم.
ادامه مسیر یادگیری پایتون
برای یادگیری منظم، آموزشهای مرتبط زیر را بهترتیب دنبال کنید:
📌 همچنین بخوانید: بازار کار پایتون در ایران، دستورهای break، continue و pass در پایتون و ساخت ربات تلگرام با پایتون
برای ذخیره پیشرفت در همه دستگاهها و دریافت گواهی پایان مسیر، رایگان ثبتنام کن یا وارد شو.