مقدمة: لماذا الوقت هو صداع كل مطور
\n\nهل سبق لك أن واجهت خطأ حيث يرى مستخدم من فلاديفوستوك تاريخ اليوم التالي، بينما التقويم يظهر اليوم؟ أو عندما يرسل خادم في AWS us-east-1 وقتًا يفسره عميلك في كالينينغراد على أنه الساعة 3 صباحًا؟ مرحبًا بك في عالم المناطق الزمنية في TypeScript.
\n\nالمشكلة هي أن JavaScript (و TypeScript كإضافة له) صُمم في الأصل للمتصفحات. كائن Date المدمج هو في الأساس طابع زمني مقنع في UTC. إنه لا يعمل مع المناطق الزمنية بالطريقة التي نحتاجها. وإذا كنت تكتب تطبيقًا جادًا في TypeScript - سواء كان لوحة تحكم في React، أو خادمًا في Node.js، أو تطبيق جوال في React Native - فلا يمكنك الاستغناء عن العمل الجيد مع التايم زون.
في هذه المقالة، سأريكم كيفية ترويض الوقت. سنفهم المفاهيم الأساسية، ونتعلم استخدام المكتبات الحديثة، ونتجنب الأخطاء النموذجية. هيا بنا!
\n\nما تحتاج معرفته عن المناطق الزمنية قبل كتابة الكود
\n\nقبل الغوص في TypeScript، دعنا نضع النقاط على الحروف. يوجد في العالم نوعان من الوقت: الوقت المطلق (UTC) والوقت المحلي (ما يراه المستخدم).
\n\n- \n
- UTC (التوقيت العالمي المنسق) - هو المعيار. يجب على الخوادم وقواعد البيانات وAPI تخزين الوقت بصيغة UTC. هذه قاعدة حديدية. \n
- قاعدة بيانات المناطق الزمنية IANA - هي قاموس للمناطق الزمنية مثل
Europe/Moscow،Asia/Vladivostok. هذه السلاسل، وليس الاختصارات مثل MSK أو PST، هي ما يجب استخدامه في الكود. \n - Offset (الإزاحة) - هو الفرق عن UTC، مثل +03:00. لكن تذكر: الإزاحة يمكن أن تتغير بسبب التوقيت الصيفي (DST). لذلك تخزين offset بدلاً من منطقة IANA فكرة سيئة. \n
\n\n\nالقاعدة الذهبية: نخزن في UTC، ونحول على العميل، ونستخدم سلاسل IANA لتحديد المناطق.
\n
لماذا لا يكفي Date الأصلي: الألم والمعاناة
\n\nدعنا نواجه الحقيقة: new Date() في TypeScript يشبه سكينًا سويسريًا كسرت شفرته. إنه يعرف فقط تخزين طابع زمني وعرضه في المنطقة المحلية للمتصفح أو الخادم. حاول أن تفعل شيئًا أكثر تعقيدًا:
// مثال سيء: محاولة العمل مع المناطق باستخدام الوسائل الأصلية\nconst date = new Date('2024-03-10T12:00:00');\nconsole.log(date.toLocaleString('ar-SA', { timeZone: 'Europe/Moscow' }));\n// سيطبع: "10/03/2024, 03:00:00 م" - لكن هذه مجرد سلسلة، وليس كائنًا!\n\n// وماذا لو احتجت الحصول على Date في منطقة أخرى؟\n// أوبس... JS الأصلي لا يعرف كيفية إنشاء Date مرتبط بمنطقة.\n\n\nالمشكلة هي أن Date يخزن دائمًا الوقت في UTC. جميع الطرق مثل getHours() تقوم ببساطة بتحويل UTC إلى الوقت المحلي للمتصفح. لا يمكنك الحصول على كائن Date "يعتقد" أنه في نيويورك.
لهذا السبب نستخدم المكتبات. في نظام TypeScript البيئي، هناك مرشحان رئيسيان: Luxon و date-fns-tz.
\n\nLuxon: المدفعية الثقيلة للعمل مع التواريخ
\n\nLuxon هي مكتبة حديثة من مبتكر Moment.js (الذي أصبح مهملاً). تمت كتابتها من الصفر، وتستخدم Intl.DateTimeFormat الأصلي، وهي مكتوبة بشكل ممتاز لـ TypeScript.
تثبيت Luxon
\n\nnpm install luxon\nnpm install --save-dev @types/luxon\n\n\nإنشاء تاريخ في منطقة زمنية محددة
\n\nimport { DateTime } from 'luxon';\n\n// إنشاء تاريخ في منطقة Europe/Moscow\nconst moscowTime = DateTime.fromObject(\n { year: 2024, month: 3, day: 10, hour: 12 },\n { zone: 'Europe/Moscow' }\n);\nconsole.log(moscowTime.toISO());\n// الإخراج: "2024-03-10T12:00:00.000+03:00"\n\n// التحويل إلى منطقة أخرى\nconst nyTime = moscowTime.setZone('America/New_York');\nconsole.log(nyTime.toISO());\n// الإخراج: "2024-03-10T05:00:00.00