كيفية الحصول على قائمة التقويمات والعملات والمناطق الزمنية المدعومة

اكتشف قيم التدويل التي تدعمها بيئة JavaScript الخاصة بك

مقدمة

عند بناء تطبيقات متعددة اللغات، غالبًا ما تحتاج إلى إنشاء عناصر واجهة مستخدم مثل القوائم المنسدلة أو أدوات الاختيار أو النماذج التي تتيح للمستخدمين اختيار التقويمات أو العملات أو المناطق الزمنية أو خيارات التوطين الأخرى. لبناء هذه المكونات، تحتاج إلى معرفة القيم التي تدعمها بيئة JavaScript.

بدلاً من الاحتفاظ بقوائم ثابتة تصبح قديمة أو تحتوي على قيم لا يدعمها المتصفح، توفر JavaScript طريقة لاكتشاف القيم المدعومة في وقت التشغيل. هذا يضمن أن تطبيقك يقدم فقط الخيارات التي تعمل بشكل صحيح في بيئة المستخدم.

تُرجع الطريقة Intl.supportedValuesOf() قوائم بقيم التدويل المدعومة. يمكنك الاستعلام عن هذه الطريقة للحصول على التقويمات والعملات والمناطق الزمنية وأنظمة الترقيم وأنواع الترتيب ووحدات القياس التي تدعمها بيئة JavaScript.

ما تُرجعه Intl.supportedValuesOf

تقبل الطريقة Intl.supportedValuesOf() معاملاً نصيًا واحدًا يحدد نوع القيم المراد إرجاعها. تُرجع مصفوفة من السلاسل النصية تمثل القيم المدعومة لهذا النوع.

const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars);
// Output: ["buddhist", "chinese", "coptic", "dangi", ...]

تدعم الطريقة ستة أنواع مختلفة من المفاتيح:

  • "calendar" تُرجع أنظمة التقويم المدعومة
  • "currency" تُرجع رموز العملات المدعومة
  • "timeZone" تُرجع معرفات المناطق الزمنية المدعومة
  • "numberingSystem" تُرجع أنظمة الترقيم المدعومة
  • "collation" تُرجع أنواع الترتيب المدعومة
  • "unit" تُرجع وحدات القياس المدعومة

المصفوفة المُرجعة دائمًا مرتبة ترتيبًا أبجديًا تصاعديًا، ولا تحتوي على قيم مكررة، وتستخدم معرفات قياسية وفقًا لمعايير Unicode.

إذا قمت بتمرير مفتاح غير صالح، فإن الدالة تطرح RangeError:

try {
  Intl.supportedValuesOf("invalid");
} catch (error) {
  console.error(error.name);
  // Output: "RangeError"
}

يشير هذا الخطأ إلى أنك استخدمت مفتاحاً لا تتعرف عليه الدالة.

الحصول على التقاويم المدعومة

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

يُرجع المفتاح "calendar" جميع أنظمة التقويم المدعومة من قبل بيئة JavaScript:

const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars);
// Output: ["buddhist", "chinese", "coptic", "dangi", "ethioaa",
//          "ethiopic", "gregory", "hebrew", "indian", "islamic",
//          "islamic-civil", "islamic-rgsa", "islamic-tbla",
//          "islamic-umalqura", "iso8601", "japanese", "persian",
//          "roc"]

التقويم الأكثر شيوعاً هو "gregory"، والذي يمثل التقويم الميلادي المستخدم في معظم أنحاء العالم. تشمل التقاويم الأخرى:

  • "buddhist" للتقويم البوذي التايلاندي
  • "chinese" للتقويم الصيني التقليدي
  • "islamic" للتقويم الهجري الإسلامي
  • "hebrew" للتقويم العبري
  • "japanese" للتقويم الياباني مع أسماء الحقب

يؤثر كل تقويم على كيفية تنسيق التواريخ وحسابها. عند استخدام Intl.DateTimeFormat مع تقويم محدد، تظهر التواريخ وفقاً لقواعد ذلك التقويم:

const date = new Date("2025-10-15");

const gregorianFormat = new Intl.DateTimeFormat("en-US", {
  calendar: "gregory",
  year: "numeric",
  month: "long",
  day: "numeric"
});

