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

استرجاع جميع معرفات المناطق الزمنية IANA المدعومة في JavaScript لبناء القوائم المنسدلة والتحقق من مدخلات المستخدم

مقدمة

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

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

توفر JavaScript طريقة Intl.supportedValuesOf() لاسترجاع جميع معرفات المناطق الزمنية التي تدعمها البيئة الحالية. هذا يضمن أن تطبيقك يقدم فقط المناطق الزمنية التي تعمل بشكل صحيح ويبقى محدثاً مع التغييرات في قاعدة بيانات المناطق الزمنية.

ما هي معرفات المناطق الزمنية

معرفات المناطق الزمنية هي سلاسل نصية موحدة تمثل مناطق جغرافية ذات قواعد زمنية متسقة. تأتي من قاعدة بيانات المناطق الزمنية IANA، وهي قائمة شاملة تحتفظ بها منظمة دولية تتتبع المناطق الزمنية وتغييرات التوقيت الصيفي في جميع أنحاء العالم.

تستخدم المعرفات تنسيقاً محدداً يجعلها واضحة ومستقرة عبر الأنظمة المختلفة. فهم هذا التنسيق يساعدك على العمل مع المناطق الزمنية بفعالية.

فهم تنسيق معرفات المناطق الزمنية IANA

تتبع معرّفات المناطق الزمنية IANA النمط Area/Location، حيث تمثل المنطقة قارة أو محيطاً ويمثل الموقع مدينة أو منطقة ضمن تلك المنطقة.

const examples = [
  'America/New_York',
  'Europe/London',
  'Asia/Tokyo',
  'Australia/Sydney',
  'Pacific/Auckland'
];

تتوافق المنطقة مع:

  • America لأمريكا الشمالية والجنوبية
  • Europe للمواقع الأوروبية
  • Asia للمواقع الآسيوية
  • Africa للمواقع الأفريقية
  • Australia للمواقع الأسترالية
  • Pacific لجزر المحيط الهادئ
  • Atlantic لجزر المحيط الأطلسي
  • Indian لجزر المحيط الهندي
  • Antarctica لمحطات الأبحاث في القطب الجنوبي

يمثل الموقع عادةً أكبر مدينة أو أكثرها تمثيلاً في المنطقة الزمنية. تمثل نيويورك المنطقة الزمنية الشرقية للولايات المتحدة. تمثل طوكيو اليابان. تمثل سيدني المنطقة الزمنية الشرقية لأستراليا.

تتضمن بعض المعرّفات ثلاثة أجزاء للمناطق ضمن منطقة أكبر:

const detailedExamples = [
  'America/Indiana/Indianapolis',
  'America/Kentucky/Louisville',
  'America/North_Dakota/Center'
];

تميز هذه المعرّفات متعددة الأجزاء المناطق التي تتبع قواعد زمنية مختلفة ضمن نفس البلد.

تستخدم قاعدة البيانات الشرطات السفلية بدلاً من المسافات في أسماء المدن:

const underscoreExamples = [
  'America/New_York',    // Not "New York"
  'America/Los_Angeles', // Not "Los Angeles"
  'Asia/Ho_Chi_Minh'     // Not "Ho Chi Minh"
];

يضمن هذا التنسيق عمل المعرّفات كرموز مفردة دون أحرف خاصة قد تسبب مشاكل في التحليل.

لماذا تستخدم المعرّفات المدن بدلاً من الاختصارات

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

تظل المعرّفات المستندة إلى المدن واضحة دون لبس. America/New_York يشير دائمًا إلى نفس المكان وقواعد الوقت، بغض النظر عن السياق.

بالإضافة إلى ذلك، لا تعكس الاختصارات التحولات في التوقيت الصيفي. EST يمثل فقط التوقيت القياسي، وليس EDT (التوقيت الصيفي الشرقي). المعرّف America/New_York يتعامل تلقائيًا مع كل من التوقيت القياسي والصيفي بناءً على التاريخ.

الحصول على جميع معرّفات المناطق الزمنية المدعومة

