العمل المتقدم مع التواريخ والوقت في TypeScript: الأساليب والأمثلة

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

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

ابدأ الدورة

العمل المتقدم مع التواريخ والوقت في TypeScript: من التصنيف إلى العمليات المعقدة

\n\n

العمل مع التواريخ والوقت - واحدة من أكثر المهام شيوعًا وفي نفس الوقت خادعة في تطوير الويب. على المستوى المتقدم، لم يعد الاستخدام البسيط لـ new Date() كافيًا. يوفر TypeScript نظام أنواع قويًا، وتتيح المكتبات الحديثة (Luxon، Date-fns) كتابة كود آمن وقابل للتنبؤ وفعال. في هذه المقالة، سنستعرض التقنيات المتقدمة: التصنيف الصارم، العمل مع المناطق الزمنية، التنسيق والتحليل المعقد، بالإضافة إلى إنشاء أدوات مساعدة خاصة بنا.

\n\n

1. التصنيف الصارم للتواريخ: الأنواع المخصصة والأنواع الموسومة (Branded Types)

\n\n

النوع Date في TypeScript لا يحمي من تمرير قيمة غير صحيحة. على سبيل المثال، دالة تتوقع تاريخ ميلاد قد تحصل على الطابع الزمني الحالي. الحل هو استخدام الأنواع الموسومة (Branded Types) أو التصنيف الاسمي (Nominal Typing).

\n\n
// نوع موسوم لتاريخ الميلاد\ntype BirthDate = Date & { __brand: 'BirthDate' };\n\nfunction createBirthDate(date: Date): BirthDate {\n  // التحقق: يجب ألا يكون التاريخ في المستقبل\n  if (date.getTime() > Date.now()) {\n    throw new Error('تاريخ الميلاد لا يمكن أن يكون في المستقبل');\n  }\n  return date as BirthDate;\n}\n\nfunction calculateAge(birthDate: BirthDate): number {\n  const diff = Date.now() - birthDate.getTime();\n  return Math.floor(diff / (1000 * 60 * 60 * 24 * 365.25));\n}\n\n// الاستخدام\nconst rawDate = new Date('1990-05-15');\nconst birth = createBirthDate(rawDate);\nconsole.log(calculateAge(birth)); // صحيح\n\n// خطأ: الوسيطة من النوع 'Date' لا يمكن تعيينها للمعامل من النوع 'BirthDate'\n// console.log(calculateAge(new Date())); \n
\n\n

يضمن هذا الأسلوب أن الدالة calculateAge تستقبل فقط تاريخ ميلاد تم التحقق منه. بالنسبة للسيناريوهات الأكثر تعقيدًا، يمكن إنشاء أنواع للطوابع الزمنية (UnixTimestamp)، والفترات الزمنية (TimeInterval)، وما إلى ذلك.

\n\n

2. التنسيق والتحليل المتقدم باستخدام Intl.DateTimeFormat

\n\n

الكائن المدمج Intl.DateTimeFormat يسمح بتنسيق التواريخ بمرونة دون الحاجة لمكتبات خارجية. على المستوى المتقدم، يمكننا إنشاء أدوات تنسيق قابلة لإعادة الاستخدام ومعالجة الإعدادات المحلية المعقدة.

\n\n
// إنشاء أداة تنسيق مع خيارات\nconst formatter = new Intl.DateTimeFormat('ar-SA', {\n  year: 'numeric',\n  month: 'long',\n  day: 'numeric',\n  weekday: 'long',\n  hour: '2-digit',\n  minute: '2-digit',\n  timeZone: 'Asia/Riyadh',\n});\n\n// التنسيق\nconsole.log(formatter.format(new Date())); \n// "الجمعة، 25 أكتوبر 2024 م، 14:30"\n\n// التحليل (أداة مساعدة مخصصة)\nfunction parseLocalizedDate(dateStr: string, locale: string): Date | null {\n  const parts = dateStr.match(/(\\d{4})-(\\d{2})-(\\d{2})/);\n  if (!parts) return null;\n  \n  const [, year, month, day] = parts;\n  return new Date(parseInt(year), parseInt(month) - 1, parseInt(day));\n}\n
\n\n

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

\n\n

3. العمل مع المناطق الزمنية ومكتبة Luxon

\n\n

الكائن المدمج Date يتعامل بشكل سيء مع المناطق الزمنية. Luxon هي مكتبة حديثة من منشئ Moment.js، وتتكامل بشكل مثالي مع TypeScript.

\n\n
import { DateTime, Settings } from 'luxon';\n\n// تعيين المنطقة الزمنية الافتراضية\nSettings.defaultZone = 'Asia/Riyadh';\n\n// إنشاء تاريخ مع تحديد المنطقة الزمنية صراحة\nconst meeting = DateTime.fromISO('2024-11-01T15:00:00', { zone: 'America/New_York' });\nconsole.log(meeting.toISO()); // 2024-11-01T15:00:00.000-04:00\n\n// التحويل إلى منطقة زمنية أخرى\nconst riyadhTime = meeting.setZone('Asia/Riyadh');\nconsole.log(riyadhTime.toFormat('dd.MM.yyyy HH:mm')); // 01.11.2024 22:00\n\n// العمل مع الفترات الزمنية\nconst start = DateTi                

المدونات

توصيات الكتب