const islamicFormat = new Intl.DateTimeFormat("en-US", {
  calendar: "islamic",
  year: "numeric",
  month: "long",
  day: "numeric"
});

console.log(gregorianFormat.format(date));
// Output: "October 15, 2025"

console.log(islamicFormat.format(date));
// Output: "Rabi' II 13, 1447 AH"

يظهر نفس تاريخ JavaScript بشكل مختلف عند تنسيقه بتقاويم مختلفة.

استخدام التقاويم المدعومة لبناء محددات الاختيار

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

const calendars = Intl.supportedValuesOf("calendar");

const select = document.createElement("select");

calendars.forEach(calendar => {
  const option = document.createElement("option");
  option.value = calendar;
  option.textContent = calendar;
  select.appendChild(option);
});

document.body.appendChild(select);

ينشئ هذا قائمة منسدلة تحتوي فقط على التقاويم التي تعمل في البيئة الحالية.

يمكنك تحسين هذا المحدد باستخدام Intl.DisplayNames لإظهار أسماء التقاويم المقروءة للإنسان:

const calendars = Intl.supportedValuesOf("calendar");
const displayNames = new Intl.DisplayNames(["en-US"], { type: "calendar" });

calendars.forEach(calendar => {
  const option = document.createElement("option");
  option.value = calendar;
  option.textContent = displayNames.of(calendar);
  // Creates options like "Gregorian Calendar", "Islamic Calendar", etc.
});

يعرض هذا أسماء وصفية بدلاً من المعرفات التقنية.

الحصول على العملات المدعومة

تحدد رموز العملات الأنظمة النقدية المستخدمة حول العالم. يدعم JavaScript مئات رموز العملات بناءً على معيار ISO 4217.

يُرجع المفتاح "currency" جميع رموز العملات المدعومة من قبل بيئة JavaScript:

const currencies = Intl.supportedValuesOf("currency");
console.log(currencies.length);
// Output: typically over 300

console.log(currencies.slice(0, 10));
// Output: ["ADP", "AED", "AFA", "AFN", "ALK", "ALL", "AMD", "ANG", "AOA", "AOK"]

تستخدم رموز العملات ثلاثة أحرف كبيرة. تتضمن الأمثلة الشائعة:

  • "USD" للدولار الأمريكي
  • "EUR" لليورو
  • "GBP" للجنيه الإسترليني البريطاني
  • "JPY" للين الياباني
  • "CNY" لليوان الصيني

تتضمن القائمة العملات الحالية وبعض العملات التاريخية التي لم تعد متداولة.

عند تنسيق قيم العملات، يجب تحديد العملة المراد استخدامها:

const amount = 1234.56;

const usdFormat = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD"
});

const eurFormat = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "EUR"
});

console.log(usdFormat.format(amount));
// Output: "$1,234.56"

console.log(eurFormat.format(amount));
// Output: "€1,234.56"

يحدد رمز العملة الرمز الذي يظهر وكيفية تنسيق القيمة.

تصفية العملات لاختيار المستخدم

تحتاج معظم التطبيقات فقط إلى عرض العملات الحالية والشائعة الاستخدام. يمكنك تصفية قائمة العملات المدعومة لتشمل فقط تلك ذات الصلة بمستخدميك:

const allCurrencies = Intl.supportedValuesOf("currency");
const commonCurrencies = ["USD", "EUR", "GBP", "JPY", "CNY", "INR", "CAD", "AUD"];

const availableCurrencies = commonCurrencies.filter(currency =>
  allCurrencies.includes(currency)
);

console.log(availableCurrencies);
// Output: ["USD", "EUR", "GBP", "JPY", "CNY", "INR", "CAD", "AUD"]

يضمن هذا أنك تعرض فقط العملات التي تلبي متطلباتك ومدعومة من قبل المتصفح.

عرض أسماء العملات

عند إنشاء محدد عملات، اعرض أسماء وصفية بدلاً من رموز الأحرف الثلاثة:

const currencies = ["USD", "EUR", "GBP", "JPY"];
const displayNames = new Intl.DisplayNames(["en-US"], { type: "currency" });

