استخدم مساعدك المفضل للملخص واستخدم هذه الصفحة والموفر AI الذي تريده
تمت ترجمة محتوى هذه الصفحة باستخدام الذكاء الاصطناعي.
اعرض آخر نسخة المحتوى الأصلي باللغة الإنكليزيةإذا كان لديك فكرة لتحسين هذه الوثيقة، فلا تتردد في المساهمة من خلال تقديم طلب سحب على GitHub.
رابط GitHub للتوثيقنسخ الـ Markdown من المستند إلى الحافظة
تنسيق التواريخ والأرقام حسب اللغة باستخدام Intl
ترجمة النصوص هي النصف المرئي فقط من التدويل (i18n). أما النصف الآخر الذي يولد تقارير الأخطاء باستمرار فهو التنسيق: مستخدم ألماني يرى 1,234.56 بدلاً من 1.234,56، أو مستخدم ياباني يرى 08/02/2026 ويفهم أنه شهر أغسطس، أو تاريخ يتم عرضه بشكل مختلف بين الخادم والمتصفح فيؤدي إلى تعطل الصفحة بسبب عدم تطابق الهيدرة (Hydration mismatch) في React.
لا شيء من هذا يتطلب تثبيت مكتبة خارجية. واجهة Intl البرمجية القياسية مدمجة بالفعل في كل بيئة تشغيل حديثة.
جدول المحتويات
ابدأ بحذف دوال مساعدة التواريخ المكتوبة يدوياً
تحتوي معظم المشاريع تقريباً على دالة formatDate كُتبت قبل أن يفكر أي شخص في دعم اللغات المتعددة. وهي تثبت ترتيباً فجائياً، وفاصلاً محدداً، وغالباً أسماء أشهر باللغة الإنجليزية.
نسخ الكود إلى الحافظة
تحل Intl.DateTimeFormat محلها بالكامل وتضمن صحة التنسيق في كل لغة:
نسخ الكود إلى الحافظة
ينطبق الأمر ذاته على الأرقام. استدعاء toFixed(2) ينتج 1234.56 في كل مكان، وهو أمر خاطئ في معظم الدول الأوروبية.
ما تغطيه واجهة Intl
افتح الجدول في نافذة منبثقة لعرض جميع محتويات البيانات بوضوح
| الواجهة البرمجية | استخداماتها |
|---|---|
Intl.DateTimeFormat | التواريخ والأوقات مع إعدادات جاهزة مثل dateStyle و timeStyle |
Intl.NumberFormat | الأرقام العشرية، العملات، النسب المئوية، الوحدات، والترميز المختصر |
Intl.RelativeTimeFormat | "منذ 3 أيام"، "خلال ساعتين" |
Intl.ListFormat | دمج القوائم مثل "أ، ب، وج" |
Intl.PluralRules | تحديد فئة الجمع المناسبة للرقم |
Intl.Collator | الترتيب الهجائي السليم للنصوص وفق قواعد اللغة |
تعتبر Intl.Collator من أكثر الأدوات التي يغفل عنها المطورون. ترتيب النصوص عبر array.sort() العادية يعتمد على ترتيب محارف يونيكود، مما يضع الحروف المشكولة بعد حرف z ويخل بترتيب الحروف الخاصة. عند ترتيب قوائم يراها المستخدم، استخدم دائماً أداة collator.
نسخ الكود إلى الحافظة
تفضيل الإعدادات الجاهزة على الخيارات المصنوعة يدوياً
تتيح خيارات dateStyle و timeStyle للغة نفسها تحديد الترتيب المنطقي والفواصل المناسبة. بينما يمنحك تحديد year و month و day يدوياً تحكماً نادراً ما يكون مرغوباً، لأن الترتيب الصحيح يختلف باختلاف الثقافات، وتنقض بذلك بيانات CLDR بافتراضات غير دقيقة.
نسخ الكود إلى الحافظة
لا تلجأ لتحديد المكونات بشكل صريح إلا إذا كانت هناك متطلبات تصميمية تلزمك بعرض ثابت ومحدد، كأعمدة الجداول الضيقة.
إنشاء كائنات التنسيق عملية مكلفة برمجياً
هذه هي نقطة الأداء الجوهرية. يتطلب بناء كائن Intl.NumberFormat تحميل بيانات لغوية ضخمة، وهي عملية تفوق بمراحل استدعاء .format() اللاحق. وتكرار إنشائها داخل حلقة تكرار على ألف عنصر يسبب بطئاً ملحوظاً.
نسخ الكود إلى الحافظة
تنطوي دوال toLocaleDateString() و toLocaleString() على نفس المشكلة الخفية: كل استدعاء يبني منسقاً جديداً داخلياً. وهي مناسبة لقيمة واحدة فقط، وغير صالحة للقوائم.
قم بتخزينها مؤقتاً بالاعتماد على دمج كود اللغة والخيارات:
نسخ الكود إلى الحافظة
خطأ المنطقة الزمنية الذي لا يظهر إلا في بيئة الإنتاج
هذه المشكلة تستنزف ساعات طويلة من وقت المطورين. يقوم الخادم بتصيير التاريخ عبر SSR، ثم يستلمه المتصفح لعمل الهيدرة، فيلقي React خطأ عدم تطابق الهيدرة لأن النص المُولد من الخادم اختلف عن المتصفح.
السبب هو أن Intl.DateTimeFormat تستخدم المنطقة الزمنية لجهاز التشغيل إذا لم يتم تحديدها بوضوح. خادم الإنتاج يعمل بتوقيت UTC، بينما حاسوب التطوير يعمل بتوقيت محلي مختلف. لذا يظل الخطأ خفياً محلياً ولا ينفجر إلا في الإنتاج.
نسخ الكود إلى الحافظة
ثلاثة حلول عملية:
- تثبيت المنطقة الزمنية على الخادم وتمريرها صراحة. حل حاسم ومستقر، لكن يرى الجميع توقيت UTC.
- التصيير على العميل فقط، مع ترك نص بديل محايد في الخادم. دقيق لكل مستخدم ولكنه قد يسبب وميضاً بصرياً سريعاً.
- تخزين المنطقة الزمنية للمستخدم وتمريرها في الخادم والعميل معاً. الخيار الأمثل ولكن يتطلب تجهيزاً برمجياً إضافياً.
أياً كان اختيارك، حدد خاصية timeZone دائماً وبشكل صريح لأي تاريخ يتم تصييره في الخادم والعميل معاً. فالتاريخ بدون منطقة زمنية هو تاريخ يحمل قيمتين مختلفتين.
العملة تحتاج إلى كود عملة، وليس إلى مجرد لغة
اللغة والعملة مفهومان منفصلان. تحديد fr-FR لا يعني حتماً التعامل باليورو: فقد يطالع مستخدم فرنسي فاتورة بالدولار الأمريكي.
نسخ الكود إلى الحافظة
تتحكم اللغة في الفواصل، وتجميع الأرقام، وموضع رمز العملة. بينما تأتي العملة نفسها من بيانات المعاملة. استنتاج العملة من كود اللغة خطأ محاسبي مباشر.
انتبه أيضاً لخيار currencyDisplay. في الواجهات التي تجتمع فيها عدة عملات تشترك برمز الدولار ($)، فإن قيمة "code" تزيل أي لبس بين الدولار الأمريكي والكندي والأسترالي.
الوقت النسبي أكثر وضوحاً من التوقيت المطلق
بالنسبة للأحداث الأخيرة، فإن "منذ ساعتين" أسهل في القراءة من الطابع الزمني الثابت، وتتولى Intl.RelativeTimeFormat توطين ذلك بدقة.
نسخ الكود إلى الحافظة
خاصية numeric: "auto" هي التي تنتج "أمس" بدلاً من التعبير الرقمي الجاف "قبل يوم واحد".
ما تقدمه مكتبة Intlayer
تغلف Intlayer هذه الواجهات في دوال مساعدة ذاتية التخزين المؤقت، لتغنيك عن إدارة خرائط الذاكرة يدوياً، وتطبق اللغة الحالية تلقائياً دون الحاجة لتمريرها في كل موضع استدعاء.
نسخ الكود إلى الحافظة
تقبل الدالة date() الإعدادات الجاهزة ("short", "long", "dateOnly", "timeOnly", "full"). وتوجد أدوات مقابلة لـ React و Vue على هيئة hooks و composables تستخرج اللغة النشطة مباشرة من السياق.
هذه مجرد طبقة تخزين مؤقت ومطابقة للغة مبنية فوق الواجهة القياسية للمنصة، أما سلوك التنسيق الفعلي فهو نابع من Intl. راجع كافة التفاصيل في توثيق أدوات التنسيق.
أخطاء شائعة
- استدعاء
toLocaleDateString()دون تمرير لغة. يعتمد على لغة النظام المضيف، والتي تتغير في الخوادم بحسب ضبط الحاوية. - التنسيق داخل الحلقات التكرارية دون تخزين مؤقت. إنشاء الكائن يستهلك معظم وقت المعالجة.
- تجاهل
timeZoneفي التواريخ المشتركة بين الخادم والعميل. يسبب أخطاء هيدرة يستحيل إعادة إنتاجها محلياً. - تخمين العملة من اللغة.
fr-FRلا تعني اليورو تلقائياً. - استخدام
sort()العادية على نصوص الواجهة. استعن دائماً بـIntl.Collator. - كتابة أسماء الشهور أو الأيام بشكل ثابت في الكود. جميعها مسجلة وموثوقة بالفعل في CLDR لكل لغة.
- الإبقاء على
numeric: "always"في الوقت النسبي. يؤدي لظهور "قبل يوم واحد" بدلاً من "أمس".
للمزيد من القراءة
التعليقات
لا توجد تعليقات بعد. كن أول من يشارك أفكاره.
