التواريخ والأرقام والعملات والمناطق الزمنية
للتاريخ أو العدد أو المبلغ المالي قيمة واحدة وطرق عرض كثيرة. فاللحظة المخزنة 2026-03-04T21:30:00Z هي 4 مارس الساعة 4:30 مساءً لمستخدم في نيويورك، و5 مارس الساعة 00:30 لمستخدم في الرياض. والعدد 1234567.89 يُعرض 1,234,567.89 في en-US و1.234.567,89 في de-DE و12,34,567.89 في hi-IN و١٬٢٣٤٬٥٦٧٫٨٩ في ar-SA. والإعداد المحلي (Locale)، وهو لغة مع منطقة يُكتب وسماً من BCP 47 مثل ar-SA أو hi-IN، يحدد التقويم والأرقام والفواصل وأسماء الأشهر ورمز العملة؛ أما المنطقة الزمنية (Time Zone) فتحدد في أي يوم وأي ساعة تقع اللحظة.
واختبار هذا المجال يعني الفصل بين القيمة وطريقة عرضها. فلكل حقل يعرض قيمة من هذا النوع أو يقبلها أو يخزنها أو يقارنها، تفحص ما يُخزَّن (صيغة قانونية واحدة، Canonical form)، وما يعرضه كل إعداد محلي (تنتجه مكتبة تنسيق لا قوالب نصية)، وما يحدث للقيمة التي يكتبها المستخدم بصيغته هو. وقد تناول درس ترميز الأحرف كيف يبقى النص سليماً في رحلته عبر النظام؛ أما هذا الدرس فيتناول القيم التي يعتمد معناها على مكان المستخدم.
لماذا يهم
تكلّف هذه العيوب المال والثقة مباشرةً. فتاريخ يُحلَّل بترتيب خاطئ يحجز رحلة في 3 أبريل بدلاً من 4 مارس. ومبلغ يُحلَّل بفاصلة عشرية خاطئة يحوّل 1.500 إلى ريال ونصف أو إلى ألف وخمسمئة. وتقرير مجمَّع حسب يوم UTC يضع طلباً سُجّل الساعة 00:30 بتوقيت الرياض في اليوم السابق، فلا تتطابق المجاميع اليومية مع البنك أبداً. وضريبة قيمة مضافة تُقرَّب لكل سطر بينما تنص القاعدة على تقريبها على الإجمالي تجعل الفاتورة تختلف عن السجلات المحاسبية بهللة واحدة (جزء من مئة من الريال)، ثم على أحدٍ أن يبحث عن هذا الفرق ويفسّره.
وصعوبة الأمر على المختبِر أن هذه العيوب غير مرئية في بيئته هو. فمن الرياض بمتصفح إنجليزي ترى أرقاماً غربية ومنطقة زمنية +03:00 بلا توقيت صيفي (Daylight Saving Time) وتقويماً واحداً. أما المستخدم في جدة بالأرقام العربية المشرقية (Arabic-Indic digits) والتقويم الهجري، والمستخدم في كولكاتا عند +05:30، والمستخدم في لندن الذي تتغيّر ساعته في مارس، فيواجهون إخفاقات لم تظهر لك قط. لذلك يجب اختيار الإعداد المحلي والمنطقة الزمنية عمداً كشروط اختبار، مثل المتصفح أو الجهاز.
قيمة واحدة وطرق عرض كثيرة
لكل قيمة حساسة للإعداد المحلي صيغة قانونية ينبغي للمنتج أن يخزنها وينقلها: اللحظة الزمنية بصيغة ISO 8601 (أو RFC 3339، وهي صيغة مقيَّدة منها لبروتوكولات الإنترنت) بتوقيت UTC أو بفارق صريح، 2026-03-04T21:30:00Z أو 2026-03-05T00:30:00+03:00؛ والعدد كسر عشري بسيط بنقطة، 1234567.89؛ والمبلغ كسر عشري مع رمز عملة من ISO 4217، {"amount": "42.95", "currency": "SAR"}. أما طريقة العرض فتُنتَج عند الطرف بمكتبة تنسيق مبنية على بيانات مشروع CLDR من يونيكود: واجهة Intl في المتصفحات وNode.js، والواجهات المبنية على ICU (International Components for Unicode) في Android وiOS.
والإعداد المحلي وسم لغة من BCP 47: en-US وen-GB وar-SA وhi-IN. فالجزء اللغوي يختار الكلمات والأسماء، والجزء الإقليمي يعدّل الافتراضات للأرقام والفواصل والتقويم وأول أيام الأسبوع. أما العملة فليست منها: فهي ترافق المبلغ رمزاً من ISO 4217. وتتجاوز امتدادات يونيكود الافتراضات صراحةً: ar-SA-u-nu-latn يطلب الأرقام الغربية، وar-SA-u-ca-islamic-umalqura تقويم أم القرى، وhi-IN-u-nu-deva أرقام الديفاناغاري. ويوضح الشكل كم تتباعد طرق عرض تاريخ واحد وعدد واحد ومبلغ واحد بينما لا تتغير القيم المخزنة إطلاقاً.
Intl لسبعة وسوم إعداد محلي: يتغيّر ترتيب الأجزاء والأرقام والفواصل واسم الشهر والتقويم وموضع العملة بينما تبقى القيم المخزنة كما هي.| وسم الإعداد المحلي | التاريخ المختصرdateStyle: short | التاريخ المطوّلdateStyle: long | العددstyle: decimal | المبلغstyle: currency |
|---|---|---|---|---|
| القيمة المخزنةتاريخ ISO 8601، وكسر عشري بسيط، ومبلغ مع رمزه من ISO 4217 | 2026-03-04 | 2026-03-04 | 1234567.89 | 1500.00 SAR |
en-USالإنجليزية، الولايات المتحدة: الشهر قبل اليوم | 3/4/26 | March 4, 2026 | 1,234,567.89 | SAR 1,500.00 |
en-GBالإنجليزية، المملكة المتحدة: اليوم قبل الشهر | 04/03/2026 | 4 March 2026 | 1,234,567.89 | SAR 1,500.00 |
de-DEالألمانية، ألمانيا: الفاصلتان متبادلتان ورمز ISO بعد المبلغ | 04.03.26 | 4. März 2026 | 1.234.567,89 | 1.500,00 SAR |
hi-INالهندية، الهند: اسم الشهر بالديفاناغاري وتجميع اللاك والكرور | 4/3/26 | 4 मार्च 2026 | 12,34,567.89 | SAR 1,500.00 |
ar-SAالعربية، السعودية: أرقام عربية مشرقية وفواصل عربية والرمز بعد المبلغ | ٤/٣/٢٠٢٦ | ٤ مارس ٢٠٢٦ | ١٬٢٣٤٬٥٦٧٫٨٩ | ١٬٥٠٠٫٠٠ ر.س. |
ar-JOالعربية، الأردن: الأرقام والمبلغ نفسها واسم الشهر الشامي | ٤/٣/٢٠٢٦ | ٤ آذار ٢٠٢٦ | ١٬٢٣٤٬٥٦٧٫٨٩ | ١٬٥٠٠٫٠٠ ر.س. |
ar-SA-u-ca-islamic-umalquraالعربية، السعودية، مع طلب تقويم أم القرى: تاريخ آخر والعدد نفسه | ١٥/٩/١٤٤٧ هـ | ١٥ رمضان ١٤٤٧ هـ | ١٬٢٣٤٬٥٦٧٫٨٩ | ١٬٥٠٠٫٠٠ ر.س. |
- يُخزَّن مرة واحدة بالصيغة القانونية
- امتداد يونيكود يطلبه المنتج صراحةً
مخرجات Node.js 22 (ICU 78 وCLDR 48)؛ وقد تختلف بيئة تشغيل أو نسخة CLDR أخرى. وتحتفظ الخلايا العربية بعلامات الاتجاه غير المرئية (U+200F) والمسافات غير الفاصلة (U+00A0) التي يدخلها المنسِّق.
- المخزَّن: هل القيمة القانونية صحيحة وغير غامضة، مع فارقها أو منطقتها الزمنية ورمز عملتها؟
- المعروض: هل يعرضها كل إعداد محلي مدعوم عبر المكتبة، بالأرقام والفواصل والتقويم والرمز التي قرّرها المنتج؟
- المُدخَل: هل تُحلَّل القيمة المكتوبة بصيغة المستخدم بذلك الإعداد المحلي، وتُطبَّع أو تُرفض برسالة واضحة، ولا تُقرأ خطأً بصمت أبداً؟
التواريخ والتقاويم والمناطق الزمنية
لعرض التاريخ ثلاثة أبعاد مستقلة. ترتيب الأجزاء: 3/4/26 هو 4 مارس في en-US و04/03/2026 هو 4 مارس في en-GB، لذا تسمّي السلسلة 03/04/2026 يوماً مختلفاً في كل منهما. والأرقام والأسماء: الأرقام العربية المشرقية، وأسماء الأشهر المترجمة، وفي عربية الشام (ar-JO وar-SY) يُسمّى مارس «آذار» بينما تستخدم العربية في السعودية «مارس». والتقويم: في السعودية يسير تقويم أم القرى جنباً إلى جنب مع التقويم الميلادي، فيوم 4 مارس 2026 هو 15 رمضان 1447 هـ، والشهر الهجري 29 أو 30 يوماً، لذلك تختلف نهايات الأشهر بين التقويمين.
والمنطقة الزمنية ليست جزءاً من الإعداد المحلي: فهي تتبع المستخدم أو الجهاز أو الحساب. واللحظة نقطة واحدة في الزمن، لكن وقتها على الساعة بل ويومها في التقويم يعتمدان على المنطقة. فـAsia/Riyadh هي UTC+03:00 بلا توقيت صيفي، وAsia/Kolkata هي UTC+05:30، وAsia/Kathmandu هي UTC+05:45، أما Europe/London وAmerica/New_York فيغيّران فارقهما مرتين في السنة. خزّن اللحظات بتوقيت UTC أو بفارق صريح، وسمِّ المناطق بأسمائها في IANA لا بفارق، وحوّل للعرض فقط، واختبر اللحظات التي يتغيّر فيها اليوم.
- قيم الاختبار: آخر يوم في الشهر وفي السنة في التقويمين، و29 فبراير 2028، و23:59 و00:00 بمنطقة المستخدم، وأيام التغيير في منطقة تطبّق التوقيت الصيفي.
- القيم التي هي تاريخ فقط، مثل تاريخ الميلاد أو تاريخ الاستحقاق، ليست لها منطقة زمنية ويجب ألا تنزاح عندما يكون الخادم أو القارئ في مكان آخر.
- الطوابع الزمنية بالثواني وبالميلي ثانية تختلط: قيمة أصغر ألف مرة تقع في يناير 1970، وأكبر ألف مرة تقع في سنة بعيدة في المستقبل.
One instant, stored once: 2026-03-04T21:30:00Z
Zone (IANA) Offset Local wall-clock time Calendar day
UTC +00:00 2026-03-04 21:30 4 March
Europe/London +00:00 2026-03-04 21:30 4 March (BST from 29 March)
America/New_York -05:00 2026-03-04 16:30 4 March (EDT from 8 March)
Asia/Riyadh +03:00 2026-03-05 00:30 5 March
Asia/Kolkata +05:30 2026-03-05 03:00 5 March
Asia/Kathmandu +05:45 2026-03-05 03:15 5 March
A report grouped by "day" lists this order on 4 March in London
and on 5 March in Riyadh. Both are right; the report must name its zone.جرّبها: محوّل ISO 8601 جرّبها: محوّل الطوابع الزمنية جرّبها: مولّد بيانات اختبار التواريخ
الأعداد والأرقام والعملات
لعرض العدد نظام أرقام وفاصلتان: فـen-US يكتب 1,234,567.89، وde-DE 1.234.567,89، وfr-FR 1 234 567,89 بمسافة ضيقة غير فاصلة، وhi-IN 12,34,567.89 بالتجميع الهندي، حيث تتكوّن كل مجموعة بعد الخانات الثلاث الأولى من خانتين (اللاك الواحد 1,00,000 أي مئة ألف، والكرور الواحد 1,00,00,000 أي عشرة ملايين)، وar-SA ١٬٢٣٤٬٥٦٧٫٨٩ بالأرقام العربية المشرقية والفاصلتين العربيتين U+066C وU+066B. ولذلك تحمل السلسلة نفسها معانيَ مختلفة: 1.500 واحد ونصف في en-US وألف وخمسمئة في de-DE. ويجب تحليل المُدخل بالإعداد المحلي الذي كتب به المستخدم، وبيئات التشغيل لا تتفق في التعامل مع الأرقام العربية المشرقية: ففي JavaScript تعطي Number("٥٠٠") القيمة NaN، بينما تعيد int("٥٠٠") في Python العدد 500. لذلك على المنتج أن يقرر، وعلى المتطلب أن ينص، هل تُطبَّع هذه الأرقام إلى 0–9 أم تُرفض برسالة واضحة.
ويضيف المال العملة وقاعدة التقريب. فالمبلغ كسر عشري مع رمز من ISO 4217، ويحدد ISO 4217 أيضاً الوحدة الصغرى (Minor unit) لكل عملة، أي عدد المنازل العشرية: منزلتان للريال السعودي SAR وللروبية INR، ولا شيء للين JPY، وثلاث للدينار الكويتي KWD والبحريني BHD والأردني JOD وللريال العماني OMR، لذا «منزلتان عشريتان» ليست قاعدة عامة. والفاصلة العائمة الثنائية (Binary floating point) لا تستوعب معظم المبالغ العشرية بدقة: في JavaScript يعطي 0.1 + 0.2 القيمة 0.30000000000000004 ويعطي 3 * 12.45 القيمة 37.349999999999994. فمكان المبالغ أعداد صحيحة بالوحدات الصغرى أو نوع عشري، ويجب أن يذكر المتطلب أين يحدث التقريب وبأي قاعدة. ويأتي رمز العملة وموضعه من الإعداد المحلي لا من قالب: SAR 1,500.00 في en-US، و1.500,00 SAR في de-DE، و١٬٥٠٠٫٠٠ ر.س. في ar-SA، حيث تحمل السلسلة أيضاً علامتَي اتجاه من اليمين إلى اليسار (U+200F) في طرفيها ومسافة غير فاصلة قبل الرمز، ولهذا تفشل السلسلة المتوقعة المكتوبة يدوياً بينما تبدو الشاشة صحيحة. وعلى الشاشة تُبقي العلامتان نفسهما المبلغ ورمزه بترتيب من اليمين إلى اليسار حتى بجوار نص لاتيني أو محايد الاتجاه، فيظهر ر.س. على يسار الرقم مع أن الأرقام تأتي أولاً في السلسلة نفسها؛ ويشرح دليل اختبار واجهات اليمين إلى اليسار، وهو الخطوة التالية في خريطة التعلم، خوارزمية يونيكود ثنائية الاتجاه (Unicode Bidirectional Algorithm) التي تقف وراء ذلك.
- المعرِّفات ليست كميات: أرقام الهواتف وأرقام IBAN وأرقام الطلبات وأرقام الهوية لا تُجمَّع ولا تُقرَّب ولا تُعرض بأرقام محلية أبداً.
- استرداد بقيمة -42.95 يجب أن يُقرَّب تماماً كما قُرِّب المبلغ الذي يعكسه؛ وموضع علامة السالب وعلامة النسبة المئوية، والعلامات غير المرئية حولهما، يأتي من الإعداد المحلي أيضاً.
- لا تجمع أبداً مبالغ بعملات مختلفة؛ فإجمالي يجمع سطوراً بالريال SAR وأخرى بالروبية INR عيب في البيانات لا مسألة تنسيق.
Order: 3 x 12.45 SAR, VAT 15 %
Rule A, VAT on the subtotal: 37.35 x 0.15 = 5.6025 -> 5.60 total 42.95
Rule B, VAT per line: 12.45 x 0.15 = 1.8675 -> 1.87 x 3 = 5.61 total 42.96
Both are "15 % VAT rounded to 2 decimals". The requirement must name the rule,
and the test must use amounts on which the two rules differ.جرّبها: مولّد مجموعات الأرقام العشرية جرّبها: مولّد بيانات الاختبار العربية
مثال تطبيقي: طلب واحد وثلاثة مستخدمين
تعيد واجهة الطلبات السجل أدناه. ويفتح صفحة التأكيد ثلاثة أشخاص: نورة في جدة (ar-SA مع أرقام غربية اختارتها في إعدادات المنتج، والمنطقة Asia/Riyadh)، وبريا في كولكاتا (hi-IN وAsia/Kolkata)، وفريق المالية في لندن (en-GB وEurope/London). وكل قيمة متوقعة تُستخرج من السجل المخزَّن بالمكتبة نفسها التي يستخدمها المنتج، ولا تُكتب من الذاكرة أبداً.
- نورة: سُجّل الطلب في 5 مارس 2026 الساعة 00:30؛ الإجمالي
42.95 ر.س.بأرقام غربية لأن الإعداد يقول ذلك، والرمز في موضعه الذي يحدده منسِّق ar-SA، والسلسلة كلها صحيحة داخل فقرة من اليمين إلى اليسار. - بريا: سُجّل الطلب في 5 مارس 2026 الساعة 03:00؛ الإجمالي
SAR 42.95برمز ISO، لأن منسِّق hi-IN يعرض الريال بهذا الرمز والمنتج لا يحوّل العملات. - المالية: سُجّل الطلب في 4 مارس 2026 الساعة 21:30؛ الإجمالي
SAR 42.95. ويحتوي التقرير اليومي ليوم 4 مارس هذا الطلب، بينما تعرضه قائمة طلبات نورة تحت 5 مارس؛ وكلاهما صحيح، ويجب أن يذكر عنوان التقرير منطقته الزمنية. - عيوب تبحث عنها:
4/3/2026أو3/5/2026في صفحة نورة (يوم UTC، أو ترتيب en-US)، وضريبة5.61(مقرَّبة لكل سطر)، و٤٢٫٩٥مع أن الإعداد يقول أرقاماً غربية، وSAR42.95ملصوقة بقالب بحيث يرى كل إعداد محلي السلسلة نفسها، وإجمالي يتغيّر بعد أن تعيد الصفحة تحليل سلسلتها المنسَّقة.
{
"order_id": "ORD-2026-0042",
"placed_at": "2026-03-04T21:30:00Z",
"subtotal": "37.35",
"vat": "5.60",
"total": "42.95",
"currency": "SAR"
}أخطاء شائعة
- كتابة السلاسل المتوقعة يدوياً ثم الفشل بسبب الأحرف غير المرئية التي يدخلها المنسِّق (U+200F وU+00A0 وU+202F)، أو النجاح لأن الاختبار يحذف كل شيء بما فيه الفواصل المهمة.
- الإبلاغ عن «تاريخ خاطئ» وهو صحيح في منطقة المستخدم، أو قبول تاريخ خاطئ لأن أحداً لم يتحقق من المنطقة؛ سجّل اللحظة المخزنة والمنطقة والإعداد المحلي معاً.
- الاختبار من مكان واحد فقط: فالرياض عند +03:00 بلا توقيت صيفي لا تُظهر أبداً عيوب التوقيت الصيفي ونصف الساعة التي يصادفها المستخدمون في كولكاتا ولندن ونيويورك.
- قبول «منزلتان عشريتان مقرَّبتان» مواصفةً دون السؤال أين يحدث التقريب وبأي قاعدة، ثم حساب الإجماليات المتوقعة في جدول بيانات يقرِّب بطريقة مختلفة.
- توطين المعرِّفات: أرقام هواتف مجمَّعة كالمبالغ، وأرقام طلبات بالأرقام العربية المشرقية، ورقم IBAN بفواصل آلاف.
- افتراض ما ينتجه
ar-SA: فافتراضات الأرقام والتقويم تأتي من نسخة CLDR داخل كل بيئة تشغيل وقد تغيّرت عبر السنين، فقد يختلف المتصفح والخادم وتطبيق الجوال ما لم يطلبها المنتج صراحةً.
من منظور ضمان الجودة
يبدأ هذا العمل في الفريق الحقيقي أثناء مراجعة المتطلبات. فلكل حقل تاريخ أو عدد أو مبلغ تسأل كيف يُخزَّن، وكيف يُعرض في كل إعداد محلي مدعوم، وكيف يُحلَّل المُدخل، وتكتب الأجوبة في معايير القبول. اسأل المطورين أي مكتبة تنسيق وأي نسخة من CLDR أو ICU تشحنها كل بيئة تشغيل، واسأل مالك المنتج أي أرقام وأي تقويم يستخدمه المنتج لكل إعداد محلي وهل يستطيع المستخدم تغييرها، واسأل المالية أين تُقرَّب ضريبة القيمة المضافة. وتتحوّل الأجوبة إلى شروط اختبار، الإعداد المحلي × المنطقة الزمنية × بيئة التشغيل، تُختار كما تُختار المتصفحات في مصفوفة التوافق.
وأثناء التنفيذ، أنتج القيم المتوقعة بالمكتبة نفسها لا باليد، واحتفظ بمجموعة صغيرة من اللحظات والمبالغ التي تكشف الفروق: وقت بعد منتصف الليل في الرياض بقليل، وتاريخ في يوم تغيير التوقيت الصيفي، ومبلغ يختلف فيه تقريب السطر عن تقريب الإجمالي، وعدد مكتوب بالأرقام العربية المشرقية. وتقرير الخطأ الجيد هنا يحوي القيمة المخزنة الخام، ووسم الإعداد المحلي، ومعرِّف المنطقة الزمنية، ونسخة بيئة التشغيل، والعرض المتوقع وكيف استخرجته؛ ومن دونها لا يستطيع المطور أن يميّز عيب التنسيق من قيمة مخزنة خاطئة.
تمرين عملي
استخرج القيم المتوقعة لطلب في نهاية السنة
تعيد واجهة الطلبات السجل أدناه: ثلاث وحدات من طابعة مكتبية بسعر 38,450.35 ريالاً للوحدة، سُجّل الطلب مساء آخر يوم في السنة بتوقيت UTC. وتقول القاعدة: «تُحسب ضريبة القيمة المضافة 15٪ على المجموع الفرعي للطلب وتُقرَّب لأعلى عند النصف (Round half up) إلى منزلتين عشريتين؛ وتُعرض التواريخ بالمنطقة الزمنية للعميل؛ وتُنسَّق المبالغ بالإعداد المحلي للعميل، وبأرقام غربية للعربية». ويُعدّ فريق المالية تقاريره بتوقيت UTC.
يقدّم عميلان هذا الطلب نفسه في اللحظة نفسها: أحدهما في الرياض (ar-SA وAsia/Riyadh) والآخر في كولكاتا (hi-IN وAsia/Kolkata). استخرج المجموع الفرعي والضريبة والإجمالي المتوقعة، والتاريخ والوقت اللذين يجب أن يعرضهما كل عميل وتقرير المالية، والفحوص التي ستجريها على صفحتَي التأكيد العربية والهندية. ثم اكتب اختباراً سلبياً واحداً لحقل الكمية، ودوّن ما يبقى غامضاً في القاعدة.
{
"order_id": "ORD-2026-0917",
"placed_at": "2026-12-31T20:15:00Z",
"lines": [{ "sku": "PRN-400", "qty": 3, "unit_price": "38450.35" }],
"currency": "SAR"
}- احسب المجموع الفرعي والضريبة والإجمالي بالقاعدة المذكورة ثم بالتقريب لكل سطر، لتعرف هل يمكن التفريق بين القاعدتين في هذا الطلب.
- حوّل اللحظة المخزنة إلى
Asia/RiyadhوAsia/Kolkataودوّن اليوم والسنة في كل منهما، ثم بتوقيت UTC لتقرير المالية. - اكتب ما ستتحقق منه في صفحة ar-SA (الأرقام والفواصل وموضع الرمز والاتجاه والأحرف غير المرئية) وفي صفحة hi-IN (التجميع، ورمز ISO أم رمز العملة).
- اكتب الاختبار السلبي لكمية مكتوبة
٣والأسئلة المفتوحة لمالك المنتج وللمالية.
إظهار الإجابة النموذجية
المجموع الفرعي 3 × 38,450.35 = 115,351.05؛ والضريبة 115,351.05 × 0.15 = 17,302.6575 تُقرَّب لأعلى عند النصف إلى 17,302.66؛ والإجمالي 132,653.71. أما بالتقريب لكل سطر فضريبة السطر 5,767.5525 تُقرَّب إلى 5,767.55، ومضروبةً في 3 تعطي 17,302.65 وإجمالياً 132,653.70، لذا فإجمالي 132,653.70 في أي صفحة أو فاتورة عيب مخالف للقاعدة المذكورة. واحسب بنوع عشري أو بالهللات: ففي JavaScript يعطي 3 * 38450.35 القيمة 115351.04999999999، فالكود الذي يقتطع بدلاً من أن يقرِّب يعرض مجموعاً فرعياً قدره 115,351.04.
الرياض (+03:00): 31 ديسمبر 2026 الساعة 23:15. كولكاتا (+05:30): 1 يناير 2027 الساعة 01:45. وتقرير المالية بتوقيت UTC: 31 ديسمبر 2026 الساعة 20:15. فالطلب نفسه ينتمي إلى سنة 2026 لعميل الرياض وللمالية، وإلى سنة 2027 لعميل كولكاتا، لذا افحص كل موضع تُستخرج منه السنة: تاريخ الفاتورة، وقائمة الطلبات المجمَّعة حسب السنة، ومرشِّح «هذه السنة»، والتقرير السنوي. وإن كانت صفحة الرياض تعرض تاريخ أم القرى فهو 22 رجب 1448 هـ.
صفحة ar-SA: أرقام غربية بحسب القاعدة (132,653.71 لا ١٣٢٬٦٥٣٫٧١)، والرمز في موضعه من المنسِّق، والسلسلة مقروءة في سياق من اليمين إلى اليسار، والعلامات غير المرئية موجودة دون أن تُفسد التخطيط، والسلسلة المتوقعة مأخوذة من استدعاء التنسيق نفسه. صفحة hi-IN: الإجمالي يتجاوز لاكاً واحداً، فيجب أن يظهر بالتجميع الهندي SAR 1,32,653.71؛ أما SAR 132,653.71 فيعني أن الصفحة استخدمت التجميع الغربي أو صيغة مثبَّتة في الكود. ويظهر الريال برمز ISO SAR لأن المنتج لا يحوّل العملات.
الاختبار السلبي: كمية ٣ مكتوبة في الصفحة العربية إما تُطبَّع إلى 3 ويبقى المجموع الفرعي 115,351.05 كما هو، أو تُرفض برسالة بالعربية؛ ويجب ألا تصبح أبداً صفراً أو NaN أو طلباً فارغاً. الأسئلة المفتوحة: أي منطقة زمنية تحدد الفترة الضريبية وسنة الفاتورة لطلب سُجّل عند تبدّل السنة؟ وهل يُقصد بـ«لأعلى عند النصف» مبالغ الاسترداد السالبة أيضاً؟ وأي منطقة زمنية تنطبق عندما يسافر العميل؟
أسئلة شائعة
هل يجب تخزين كل تاريخ بتوقيت UTC؟
خزّن اللحظات (متى حدث شيء أو سيحدث) بتوقيت UTC أو بفارق صريح، وحوّلها للعرض. أما القيم التي هي تاريخ فقط، مثل تاريخ الميلاد أو تاريخ الاستحقاق أو عطلة رسمية، فليست لها منطقة زمنية ويجب أن تبقى تواريخ مجردة. وللأحداث المجدولة بالوقت المحلي في مستقبل بعيد، احتفظ بالوقت المحلي مع معرِّف المنطقة في IANA، لأن قواعد الفوارق قد تتغيّر قبل الحدث.
هل المنطقة الزمنية جزء من اختبار التوطين؟
تُختبر معه لكنها ليست خاصية للإعداد المحلي. فمستخدم hi-IN قد يكون في الرياض ومستخدم en-GB في كولكاتا. عامل الإعداد المحلي والمنطقة الزمنية شرطَي اختبار مستقلَّين واجمع بينهما عمداً، كما تجمع بين المتصفح ونظام التشغيل.
لماذا يفشل تأكيدي مع أن المبلغ على الشاشة يبدو صحيحاً؟
تحوي السلاسل المنسَّقة أحرفاً لا تراها: علامات اتجاه من اليمين إلى اليسار (U+200F) حول المبالغ العربية، ومسافة غير فاصلة (U+00A0) قبل الرمز، ومسافة ضيقة غير فاصلة (U+202F) فاصلةً للآلاف في الفرنسية. أنتج السلسلة المتوقعة بواجهة التنسيق نفسها والإعداد المحلي نفسه، أو طبِّع الطرفين عمداً وصرّح بذلك في الاختبار.
هل يعني ar-SA دائماً الأرقام العربية المشرقية والتقويم الهجري؟
لا. فالافتراضات تأتي من بيانات CLDR في كل بيئة تشغيل وقد تغيّرت بين النسخ؛ فعلى سبيل المثال يعطي Node.js 22 وChromium الحالي لـar-SA أرقاماً عربية مشرقية مع التقويم الميلادي. وينبغي للمنتج أن يطلب ما يريده صراحةً (-u-nu-latn و-u-ca-islamic-umalqura)، وعليك أن تختبر ما ضبطه المنتج على كل بيئة تشغيل يشحنها.
المراجع
- Unicode CLDR Projectمستودع بيانات اللغات والمناطق المشترك: بيانات صيغ التاريخ والوقت والأرقام والعملات وقواعد الجمع التي تعتمدها معظم المنصات.
- Time Zone Databaseقاعدة بيانات tz للمناطق الزمنية في العالم وقواعد فروق التوقيت والتوقيت الصيفي تاريخياً، وتُحدَّث عدة مرات في السنة.
- ISO 4217 — Currency codesرموز العملات ثلاثية الأحرف (SAR وINR وUSD…) ووحداتها الفرعية — المرجع لاختبار حقول العملة وتنسيقها.
- RFC 3339: Date and Time on the Internet: Timestampsملف تعريف الطوابع الزمنية على الإنترنت المشتق من ISO 8601 (2026-09-23T10:15:00Z) وقواعد الإزاحة الزمنية.
تدرّب بأدوات متقن
حوّل التاريخ والوقت بين المناطق الزمنية (الرياض، عمّان، دلهي، UTC، نيويورك، لندن…).
حلّل وولّد سلاسل التاريخ والوقت والمدد والفترات بصيغة ISO 8601.
حوّل الطوابع الزمنية (ثوانٍ، ميلي ثانية، ميكرو ثانية) إلى تواريخ مقروءة وبالعكس، بأي منطقة زمنية.
ولّد مجموعات بيانات للتواريخ: تواريخ عشوائية ضمن نطاق، وأيام كبيسة، ونهايات الأشهر، وحدود التوقيت الصيفي، وصيغ متعددة.
ولّد مجموعات بيانات عشرية / ذات فاصلة عائمة بدقة ثابتة ومبالغ بنمط العملات وحالات تقريب حدّية.
ولّد أسماء وعناوين وجملاً وأرقاماً عربية (بالأرقام العربية-الهندية) وحالات حدّية للكتابة من اليمين إلى اليسار لاختبار التوطين.
للتعمّق أكثر
تقدّمك في هذا الموضوع
سجّل الدخول لتتابع تقدّمك
علّم الموضوعات مكتملة، وتابع من حيث توقفت، وافتح امتحانات التخصص.