مقارنة التواريخ في JavaScript: تحسين الأداء

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

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

ابدأ الدورة

مقارنة التواريخ في JavaScript: كيف تتجنب الأخطاء وتسريع الكود

\n\n

تخيل: أنت تكتب متجرًا إلكترونيًا، وتحتاج إلى التحقق مما إذا كان الخصم على المنتج قد انتهى. أو تقوم بعمل تقويم للمهام حيث تحتاج إلى تصفية الأحداث الخاصة باليوم. أو تجمع تحليلات - "أظهر جميع الطلبات خلال الأسبوع الماضي". في كل هذه الحالات، تحتاج إلى مقارنة تاريخين. قد يبدو الأمر بسيطًا، لكن JavaScript، كالعادة، مستعدة لتقديم المفاجآت.

\n\n

سؤال "Compare two dates with JavaScript" على Stack Overflow حصد آلاف المشاهدات - وهذا ليس من قبيل الصدفة. المطورون، حتى ذوو الخبرة، غالبًا ما يتعثرون في الميزات غير الواضحة للعمل مع التواريخ. في هذه المقالة، لن نعرض فقط كيفية مقارنة تاريخين، بل سنحلل أيضًا أي طريقة أسرع وأيها أكثر أمانًا. هيا بنا!

\n\n

لماذا لا تعمل المقارنة البسيطة للتواريخ؟

\n\n

لنبدأ بالخطأ الكلاسيكي للمبتدئين. لنفترض أن لدينا تاريخين:

\n\n
let date1 = new Date('2024-03-15');\nlet date2 = new Date('2024-03-20');\n\nconsole.log(date1 < date2);  // true\nconsole.log(date1 > date2);  // false\nconsole.log(date1 == date2); // false\n
\n\n

مع العوامل < و > كل شيء يعمل بشكل ممتاز. يقوم JavaScript بتحويل كائنات Date إلى أرقام (ملي ثانية) ومقارنتها. لكن العامل == (والصارم ===) يتصرف بشكل مختلف. فهو يقارن المراجع إلى الكائنات، وليس قيمها. تاريخان مختلفان هما كائنان مختلفان، لذلك سيعيد == دائمًا false، حتى لو تطابقت التواريخ حتى الملي ثانية.

\n\n

هذا هو الفخ الأول. ومن هنا الخلاصة: لا تستخدم أبدًا == أو === لمقارنة التواريخ. استخدم فقط <، >، <=، >= أو الطرق الخاصة.

\n\n

طريقة getTime(): المعيار الذهبي لمقارنة التواريخ

\n\n

الطريقة الأكثر موثوقية وكفاءة هي استخدام طريقة getTime(). فهي تعيد عدد الملي ثانية المنقضية منذ 1 يناير 1970 (عصر Unix). والأرقام، يعرف JavaScript كيفية مقارنتها بشكل ممتاز:

\n\n
let date1 = new Date('2024-03-15T10:00:00');\nlet date2 = new Date('2024-03-15T10:00:00');\nlet date3 = new Date('2024-03-20T10:00:00');\n\nconsole.log(date1.getTime() === date2.getTime()); // true\nconsole.log(date1.getTime() < date3.getTime());   // true\nconsole.log(date1.getTime() > date3.getTime());   // false\n
\n\n

لماذا هذا فعال؟ لأن getTime() هي عملية خفيفة جدًا. إنها ببساطة تعيد القيمة الرقمية المخزنة بالفعل داخل كائن Date. لا تحليل، ولا حسابات إضافية. مجرد رقم.

\n\n

دعنا نقيس الأداء. إليك اختبار صغير في وحدة تحكم المتصفح:

\n\n
let date1 = new Date('2024-01-01');\nlet date2 = new Date('2024-12-31');\n\nconsole.time('getTime');\nfor (let i = 0; i < 1000000; i++) {\n    date1.getTime() < date2.getTime();\n}\nconsole.timeEnd('getTime');\n// النتيجة: ~5-10 ملي ثانية في المتصفحات الحديثة\n
\n\n

مليون مقارنة في 10 ملي ثانية - هذه نتيجة ممتازة. للمقارنة، قد تكون الطرق البديلة أبطأ بمقدار 2-3 مرات.

\n\n

مقارنة التواريخ باستخدام valueOf()

\n\n

طريقة valueOf() تفعل نفس الشيء الذي تفعله getTime() - تعيد التمثيل الرقمي للتاريخ. لكن هناك فارق بسيط: عند استخدام عوامل المقارنة (<، >، إلخ)، يقوم JavaScript باستدعاء valueOf() ضمنيًا لكائنات Date. أي أن هذا الكود:

\n\n
let date1 = new Date('2024-03-15');\nlet date2 = new Date('2024-03-20');\nconsole.log(date1 < date2);\n
\n\n

في الواقع يعمل كالتالي:

\n\n
console.log(date1.valueOf() < date2.valueOf());\n
\n\n

لذلك، للمقارنات البسيطة باستخدام < و >، يمكن استخدام كائنات Date مباشرة. لكن للمساواة الدقيقة (===)، لن يعمل هذا، وهنا لا غنى عن getTime() أو va

المدونات

توصيات الكتب