تُرجع الدالة Intl.supportedValuesOf() مع المعامل 'timeZone' مصفوفة بجميع معرّفات المناطق الزمنية المدعومة من قبل بيئة JavaScript.

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

console.log(timeZones.length);
// Output: over 400

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

تُرجع الدالة المعرّفات مرتبة أبجديًا دون تكرار. تعتمد القائمة الدقيقة على بيئة JavaScript، لكن المتصفحات الحديثة وإصدارات Node.js تدعم أكثر من 400 منطقة زمنية.

يمكن استخدام كل معرّف في المصفوفة مع Intl.DateTimeFormat لتنسيق التواريخ والأوقات لتلك المنطقة الزمنية:

const timeZone = timeZones[0]; // "Africa/Abidjan"
const date = new Date('2025-10-15T12:00:00Z');

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: timeZone,
  dateStyle: 'long',
  timeStyle: 'short'
});

console.log(formatter.format(date));
// Output: "October 15, 2025 at 12:00 PM"

تضمن الدالة أن كل معرّف تُرجعه يعمل بشكل صحيح مع واجهات برمجة تطبيقات Intl.

إنشاء محدد للمنطقة الزمنية

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

function buildTimeZoneSelector() {
  const timeZones = Intl.supportedValuesOf('timeZone');
  const select = document.createElement('select');
  select.name = 'timeZone';

  timeZones.forEach(timeZone => {
    const option = document.createElement('option');
    option.value = timeZone;
    option.textContent = timeZone;
    select.appendChild(option);
  });

  return select;
}

const selector = buildTimeZoneSelector();
document.body.appendChild(selector);

ينشئ هذا عنصر تحديد يحتوي على خيارات لكل منطقة زمنية مدعومة. يمكن للمستخدمين التمرير عبر القائمة واختيار موقعهم.

ومع ذلك، فإن قائمة تحتوي على أكثر من 400 معرّف غير مرتب تخلق تجربة مستخدم سيئة. يحتاج المستخدمون إلى فهم كيفية تنظيم المعرّفات والعثور على موقعهم بسرعة.

تجميع المناطق الزمنية حسب المنطقة

يجعل تنظيم المناطق الزمنية حسب القارة القائمة أسهل في التصفح. يمكنك استخراج المنطقة من كل معرّف وتجميعها وفقًا لذلك.

function groupTimeZonesByRegion() {
  const timeZones = Intl.supportedValuesOf('timeZone');
  const grouped = {};

  timeZones.forEach(timeZone => {
    const parts = timeZone.split('/');
    const region = parts[0];

    if (!grouped[region]) {
      grouped[region] = [];
    }

    grouped[region].push(timeZone);
  });

  return grouped;
}

const grouped = groupTimeZonesByRegion();

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

console.log(grouped['America'].slice(0, 5));
// Output: [
//   "America/Adak",
//   "America/Anchorage",
//   "America/Anguilla",
//   "America/Antigua",
//   "America/Araguaina"
// ]

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

يمكنك استخدام هذه البيانات المجمعة لبناء محدد أكثر تنظيمًا باستخدام عناصر optgroup:

function buildGroupedTimeZoneSelector() {
  const grouped = groupTimeZonesByRegion();
  const select = document.createElement('select');
  select.name = 'timeZone';

  Object.keys(grouped).sort().forEach(region => {
    const optgroup = document.createElement('optgroup');
    optgroup.label = region;

    grouped[region].forEach(timeZone => {
      const option = document.createElement('option');
      option.value = timeZone;
      option.textContent = timeZone.split('/').slice(1).join('/');
      optgroup.appendChild(option);
    });

    select.appendChild(optgroup);
  });

  return select;
}

const groupedSelector = buildGroupedTimeZoneSelector();
document.body.appendChild(groupedSelector);

ينشئ هذا عنصر select حيث تظهر المناطق الزمنية تحت عناوينها الإقليمية. يعرض نص الخيار جزء المدينة فقط من المعرف، مما يجعل القائمة أكثر قابلية للقراءة.

تصفية المناطق الزمنية حسب المنطقة