currencies.forEach(currency => {
  const name = displayNames.of(currency);
  console.log(`${currency}: ${name}`);
});
// Output:
// USD: US Dollar
// EUR: Euro
// GBP: British Pound
// JPY: Japanese Yen

يوفر هذا تجربة مستخدم أفضل من خلال إظهار ما يمثله كل رمز.

الحصول على المناطق الزمنية المدعومة

تمثل المناطق الزمنية المناطق الجغرافية التي تلتزم بنفس التوقيت القياسي. يدعم JavaScript مئات معرفات المناطق الزمنية بناءً على قاعدة بيانات IANA للمناطق الزمنية.

يُرجع المفتاح "timeZone" جميع معرفات المناطق الزمنية المدعومة من قبل بيئة JavaScript:

const timeZones = Intl.supportedValuesOf("timeZone");
console.log(timeZones.length);
// Output: typically over 400

console.log(timeZones.slice(0, 10));
// Output: ["Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa",
//          "Africa/Algiers", "Africa/Asmara", "Africa/Bamako",
//          "Africa/Bangui", "Africa/Banjul", "Africa/Bissau", "Africa/Blantyre"]

تتبع معرفات المناطق الزمنية التنسيق Continent/City، مثل "America/New_York" أو "Europe/London". تتضمن بعض المعرفات مكونات إضافية مثل "America/Indiana/Indianapolis".

عند تنسيق التواريخ والأوقات، تؤثر المنطقة الزمنية على الوقت المحلي الذي يظهر:

const date = new Date("2025-10-15T12:00:00Z");

const newYorkFormat = new Intl.DateTimeFormat("en-US", {
  timeZone: "America/New_York",
  year: "numeric",
  month: "long",
  day: "numeric",
  hour: "numeric",
  minute: "numeric",
  timeZoneName: "short"
});

const tokyoFormat = new Intl.DateTimeFormat("en-US", {
  timeZone: "Asia/Tokyo",
  year: "numeric",
  month: "long",
  day: "numeric",
  hour: "numeric",
  minute: "numeric",
  timeZoneName: "short"
});

console.log(newYorkFormat.format(date));
// Output: "October 15, 2025, 8:00 AM EDT"

console.log(tokyoFormat.format(date));
// Output: "October 15, 2025, 9:00 PM JST"

تظهر نفس اللحظة الزمنية كأوقات محلية مختلفة حسب المنطقة الزمنية.

بناء محددات المناطق الزمنية

تحتاج محددات المناطق الزمنية إلى عرض مئات الخيارات بطريقة يمكن للمستخدمين فهمها. قم بتجميع المناطق الزمنية حسب المنطقة الجغرافية لتسهيل الاختيار:

const timeZones = Intl.supportedValuesOf("timeZone");

const grouped = timeZones.reduce((groups, tz) => {
  const [region] = tz.split("/");
  if (!groups[region]) {
    groups[region] = [];
  }
  groups[region].push(tz);
  return groups;
}, {});

console.log(Object.keys(grouped));
// Output: ["Africa", "America", "Antarctica", "Arctic", "Asia",
//          "Atlantic", "Australia", "Europe", "Indian", "Pacific", "Etc"]

يقوم هذا التنظيم بتجميع المناطق الزمنية حسب القارة، مما يسهل على المستخدمين العثور على موقعهم.

يمكنك تحسين تجربة المستخدم بشكل أكبر من خلال إظهار الفارق الزمني الحالي لكل منطقة زمنية:

function getTimeZoneOffset(timeZone) {
  const date = new Date();
  const formatter = new Intl.DateTimeFormat("en-US", {
    timeZone,
    timeZoneName: "shortOffset"
  });
  const parts = formatter.formatToParts(date);
  const offsetPart = parts.find(part => part.type === "timeZoneName");
  return offsetPart ? offsetPart.value : "";
}

const timeZones = ["America/New_York", "Europe/London", "Asia/Tokyo"];

timeZones.forEach(tz => {
  const offset = getTimeZoneOffset(tz);
  console.log(`${tz}: ${offset}`);
});
// Output:
// America/New_York: GMT-4
// Europe/London: GMT+1
// Asia/Tokyo: GMT+9

يساعد إظهار الفوارق الزمنية المستخدمين على فهم الفرق الزمني بين المناطق.

