العمل مع التواريخ والوقت في C++: دليل شامل

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

العمل مع التواريخ والوقت في C++: من الكلاسيكي إلى المعيار الحديث



إدارة التواريخ والوقت هي إحدى المهام الأساسية في تطوير البرمجيات. سواء كان تسجيل الأحداث، حساب المواعيد النهائية، العمل مع المؤقتات أو تحليل البيانات - لا يمكن الاستغناء عن أدوات موثوقة. في C++ توجد عدة طرق لذلك: من المكتبة الكلاسيكية <ctime> إلى المكتبة الحديثة <chrono> التي ظهرت في C++11 وتم توسيعها بشكل كبير في C++20. في هذه المقالة سنستعرض الطرق الأساسية للعمل مع التواريخ والوقت، ونقدم أمثلة عملية، ونوضح كيفية تجنب الأخطاء الشائعة.



1. الطريقة الكلاسيكية: مكتبة <ctime>



مكتبة <ctime> جاءت إلى C++ من لغة C. توفر وسائل بسيطة ولكنها محدودة للعمل مع الوقت التقويمي. الأنواع الأساسية: std::time_t (عدد صحيح من الثواني منذ 1 يناير 1970) و std::tm (هيكل يحتوي على حقول السنة، الشهر، اليوم، الساعات، الدقائق، الثواني، إلخ).



مثال 1: الحصول على الوقت الحالي وتنسيقه



#include <iostream>#include <ctime>

int main() { // الحصول على الوقت الحالي std::time_t now = std::time(nullptr); // التحويل إلى الوقت المحلي std::tm* local = std::localtime(&now); // الطباعة بصيغة "YYYY-MM-DD HH:MM:SS" char buffer[80]; std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local); std::cout << "الوقت الحالي: " << buffer << std::endl; return 0;}


الدوال الأساسية في <ctime>:

  • std::time() — تعيد الوقت التقويمي الحالي.
  • std::localtime() — تحول time_t إلى هيكل tm يمثل الوقت المحلي.
  • std::gmtime() — نفس الشيء ولكن لـ UTC (التوقيت العالمي المنسق).
  • std::mktime() — تحويل عكسي: من tm إلى time_t.
  • std::difftime() — تحسب الفرق بالثواني بين لحظتين زمنيتين.
  • std::strftime() — تنسيق التاريخ والوقت إلى سلسلة نصية وفق قالب محدد.


العيوب: المكتبة لا تراعي المناطق الزمنية (باستثناء المحلي وUTC)، لا تدعم الدقة العالية (فقط الثواني)، وهيكل tm ليس آمنًا من حيث النوع (على سبيل المثال، السنة تحسب من 1900، الشهر من 0 إلى 11).



2. المعيار الحديث: مكتبة <chrono> (C++11 وما بعده)



بدءًا من C++11، تمت إضافة <chrono> إلى المكتبة القياسية - وهي مكتبة آمنة من حيث النوع وعالية الدقة للعمل مع الوقت. تعمل بثلاثة مفاهيم أساسية: المدة (duration)، نقطة زمنية (time_point) و الساعة (clock).



أنواع الساعات:

  • std::chrono::system_clock — وقت النظام، مرتبط بالتقويم (يمكن تحويله إلى time_t).
  • std::chrono::steady_clock — ساعة رتيبة، مثالية لقياس الفترات الزمنية (لا تتأثر بالتعديلات).
  • std::chrono::high_resolution_clock — ساعة بأعلى دقة متاحة (غالبًا ما تكون مرادفًا لـ steady_clock).


مثال 2: قياس وقت تنفيذ عملية



#include <iostream>#include <chrono>#include <thread>

int main() { // تسجيل البداية auto start = std::chrono::steady_clock::now(); // محاكاة عمل std::this_thread::sleep_for(std::chrono::milliseconds(500)); // تسجيل النهاية auto end = std::chrono::steady_clock::now(); // حساب الفرق auto duration = end - start; // طباعة المدة بالمللي ثانية std::cout << "مدة التنفيذ: " << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() << " مللي ثانية" << std::endl; return 0;}


المزايا الرئيسية لـ <chrono>:

  • السلامة من حيث النوع: لا يمكن خلط الدقائق مع الثواني عن طريق الخطأ.
  • الدقة: دعم النانو ثانية، الميكرو ثانية، المللي ثانية، الثواني، الدقائق، الساعات.
  • المرونة: سهولة إنشاء فترات زمنية مخصصة.
  • التوافق: يمكن تحويل system_clock::time_point إلى time_t للعمل مع الدوال القديمة.


مثال 3: العمل مع التواريخ في C++20



#include <iostream>#include <chrono>

int main() { using namespace std::chrono; // إنشاء تاريخ: 15 مارس 2024 year_month_day date = 2024y / March / 15d; // إضافة 30 يومًا auto new_date = sys_days{date} + days{30}; // تحويل إلى هيكل year_month_day year_month_day result = new_date; std::cout << "التاريخ الأصلي: " << date << ""; std::cout << "التاريخ بعد 30 يومًا: " << result << ""; return 0;}


3. الأخطاء الشائعة وكيفية تجنبها



الخطأ رقم 1: تجاهل المناطق الزمنية

عند استخدام std::localtime() تذكر أنه يعيد الوقت المحلي. إذا كان تطبيقك يعمل مع مستخدمين من مناطق زمنية مختلفة، استخدم std::gmtime() أو مكتبات خارجية مثل date.h (Howard Hinnant) للعمل مع المناطق الزمنية.



الخطأ رقم 2: استخدام time_t للفترات الزمنية القصيرة

time_t يعمل بدقة ثانية واحدة. لقياس الفترات القصيرة (مللي ثانية، ميكرو ثانية) استخدم <chrono>.



الخطأ رقم 3: افتراض أن year_month_day آمن في العمليات الحسابية

عند إضافة أيام إلى تاريخ، استخدم التحويل إلى sys_days ثم أضف days. العمليات المباشرة على year_month_day قد تعطي نتائج غير متوقعة.



الخلاصة



توفر C++ أدوات قوية للعمل مع الوقت - من البسيطة <ctime> إلى الحديثة <chrono>. في المشاريع الجديدة يُوصى باستخدام <chrono>، خاصة مع إمكانيات C++20 التي تبسط العمل مع التواريخ والمناطق الزمنية. تذكر دائمًا مراعاة المناطق الزمنية ودقة القياسات لتجنب الأخطاء الشائعة. استخدم الأمثلة المقدمة كنقطة انطلاق لحلولك الخاصة!

المدونات

توصيات الكتب