النوعان الأساسيان: date و datetime
تقدّم لك وحدة datetime في بايثون أربعة أنواع تستحق المعرفة: date و time و datetime و timedelta. الثلاثة الأولى تعبّر عن التاريخ والوقت كما يوحي اسمها، أما الرابع فهو فترة زمنية (مدّة).
كائن date يمثّل يومًا واحدًا (سنة وشهر ويوم) بدون أي وقت. أما datetime فهو تاريخ مع وقت. إذا ما كنت محتاجًا الوقت، فاستخدام date أنظف وأبسط.
إنشاء تواريخ محدّدة في بايثون
أنشئ الكائن مباشرةً:
الوسطاء (arguments) هي year, month, day للـ date، وتصل إلى year, month, day, hour, minute, second, microsecond للـ datetime.
قراءة الحقول
كل كائن date أو datetime يحتوي على خصائص (attributes) يمكن الوصول إليها مباشرة:
isoformat() صديقك المفضّل لمّا تحتاج مخرجات تقدر الأنظمة الأخرى تقرأها، لأنه يعطيك شيئاً بالشكل ده "2026-04-20T09:30:15" يقدر أي نظام يفهمه بدون لبس.
تنسيق التاريخ في بايثون باستخدام strftime
لمّا تبغى تعرض التاريخ بصيغة مفهومة للبشر، الدالة .strftime(fmt) تحوّل كائن date أو datetime إلى نص منسّق حسب ما تريد:
رموز التنسيق الأكثر استخداماً والتي يُفضّل تذكّرها:
%Y— السنة بأربع خانات (2026)%m— رقم الشهر بخانتين (04)%d— اليوم في الشهر بخانتين (20)%H/%I— الساعة بنظام 24 / 12%M— الدقائق%S— الثواني%A/%a— اسم اليوم كاملاً / مختصراً (Monday / Mon)%B/%b— اسم الشهر كاملاً / مختصراً (April / Apr)%p— صباحاً/مساءً (AM/PM)
لا داعي لحفظها عن ظهر قلب؛ احتفظ برابط مرجعي لها وارجع إليه وقت الحاجة.
تحويل نص إلى تاريخ باستخدام strptime
الآن الاتجاه المعاكس: نأخذ نصاً بصيغة معروفة ونحوّله إلى كائن datetime:
صيغة التنسيق يجب أن تطابق النص المُدخَل تمامًا، وإلا سيُطلق strptime خطأ من نوع ValueError.
أما إذا كنت تتعامل مع نصوص بصيغة ISO-8601 (الصيغة القياسية التي تفهمها الأنظمة)، فهناك طريقة أبسط بكثير في إصدارات بايثون الحديثة:
إذا كنت تتعامل مع صيغ تواريخ غير منتظمة، فهناك مكتبة خارجية اسمها dateutil (تثبّتها عبر pip install python-dateutil) توفّر دالة parser.parse() مرنة جدًا تحاول تخمين الصيغة بشكل منطقي.
العمليات الحسابية باستخدام timedelta
لإجراء عمليات حسابية على التواريخ في بايثون، نستخدم timedelta سواء لحساب الفرق بين وقتين أو لإضافة فترة زمنية إلى تاريخ معيّن:
وسائط timedelta المتاحة هي: days, seconds, microseconds, milliseconds, minutes, hours, weeks. لن تجد months أو years، لأن طول الشهر غير ثابت. إذا احتجت إلى حسابات بالأشهر أو السنوات، استخدم dateutil.relativedelta:
from dateutil.relativedelta import relativedelta
from datetime import date
today = date.today()
next_quarter = today + relativedelta(months=3)
print(next_quarter)
المناطق الزمنية: naive مقابل aware
كائن datetime بدون معلومات عن المنطقة الزمنية يُسمى naive — أي أن بايثون لا يعرف أي منطقة زمنية يمثّلها. العمليات الحسابية على التواريخ من نوع naive تعمل بلا مشاكل طالما بقيت داخل منطقة زمنية واحدة، لكن المشاكل تبدأ في اللحظة التي تلتقي فيها بيانات قادمة من مناطق مختلفة.
أما كائن aware فيحمل معه معلومات المنطقة الزمنية. لربط منطقة زمنية صراحةً بالتاريخ:
أضافت بايثون 3.9 وحدة zoneinfo للتعامل مع المناطق الزمنية بالاسم (بالاعتماد على قاعدة بيانات IANA الموجودة في النظام):
للتحويل بين المناطق الزمنية، استخدم .astimezone():
قاعدة تستحق الحفظ: خزّن التواريخ والأوقات بصيغة UTC دائمًا، وحوّلها إلى التوقيت المحلي فقط عند العرض للمستخدم. هذه العادة وحدها تكفيك معظم المشاكل المتعلقة بالمناطق الزمنية.
التعامل مع timestamp في بايثون
الـ Unix timestamp هو ببساطة عدد الثواني المنقضية منذ 1970-01-01 بتوقيت UTC. وبايثون يتعامل معه بسلاسة:
الطوابع الزمنية (timestamps) مفيدة للمقارنات والترتيب والتكامل مع الأنظمة الأخرى. أما إذا كان الناتج معروضًا للمستخدم، فالأفضل تحويله إلى كائن datetime أولًا.
قياس المدة التي يستغرقها تنفيذ شيء ما
لقياس المدة بشكل سريع، اطرح كائني datetime من بعضهما:
لو تبغى قياس أداء أدق، استخدم time.perf_counter() — دقته أقل من الميكروثانية وما يتأثر بتغييرات ساعة النظام. أما datetime.now() فيكفيك لو تبغى تعرف "كم استغرق هذا الطلب من الـ API" وأشباهه.
أنماط راح تستخدمها كثير
الخلاصة
dateوdatetimeوtimedeltaتغطي 90% من احتياجاتك مع التاريخ والوقت في بايثون.- استخدم صيغة ISO-8601 للتنسيق الذي تقرأه الآلة، و
strftimeللتنسيق الذي يقرأه البشر. - احفظ الأوقات بتوقيت UTC، وحوّلها إلى المنطقة الزمنية المطلوبة وقت العرض فقط.
- اعتمد على
zoneinfoللتعامل مع المناطق الزمنية المسماة. - عند التعامل مع الأشهر والسنوات، استعن بـ
dateutil.relativedelta.
أداة أخرى ستحتاجها كثيرًا في مشاريعك الفعلية: التعابير النمطية (Regular Expressions)، وهي موضوع الدرس القادم.
الأسئلة الشائعة
كيف أحصل على التاريخ والوقت الحاليين في بايثون؟
الدالة datetime.now() تعيد التاريخ والوقت المحليين. أما datetime.utcnow() فتعيد وقت UTC، لكن الطريقة المفضّلة حالياً هي datetime.now(timezone.utc) لأن utcnow() تُرجع كائناً بدون معلومات المنطقة الزمنية (naive). ولو احتجت التاريخ فقط بدون الوقت، استخدم date.today().
كيف أحوّل التاريخ إلى نص بصيغة معينة؟
استعمل .strftime(format) مع رموز التنسيق مثل %Y-%m-%d للسنة والشهر واليوم. مثال: datetime.now().strftime('%Y-%m-%d %H:%M'). ولتحويل نص إلى كائن تاريخ، استخدم datetime.strptime(text, format) بنفس رموز التنسيق.
كيف أضيف أياماً إلى تاريخ معيّن في بايثون؟
عبر timedelta مثل: from datetime import date, timedelta; date.today() + timedelta(days=7). يدعم timedelta الأيام والساعات والدقائق والثواني والأسابيع. أما إذا أردت إضافة شهور أو سنوات فاستعمل dateutil.relativedelta من مكتبة خارجية، لأن timedelta لا يتعامل مع الشهور.