الحصول على أنظمة الترقيم المدعومة

تحدد أنظمة الترقيم كيفية عرض الأرقام. بينما تستخدم معظم التطبيقات الأرقام العربية القياسية (0-9)، فإن العديد من اللغات لديها أنظمة ترقيم تقليدية خاصة بها.

يُرجع المفتاح "numberingSystem" جميع أنظمة الترقيم المدعومة من قبل بيئة JavaScript:

const numberingSystems = Intl.supportedValuesOf("numberingSystem");
console.log(numberingSystems.slice(0, 10));
// Output: ["adlm", "ahom", "arab", "arabext", "armn", "armnlow",
//          "bali", "beng", "bhks", "brah"]

تتضمن أنظمة الترقيم الشائعة:

  • "latn" للأرقام اللاتينية القياسية (0-9)
  • "arab" للأرقام العربية الهندية
  • "thai" للأرقام التايلاندية
  • "deva" لأرقام الديفاناغاري المستخدمة في الهندية

تعرض أنظمة الترقيم المختلفة نفس الرقم بشكل مختلف:

const number = 12345;

const latinFormat = new Intl.NumberFormat("en-US", {
  numberingSystem: "latn"
});

const arabFormat = new Intl.NumberFormat("en-US", {
  numberingSystem: "arab"
});

const thaiFormat = new Intl.NumberFormat("en-US", {
  numberingSystem: "thai"
});

console.log(latinFormat.format(number));
// Output: "12,345"

console.log(arabFormat.format(number));
// Output: "١٢٬٣٤٥"

console.log(thaiFormat.format(number));
// Output: "๑๒,๓๔๕"

تظهر نفس القيمة العددية بأشكال أرقام مختلفة.

الحصول على أنواع الترتيب المدعومة

تحدد أنواع الترتيب كيفية فرز النصوص ومقارنتها. لدى اللغات المختلفة قواعد مختلفة للترتيب الأبجدي.

يُرجع المفتاح "collation" جميع أنواع الترتيب المدعومة من قبل بيئة JavaScript:

const collations = Intl.supportedValuesOf("collation");
console.log(collations.slice(0, 10));
// Output: ["big5han", "compat", "dict", "direct", "ducet", "emoji",
//          "eor", "gb2312", "phonebk", "phonetic"]

تشمل أنواع الترتيب الشائعة:

  • "standard" للترتيب الافتراضي لكل لغة
  • "phonetic" للترتيب الصوتي
  • "pinyin" للترتيب حسب البينيين الصيني
  • "emoji" لترتيب الرموز التعبيرية

يؤثر الترتيب على كيفية فرز مصفوفات السلاسل النصية:

const words = ["ä", "z", "a"];

const standardCollator = new Intl.Collator("de-DE", {
  collation: "standard"
});

const phoneticCollator = new Intl.Collator("de-DE", {
  collation: "phonetic"
});

console.log(words.sort(standardCollator.compare));
// Output: ["a", "ä", "z"]

console.log(words.sort(phoneticCollator.compare));
// Output: ["a", "ä", "z"]

يمكن أن تنتج أنواع الترتيب المختلفة ترتيبات فرز مختلفة لنفس المدخلات.

الحصول على الوحدات المدعومة

تمثل معرّفات الوحدات وحدات القياس مثل الأمتار أو الجالونات أو درجات مئوية. يدعم JavaScript العديد من أنواع الوحدات لتنسيق القياسات.

يُرجع المفتاح "unit" جميع معرّفات الوحدات المدعومة من قبل بيئة JavaScript:

const units = Intl.supportedValuesOf("unit");
console.log(units.slice(0, 10));
// Output: ["acre", "bit", "byte", "celsius", "centimeter", "day",
//          "degree", "fahrenheit", "fluid-ounce", "foot"]

تشمل الوحدات الشائعة:

  • الطول: "meter"، "kilometer"، "mile"، "foot"
  • الوزن: "gram"، "kilogram"، "pound"، "ounce"
  • درجة الحرارة: "celsius"، "fahrenheit"
  • الحجم: "liter"، "gallon"
  • الرقمية: "byte"، "kilobyte"، "megabyte"

