تنسيق التاريخ في JavaScript: ليس مجرد "ربط السلاسل النصية"
\n\nسؤال "How do I format a date in JavaScript?" هو أحد أكثر الأسئلة شيوعًا على Stack Overflow. وليس من دون سبب. كل مطور واجه مرة واحدة على الأقل موقفًا يحتاج فيه إلى عرض التاريخ ليس بالتنسيق القياسي "Fri Feb 14 2025 12:00:00 GMT+0300"، ولكن بشكل جميل: "14 فبراير 2025" أو "2025-02-14". قد يبدو الأمر بسيطًا؟ لكن هناك الكثير من المزالق ومشاكل الأداء هنا.
\n\nفي هذه المقالة، سنستعرض جميع طرق تنسيق التواريخ في JavaScript: من أبسطها إلى الأكثر كفاءة في الأداء. ستتعلم كيفية تجنب الأخطاء النموذجية وجعل الكود ليس فقط جميلًا، ولكن أيضًا سريعًا. هيا بنا!
\n\nلماذا الكائن Date الأصلي غير مريح إلى هذا الحد؟
\n\nالكائن المدمج Date في JavaScript هو، بعبارة ملطفة، "إرث الماضي". فهو لا يوفر طريقة مدمجة format() كما في Python أو PHP. بدلاً من ذلك، عليك تجميع التاريخ يدويًا باستخدام الدوال الجالبة (getters):
const date = new Date();\nconst day = String(date.getDate()).padStart(2, '0');\nconst month = String(date.getMonth() + 1).padStart(2, '0');\nconst year = date.getFullYear();\nconsole.log(`${year}-${month}-${day}`); // "2025-02-14"\n\nهذا يعمل، لكنه يبدو ضخمًا. وإذا كنت بحاجة أيضًا إلى توطين التاريخ (مثلًا إلى اللغة العربية)، فإن الكود يتضخم إلى أحجام غير لائقة. ولهذا السبب يبحث المطورون عن بدائل.
\n\nطريقة toLocaleDateString: بسيطة وسريعة
\n\nأسهل طريقة لتنسيق التاريخ في JavaScript هي استخدام طريقة toLocaleDateString(). فهي تقبل الإعدادات المحلية (locale) وكائنًا بالخيارات:
const date = new Date();\nconst options = { year: 'numeric', month: 'long', day: 'numeric' };\nconsole.log(date.toLocaleDateString('ar-SA', options)); // "١٤ فبراير ٢٠٢٥"\n\nهذه الطريقة تتكيف تلقائيًا مع الإعدادات المحلية. هل تريد "February 14, 2025"؟ فقط قم بتغيير الإعدادات المحلية إلى 'en-US'.
المزايا:
\n- \n
- سهولة الاستخدام. \n
- توطين مدمج. \n
- الكود يُقرأ كلغة طبيعية. \n
العيوب:
\n- \n
- الأداء: كل استدعاء لـ
toLocaleDateString()ينشئ كائن تنسيق جديد. في حلقة من 1000 عنصر، قد يكون هذا ملحوظًا. \n - تحكم محدود في التنسيق (لا يمكن، على سبيل المثال، عرض "14.02.2025" بدون السنة). \n
Intl.DateTimeFormat: قوي وفعال
\n\nللحصول على تحكم أكثر دقة وتحسين، استخدم Intl.DateTimeFormat. هذا كائن يمكن إنشاؤه مرة واحدة واستخدامه بشكل متكرر:
const formatter = new Intl.DateTimeFormat('ar-SA', {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit'\n});\n\nconst date1 = new Date();\nconst date2 = new Date('2024-12-25');\nconsole.log(formatter.format(date1)); // "١٤/٠٢/٢٠٢٥"\nconsole.log(formatter.format(date2)); // "٢٥/١٢/٢٠٢٤"\n\nلماذا هذا أسرع؟ لأنه يتم إنشاء كائن التنسيق مرة واحدة، وليس في كل استدعاء. في اختبارات الأداء، يكون Intl.DateTimeFormat أسرع بمقدار 5-10 مرات من toLocaleDateString() في الحلقات.
علاوة على ذلك، يدعم Intl.DateTimeFormat خيارات إضافية مثل weekday و hour و minute و second وحتى timeZone:
const formatter = new Intl.DateTimeFormat('en-US', {\n weekday: 'long',\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n});\nconsole.log(formatter.format(new Date())); // "Friday, Feb 14, 2025, 12:00 PM"\n\nسؤال صعب: ماذا لو كنت بحاجة إلى عرض التاريخ بتنسيق "2025-02-14" بدون توطين؟ Intl.DateTimeFormat لا يمكنه عرض الساعات والدقائق والثواني بشكل منفصل، ولكن بالنسبة للتواريخ البسيطة فهذا