في بعض الأحيان تحتاج فقط إلى المناطق الزمنية من مناطق محددة. على سبيل المثال، قد يعرض تطبيق يخدم مستخدمي أمريكا الشمالية فقط المناطق الزمنية الأمريكية.

function getTimeZonesForRegion(region) {
  const timeZones = Intl.supportedValuesOf('timeZone');
  return timeZones.filter(timeZone => timeZone.startsWith(`${region}/`));
}

const americanTimeZones = getTimeZonesForRegion('America');
console.log(americanTimeZones.length);
// Output: over 150

console.log(americanTimeZones.slice(0, 5));
// Output: [
//   "America/Adak",
//   "America/Anchorage",
//   "America/Anguilla",
//   "America/Antigua",
//   "America/Araguaina"
// ]

تقوم هذه الدالة بتصفية القائمة الكاملة لتشمل فقط المعرفات التي تبدأ بالمنطقة المحددة. يمكنك استدعاؤها باسم أي منطقة للحصول على قائمة مركزة.

يمكنك التصفية لمناطق متعددة:

function getTimeZonesForRegions(regions) {
  const timeZones = Intl.supportedValuesOf('timeZone');
  return timeZones.filter(timeZone => {
    return regions.some(region => timeZone.startsWith(`${region}/`));
  });
}

const europeanAndAsianTimeZones = getTimeZonesForRegions(['Europe', 'Asia']);
console.log(europeanAndAsianTimeZones.length);
// Output: over 200

يوفر هذا مرونة للتطبيقات التي تخدم مناطق متعددة ولكن ليس جميع المناطق.

البحث عن مناطق زمنية محددة

عندما يعرف المستخدمون المدينة التي يبحثون عنها، يساعدهم البحث بالاسم في العثور عليها بسرعة.

function searchTimeZones(query) {
  const timeZones = Intl.supportedValuesOf('timeZone');
  const lowerQuery = query.toLowerCase();

  return timeZones.filter(timeZone => {
    return timeZone.toLowerCase().includes(lowerQuery);
  });
}

const newYorkResults = searchTimeZones('new_york');
console.log(newYorkResults);
// Output: ["America/New_York"]

const londonResults = searchTimeZones('london');
console.log(londonResults);
// Output: ["Europe/London"]

const tokyoResults = searchTimeZones('tokyo');
console.log(tokyoResults);
// Output: ["Asia/Tokyo"]

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

للحصول على تجربة مستخدم أفضل، يمكنك البحث عن تطابقات جزئية ومعالجة المسافات:

function searchTimeZonesFlexible(query) {
  const timeZones = Intl.supportedValuesOf('timeZone');
  const normalizedQuery = query.toLowerCase().replace(/\s+/g, '_');

  return timeZones.filter(timeZone => {
    return timeZone.toLowerCase().includes(normalizedQuery);
  });
}

const results = searchTimeZonesFlexible('new york');
console.log(results);
// Output: ["America/New_York"]

يحول هذا الإصدار المسافات في الاستعلام إلى شرطات سفلية، مطابقًا التنسيق المستخدم في معرفات المناطق الزمنية.

التحقق من صحة معرفات المناطق الزمنية

عندما يقدم المستخدمون معرفات المناطق الزمنية كمدخلات، تحتاج إلى التحقق من صحة المعرف قبل استخدامه مع Intl.DateTimeFormat.

function isValidTimeZone(timeZone) {
  const supportedTimeZones = Intl.supportedValuesOf('timeZone');
  return supportedTimeZones.includes(timeZone);
}

console.log(isValidTimeZone('America/New_York'));
// Output: true

console.log(isValidTimeZone('Europe/London'));
// Output: true

console.log(isValidTimeZone('Invalid/TimeZone'));
// Output: false

console.log(isValidTimeZone('EST'));
// Output: false

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

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

function validateTimeZoneByCatch(timeZone) {
  try {
    new Intl.DateTimeFormat('en-US', { timeZone });
    return true;
  } catch (error) {
    return false;
  }
}

console.log(validateTimeZoneByCatch('America/New_York'));
// Output: true

console.log(validateTimeZoneByCatch('Invalid/TimeZone'));
// Output: false