عند تنسيق القياسات، حدد الوحدة المراد استخدامها:

const distance = 1000;

const meterFormat = new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "meter"
});

const kilometerFormat = new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "kilometer"
});

console.log(meterFormat.format(distance));
// Output: "1,000 m"

console.log(kilometerFormat.format(1));
// Output: "1 km"

تحدد الوحدة الاختصار أو الرمز الذي يظهر مع الرقم.

يمكنك دمج الوحدات باستخدام التنسيق "unit1-per-unit2":

const speed = 100;

const speedFormat = new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "kilometer-per-hour"
});

console.log(speedFormat.format(speed));
// Output: "100 km/h"

ينشئ هذا وحدات مركبة مثل كيلومتر في الساعة أو ميل لكل جالون.

بناء واجهات مستخدم ديناميكية

حالة الاستخدام الأساسية لـ Intl.supportedValuesOf() هي بناء واجهات مستخدم تتكيف مع بيئة JavaScript الحالية. بدلاً من ترميز الخيارات بشكل ثابت، استعلم عن القيم المدعومة في وقت التشغيل.

ينشئ هذا المثال نموذج إعدادات حيث يمكن للمستخدمين اختيار التقويم والعملة والمنطقة الزمنية المفضلة لديهم:

function buildSettingsForm() {
  const form = document.createElement("form");

  // Calendar selector
  const calendarSelect = buildSelector(
    "calendar",
    Intl.supportedValuesOf("calendar")
  );
  form.appendChild(createFormGroup("Calendar", calendarSelect));

  // Currency selector
  const currencies = ["USD", "EUR", "GBP", "JPY", "CNY"];
  const currencySelect = buildSelector("currency", currencies);
  form.appendChild(createFormGroup("Currency", currencySelect));

  // Time zone selector
  const timeZones = Intl.supportedValuesOf("timeZone");
  const timeZoneSelect = buildSelector("timeZone", timeZones);
  form.appendChild(createFormGroup("Time Zone", timeZoneSelect));

  return form;
}

function buildSelector(name, values) {
  const select = document.createElement("select");
  select.name = name;

  values.forEach(value => {
    const option = document.createElement("option");
    option.value = value;
    option.textContent = value;
    select.appendChild(option);
  });

  return select;
}

function createFormGroup(label, input) {
  const group = document.createElement("div");
  const labelElement = document.createElement("label");
  labelElement.textContent = label;
  group.appendChild(labelElement);
  group.appendChild(input);
  return group;
}

document.body.appendChild(buildSettingsForm());

ينشئ هذا واجهة إعدادات كاملة باستخدام القيم المدعومة من المتصفح فقط.

استخدام القيم المدعومة للكشف عن الميزات

يمكنك استخدام Intl.supportedValuesOf() للكشف عما إذا كانت قيم معينة مدعومة قبل استخدامها. يساعد هذا في تنفيذ استراتيجيات التحسين التدريجي والبدائل الاحتياطية.

تحقق مما إذا كان تقويم معين مدعومًا:

function isCalendarSupported(calendar) {
  const supported = Intl.supportedValuesOf("calendar");
  return supported.includes(calendar);
}

if (isCalendarSupported("islamic")) {
  console.log("Islamic calendar is supported");
} else {
  console.log("Islamic calendar is not supported");
}

يعمل هذا النمط مع أي نوع قيمة:

function isValueSupported(type, value) {
  try {
    const supported = Intl.supportedValuesOf(type);
    return supported.includes(value);
  } catch (error) {
    return false;
  }
}

console.log(isValueSupported("currency", "USD"));
// Output: true

console.log(isValueSupported("timeZone", "America/New_York"));
// Output: true

يتعامل كتلة try-catch مع البيئات التي لا يتوفر فيها Intl.supportedValuesOf().

يمكنك استخدام هذا للتحميل المشروط للـ polyfills:

async function ensureCalendarSupport(calendar) {
  if (!isValueSupported("calendar", calendar)) {
    console.log(`Loading polyfill for ${calendar} calendar`);
    await import("./calendar-polyfill.js");
  }
}

await ensureCalendarSupport("persian");

يحمل هذا الكود الإضافي فقط عند الحاجة.