المناطق الزمنية في TypeScript: كيف لا تفقد صوابك مع التواريخ

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

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

ابدأ الدورة

مقدمة: لماذا الوقت هو صداع كل مطور

\n\n

هل سبق لك أن واجهت خطأ حيث يرى مستخدم من فلاديفوستوك تاريخ اليوم التالي، بينما التقويم يظهر اليوم؟ أو عندما يرسل خادم في AWS us-east-1 وقتًا يفسره عميلك في كالينينغراد على أنه الساعة 3 صباحًا؟ مرحبًا بك في عالم المناطق الزمنية في TypeScript.

\n\n

المشكلة هي أن JavaScript (و TypeScript كإضافة له) صُمم في الأصل للمتصفحات. كائن Date المدمج هو في الأساس طابع زمني مقنع في UTC. إنه لا يعمل مع المناطق الزمنية بالطريقة التي نحتاجها. وإذا كنت تكتب تطبيقًا جادًا في TypeScript - سواء كان لوحة تحكم في React، أو خادمًا في Node.js، أو تطبيق جوال في React Native - فلا يمكنك الاستغناء عن العمل الجيد مع التايم زون.

\n\n

في هذه المقالة، سأريكم كيفية ترويض الوقت. سنفهم المفاهيم الأساسية، ونتعلم استخدام المكتبات الحديثة، ونتجنب الأخطاء النموذجية. هيا بنا!

\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
\n\n

لماذا لا يكفي Date الأصلي: الألم والمعاناة

\n\n

دعنا نواجه الحقيقة: new Date() في TypeScript يشبه سكينًا سويسريًا كسرت شفرته. إنه يعرف فقط تخزين طابع زمني وعرضه في المنطقة المحلية للمتصفح أو الخادم. حاول أن تفعل شيئًا أكثر تعقيدًا:

\n\n
// مثال سيء: محاولة العمل مع المناطق باستخدام الوسائل الأصلية\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 "يعتقد" أنه في نيويورك.

\n\n

لهذا السبب نستخدم المكتبات. في نظام TypeScript البيئي، هناك مرشحان رئيسيان: Luxon و date-fns-tz.

\n\n

Luxon: المدفعية الثقيلة للعمل مع التواريخ

\n\n

Luxon هي مكتبة حديثة من مبتكر Moment.js (الذي أصبح مهملاً). تمت كتابتها من الصفر، وتستخدم Intl.DateTimeFormat الأصلي، وهي مكتوبة بشكل ممتاز لـ TypeScript.

\n\n

تثبيت Luxon

\n\n
npm install luxon\nnpm install --save-dev @types/luxon\n
\n\n

إنشاء تاريخ في منطقة زمنية محددة

\n\n
import { 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                

المدونات

توصيات الكتب