يعمل هذا النهج ولكنه أقل كفاءة من التحقق من قائمة القيم المدعومة. استخدم التحقق من القيم المدعومة عندما يكون الأداء مهماً.

عرض الإزاحات الحالية للمناطق الزمنية

غالباً ما يفكر المستخدمون في المناطق الزمنية من حيث إزاحتها عن التوقيت العالمي المنسق (UTC). يساعد عرض الإزاحة الحالية بجانب كل اسم منطقة زمنية المستخدمين على فهم فرق التوقيت.

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',
  'Australia/Sydney'
];

timeZones.forEach(timeZone => {
  const offset = getTimeZoneOffset(timeZone);
  console.log(`${timeZone}: ${offset}`);
});

// Output:
// America/New_York: GMT-4
// Europe/London: GMT+1
// Asia/Tokyo: GMT+9
// Australia/Sydney: GMT+11

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

لاحظ أن الإزاحات تتغير مع التوقيت الصيفي. تعرض نفس المنطقة الزمنية إزاحات مختلفة في الشتاء والصيف:

const newYorkWinter = getTimeZoneOffset('America/New_York');
// In January: GMT-5

const newYorkSummer = getTimeZoneOffset('America/New_York');
// In July: GMT-4

تعكس الإزاحة التي تعيدها هذه الدالة التاريخ الحالي، لذا يتم تحديثها تلقائياً مع تغير قواعد التوقيت الصيفي على مدار العام.

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

يؤدي الجمع بين التجميع والتصفية وعرض الإزاحة إلى إنشاء محدد منطقة زمنية شامل:

function buildCompleteTimeZoneSelector() {
  const timeZones = Intl.supportedValuesOf('timeZone');
  const select = document.createElement('select');
  select.name = 'timeZone';

  const grouped = {};
  timeZones.forEach(timeZone => {
    const region = timeZone.split('/')[0];
    if (!grouped[region]) {
      grouped[region] = [];
    }
    grouped[region].push(timeZone);
  });

  Object.keys(grouped).sort().forEach(region => {
    const optgroup = document.createElement('optgroup');
    optgroup.label = region;

    grouped[region].forEach(timeZone => {
      const offset = getTimeZoneOffset(timeZone);
      const location = timeZone.split('/').slice(1).join('/');

      const option = document.createElement('option');
      option.value = timeZone;
      option.textContent = `${location} (${offset})`;
      optgroup.appendChild(option);
    });

    select.appendChild(optgroup);
  });

  return select;
}

const completeSelector = buildCompleteTimeZoneSelector();
document.body.appendChild(completeSelector);

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

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

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

function getUserTimeZone() {
  return Intl.DateTimeFormat().resolvedOptions().timeZone;
}

const userTimeZone = getUserTimeZone();
console.log(userTimeZone);
// Output: "America/New_York" (or user's actual time zone)

يُرجع هذا معرّف IANA للمنطقة الزمنية لنظام المستخدم. يمكنك استخدام هذا لتحديد الخيار الصحيح مسبقاً في محدد المنطقة الزمنية:

function buildTimeZoneSelectorWithDefault() {
  const selector = buildCompleteTimeZoneSelector();
  const userTimeZone = getUserTimeZone();

  const options = selector.querySelectorAll('option');
  options.forEach(option => {
    if (option.value === userTimeZone) {
      option.selected = true;
    }
  });

  return selector;
}

const selectorWithDefault = buildTimeZoneSelectorWithDefault();
document.body.appendChild(selectorWithDefault);

ينشئ هذا محدداً مع المنطقة الزمنية الحالية للمستخدم محددة مسبقاً، مما يقلل الاحتكاك عندما يؤكد المستخدمون موقعهم.

التعامل مع المناطق الزمنية الخاصة

تتضمن قائمة المناطق الزمنية المدعومة بعض المعرّفات الخاصة التي لا تتبع نمط Area/Location القياسي.

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

const specialTimeZones = timeZones.filter(tz => !tz.includes('/'));
console.log(specialTimeZones);
// Output: ["UTC"]

يمثل معرّف UTC التوقيت العالمي المنسق، الذي ليس له إزاحة ولا تغييرات في التوقيت الصيفي. هذا المعرّف مفيد عندما تريد عرض الأوقات في إطار مرجعي عالمي بدلاً من منطقة زمنية محلية.

تتضمن بعض البيئات معرّفات خاصة إضافية مثل GMT أو إزاحات المناطق مثل Etc/GMT+5. يمكنك تصفية هذه إذا كان تطبيقك يحتاج فقط إلى المناطق الزمنية الجغرافية القياسية:

function getGeographicTimeZones() {
  const timeZones = Intl.supportedValuesOf('timeZone');
  return timeZones.filter(timeZone => {
    return timeZone.includes('/') && !timeZone.startsWith('Etc/');
  });
}

const geographicTimeZones = getGeographicTimeZones();
console.log(geographicTimeZones.length);
// Output: over 400

يصفي هذا المعرّفات غير الجغرافية، تاركاً فقط المناطق الزمنية القياسية المستندة إلى المدن.

فهم أسماء المناطق الزمنية البديلة

تتضمن قاعدة بيانات IANA معرّفات متعددة تشير إلى نفس قواعد المنطقة الزمنية. على سبيل المثال، Asia/Calcutta و Asia/Kolkata كلاهما يشيران إلى التوقيت القياسي الهندي، لكن Kolkata هو الاسم الحديث.

تُرجع طريقة Intl.supportedValuesOf() المعرّفات القانونية. إذا قدم المستخدمون اسماً بديلاً، فإنه لا يزال يعمل مع Intl.DateTimeFormat:

const canonicalFormatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'Asia/Kolkata',
  timeZoneName: 'long'
});

const aliasFormatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'Asia/Calcutta',
  timeZoneName: 'long'
});

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

console.log(canonicalFormatter.format(date));
// Output: time in Indian Standard Time

console.log(aliasFormatter.format(date));
// Output: time in Indian Standard Time

ينتج كلا المنسقين نفس النتيجة لأن الاسم المستعار يشير إلى المعرف القياسي داخليًا.

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

function normalizeTimeZone(timeZone) {
  try {
    const formatter = new Intl.DateTimeFormat('en-US', { timeZone });
    return formatter.resolvedOptions().timeZone;
  } catch (error) {
    return null;
  }
}

console.log(normalizeTimeZone('Asia/Calcutta'));
// Output: "Asia/Kolkata"

console.log(normalizeTimeZone('America/New_York'));
// Output: "America/New_York"

console.log(normalizeTimeZone('Invalid/Zone'));
// Output: null

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

دعم المتصفح والتوافق

تتوفر طريقة Intl.supportedValuesOf() في المتصفحات الحديثة وإصدارات Node.js:

  • Chrome 99 وما بعده
  • Firefox 93 وما بعده
  • Safari 15.4 وما بعده
  • Edge 99 وما بعده
  • Node.js 18.0.0 وما بعده

بالنسبة للبيئات الأقدم، يمكنك اكتشاف الميزة وتوفير بديل:

function getSupportedTimeZones() {
  if (typeof Intl.supportedValuesOf === 'function') {
    return Intl.supportedValuesOf('timeZone');
  }

  return [
    'Africa/Cairo',
    'America/New_York',
    'America/Chicago',
    'America/Denver',
    'America/Los_Angeles',
    'Asia/Dubai',
    'Asia/Kolkata',
    'Asia/Tokyo',
    'Australia/Sydney',
    'Europe/London',
    'Europe/Paris',
    'Pacific/Auckland',
    'UTC'
  ];
}

const timeZones = getSupportedTimeZones();

تتحقق هذه الدالة مما إذا كان Intl.supportedValuesOf موجودًا وتعيد القائمة الكاملة إذا كان متاحًا. إذا لم يكن كذلك، فإنها تعيد قائمة مشفرة أصغر من المناطق الزمنية الشائعة. يضمن البديل عمل تطبيقك في البيئات الأقدم مع توفير القائمة الكاملة في البيئات الحديثة.