آموزش پایتون, پایتون سطح متوسط

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

تاریخ و زمان در پایتون با 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 در نظر گرفته شده است. در یک برنامه واقعی بهتر است منطقه زمانی ورودی نیز از کاربر دریافت یا از تنظیمات حساب او مشخص شود.

تمرین‌های درس

  1. تاریخ تولد را دریافت و تعداد روزهای گذشته از آن را محاسبه کنید.
  2. تاریخ امروز و تاریخ هفت، سی و نود روز آینده را نمایش دهید.
  3. رشته 2026-12-25 18:45 را به datetime تبدیل و با قالب دیگری چاپ کنید.
  4. یک زمان UTC را به مناطق زمانی استانبول و تهران تبدیل کنید.
  5. برنامه‌ای بسازید که مشخص کند تاریخ واردشده در گذشته، امروز یا آینده است.
  6. پروژه مدیریت مهلت را توسعه دهید و منطقه زمانی کاربر را نیز دریافت کنید.

اشتباهات رایج

  • مقایسه datetime ساده با datetime آگاه از منطقه زمانی
  • استفاده از utcnow() به‌جای ساخت زمان UTC آگاه
  • اشتباه‌گرفتن strftime با strptime
  • استفاده از timedelta.seconds به‌عنوان کل ثانیه‌ها
  • ذخیره زمان محلی بدون ثبت منطقه زمانی
  • استفاده از اختلاف ثابت برای منطقه‌ای که قوانین زمانی متغیر دارد
  • نادیده‌گرفتن ورودی نامعتبر و خطای ValueError
  • فرض‌کردن اینکه نام ماه و روز در همه سیستم‌ها یکسان نمایش داده می‌شود

جمع‌بندی

در این درس با کلاس‌های اصلی ماژول datetime آشنا شدیم، تاریخ و زمان ساختیم، مقادیر فعلی را دریافت کردیم، رشته‌ها را با strftime و strptime تبدیل کردیم و محاسبات زمانی را با timedelta انجام دادیم.

همچنین تفاوت datetime ساده و آگاه از منطقه زمانی، ذخیره زمان در UTC، تبدیل مناطق زمانی با zoneinfo و فرمت ISO 8601 را بررسی کردیم. در درس بعدی، وارد برنامه‌نویسی شی‌گرا می‌شویم و مفاهیم Class و Object را یاد می‌گیریم.

ادامه مسیر یادگیری پایتون

برای یادگیری منظم، آموزش‌های مرتبط زیر را به‌ترتیب دنبال کنید:

📌 همچنین بخوانید: بازار کار پایتون در ایران، دستورهای break، continue و pass در پایتون و ساخت ربات تلگرام با پایتون

می‌خواهی پیشرفتت ذخیره شود؟با ورود یا ثبت‌نام رایگان، درس‌های تمام‌شده را علامت بزن و درصد پیشرفتت را در حساب کاربری ببین.ورود / ثبت‌نام برای ذخیره پیشرفت
درس بعدی · دوره پایتون متوسط (16 از 18)مبانی برنامه‌نویسی شی‌گرا در پایتون؛ آموزش Class و Object ←
آموزش‌های تازه، کد آماده و رفع خطاهر هفته در کانال Dev Source؛ رایگان.
🧭 مسیر یادگیری پایتون از صفر
ماژول 8: ماژول‌ها و کتابخانه‌ها — درس 37 از 44

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

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *