الحصول على قائمة أنظمة التقويم المتاحة
اكتشف أنظمة التقويم التي تدعمها بيئة JavaScript الخاصة بك
مقدمة
عند بناء تطبيقات لجمهور عالمي، غالبًا ما يحتاج المستخدمون إلى عرض التواريخ بنظام التقويم المفضل لديهم. بينما قد تكون على دراية بالتقويم الميلادي المستخدم في معظم الدول الغربية، تستخدم العديد من الثقافات أنظمة تقويم مختلفة تمامًا مثل التقويم الهجري الإسلامي، أو التقويم العبري، أو التقويم البوذي.
للسماح للمستخدمين باختيار التقويم المفضل لديهم، تحتاج إلى معرفة أنظمة التقويم التي تدعمها بيئة JavaScript. بدلاً من الاحتفاظ بقائمة ثابتة تصبح قديمة أو تتضمن قيمًا غير مدعومة، توفر JavaScript طريقة لاكتشاف أنظمة التقويم المتاحة في وقت التشغيل.
تُرجع الدالة Intl.supportedValuesOf() مع المعامل "calendar" مصفوفة تحتوي على جميع معرفات أنظمة التقويم المدعومة في البيئة الحالية. يضمن هذا أن تطبيقك يعرض فقط خيارات التقويم التي تعمل بشكل صحيح.
ما هي أنظمة التقويم
أنظمة التقويم هي طرق مختلفة لتنظيم وحساب الوقت. بينما تتتبع جميع التقويمات الأيام والأشهر والسنوات، فإنها تستخدم قواعد مختلفة لحساب موعد بداية السنة، ومدة الأشهر، وكيفية حساب الدورات الفلكية.
التقويم الميلادي، الذي تم تقديمه في عام 1582، هو التقويم المدني الأكثر استخدامًا على نطاق واسع. يستخدم سنة شمسية تبلغ حوالي 365.25 يومًا، مقسمة إلى 12 شهرًا، مع إضافة سنوات كبيسة كل أربع سنوات (مع استثناءات لسنوات القرن).
تتبع أنظمة التقويم الأخرى قواعد مختلفة. التقويم الإسلامي قمري بحت، حيث تتبع الأشهر أطوار القمر. هذا يعني أن السنة الإسلامية أقصر بحوالي 11 يومًا من السنة الشمسية، مما يتسبب في انتقال التواريخ الإسلامية عبر الفصول بمرور الوقت. التقويمان العبري والصيني قمريان شمسيان، يجمعان بين الأشهر القمرية والتعديلات للحفاظ على تزامن التقويم مع السنة الشمسية.
عند تنسيق التواريخ في JavaScript، يحدد نظام التقويم أرقام السنة والشهر واليوم التي تظهر. نفس اللحظة الزمنية لها تمثيلات تاريخية مختلفة في أنظمة التقويم المختلفة.
استخدام Intl.supportedValuesOf للحصول على أنظمة التقويم
تقبل الدالة Intl.supportedValuesOf() معاملاً نصياً يحدد نوع القيم المراد إرجاعها. للحصول على أنظمة التقويم، مرر "calendar":
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"]
تُرجع الدالة مصفوفة من السلاسل النصية التي تمثل معرفات التقويم. تتبع هذه المعرفات معيار Unicode CLDR (مستودع بيانات اللغة المشتركة)، والذي يوفر طريقة متسقة للإشارة إلى أنظمة التقويم عبر منصات ولغات برمجة مختلفة.
تتميز المصفوفة المُرجعة بالخصائص التالية:
- يتم ترتيب القيم بترتيب أبجدي تصاعدي
- تتم إزالة القيم المكررة
- يستخدم كل معرف أحرفاً صغيرة وشرطات
- تتضمن القائمة جميع أنظمة التقويم المدعومة من قبل تطبيق JavaScript
تدعم المتصفحات وبيئات JavaScript المختلفة مجموعات مختلفة من التقويمات، على الرغم من أن جميع المتصفحات الحديثة تدعم مجموعة أساسية من التقويمات الشائعة.
فهم معرفات التقويم
يمثل كل معرف تقويم نظام تقويم محدداً تستخدمه ثقافة واحدة أو أكثر. فيما يلي المعرفات الأكثر شيوعاً:
يمثل المعرف "gregory" التقويم الميلادي، وهو التقويم المدني القياسي المستخدم في معظم البلدان. هذا هو التقويم الذي تستخدمه في الحياة اليومية إذا كنت تعيش في الولايات المتحدة أو أوروبا أو معظم أنحاء العالم الأخرى.
يمثل المعرف "buddhist" التقويم البوذي التايلاندي، والذي يستخدم نفس هيكل الشهر واليوم كالتقويم الميلادي ولكنه يحسب السنوات من ميلاد بوذا (543 قبل الميلاد في التقويم الميلادي). السنة 2025 في التقويم الميلادي هي السنة 2568 في التقويم البوذي.
يمثل المعرف "chinese" التقويم الصيني التقليدي، وهو تقويم قمري شمسي حيث تتبع الأشهر أطوار القمر وتتوافق السنوات مع الفترة المدارية لكوكب المشتري. يُستخدم التقويم الصيني لتحديد الأعياد التقليدية مثل رأس السنة الصينية.
يمثل المعرف "islamic" التقويم الهجري الإسلامي، وهو تقويم قمري بحت يتكون من 12 شهراً من 29 أو 30 يوماً. تُحسب السنوات من الهجرة، عندما هاجر محمد من مكة إلى المدينة في عام 622 ميلادي.
يمثل المعرف "hebrew" التقويم العبري، وهو تقويم قمري شمسي يُستخدم للشعائر الدينية اليهودية. يحسب السنوات من تاريخ الخلق التقليدي (3761 قبل الميلاد في التقويم الميلادي).
يمثل المعرف "japanese" التقويم الياباني، الذي يستخدم نفس هيكل الشهر واليوم كالتقويم الميلادي ولكنه يقسم الوقت إلى حقب بناءً على الإمبراطور الحاكم. الحقبة الحالية هي ريوا، التي بدأت في عام 2019.
يمثل المعرف "persian" التقويم الهجري الشمسي المستخدم في إيران وأفغانستان. إنه تقويم شمسي تُحسب سنواته من الهجرة، مما يجعله مختلفاً عن التقويم الإسلامي القمري.
تشمل المعرفات الإضافية "coptic" (التقويم القبطي الأرثوذكسي)، "dangi" (التقويم الكوري التقليدي)، "ethiopic" (التقويم الإثيوبي)، "indian" (التقويم الوطني الهندي)، و"roc" (تقويم جمهورية الصين المستخدم في تايوان).
بعض المعرفات لها متغيرات مثل "islamic-civil"، "islamic-rgsa"، "islamic-tbla"، و"islamic-umalqura"، والتي تمثل طرق حساب مختلفة للتقويم الإسلامي.
يمثل المعرف "iso8601" تقويم ISO 8601، وهو في الأساس التقويم الميلادي ولكنه يستخدم دائماً التقويم الميلادي الاستباقي (تمديد التقويم الميلادي إلى الوراء قبل تقديمه في عام 1582).
رؤية أنظمة التقويم في العمل
لفهم كيف تؤثر أنظمة التقويم على تنسيق التاريخ، قم بتنسيق نفس التاريخ باستخدام تقويمات مختلفة:
const date = new Date("2025-10-15");
const gregorian = new Intl.DateTimeFormat("en-US", {
calendar: "gregory",
year: "numeric",
month: "long",
day: "numeric"
});
const islamic = new Intl.DateTimeFormat("en-US", {
calendar: "islamic",
year: "numeric",
month: "long",
day: "numeric"
});
const hebrew = new Intl.DateTimeFormat("en-US", {
calendar: "hebrew",
year: "numeric",
month: "long",
day: "numeric"
});
const buddhist = new Intl.DateTimeFormat("en-US", {
calendar: "buddhist",
year: "numeric",
month: "long",
day: "numeric"
});
console.log(gregorian.format(date));
// Output: "October 15, 2025"
console.log(islamic.format(date));
// Output: "Rabi' II 16, 1447 AH"
console.log(hebrew.format(date));
// Output: "Tishrei 23, 5786"
console.log(buddhist.format(date));
// Output: "October 15, 2568 BE"
نفس كائن Date في JavaScript يمثل نفس اللحظة الزمنية، لكن كل نظام تقويم يعبر عن تلك اللحظة بقيم مختلفة للسنة والشهر واليوم. التاريخ الميلادي 15 أكتوبر 2025 يقابل 16 ربيع الثاني 1447 في التقويم الهجري، و23 تشري 5786 في التقويم العبري، و15 أكتوبر 2568 في التقويم البوذي.
يوضح هذا سبب حاجتك لتحديد نظام التقويم المستخدم عند تنسيق التواريخ للمستخدمين الذين يتبعون تقويمات مختلفة.
بناء محدد التقويم
عند إنشاء واجهات مستخدم تتيح للمستخدمين اختيار التقويم المفضل لديهم، استعلم عن التقويمات المتاحة وقم ببناء المحدد ديناميكياً:
function buildCalendarSelector() {
const calendars = Intl.supportedValuesOf("calendar");
const select = document.createElement("select");
select.id = "calendar-selector";
calendars.forEach(calendar => {
const option = document.createElement("option");
option.value = calendar;
option.textContent = calendar;
select.appendChild(option);
});
return select;
}
const selector = buildCalendarSelector();
document.body.appendChild(selector);
ينشئ هذا قائمة منسدلة تحتوي على كل تقويم مدعوم. ومع ذلك، فإن المعرفات التقنية مثل "gregory" و"islamic" ليست سهلة الاستخدام. يحتاج المستخدمون إلى رؤية أسماء وصفية بلغتهم الخاصة.
عرض أسماء التقويمات المقروءة
تحول واجهة برمجة التطبيقات Intl.DisplayNames معرفات التقويم إلى أسماء مقروءة. استخدمها لإنشاء محدد تقويم أفضل:
function buildCalendarSelector(locale = "en-US") {
const calendars = Intl.supportedValuesOf("calendar");
const displayNames = new Intl.DisplayNames([locale], { type: "calendar" });
const select = document.createElement("select");
select.id = "calendar-selector";
calendars.forEach(calendar => {
const option = document.createElement("option");
option.value = calendar;
option.textContent = displayNames.of(calendar);
select.appendChild(option);
});
return select;
}
const selector = buildCalendarSelector("en-US");
document.body.appendChild(selector);
الآن تعرض القائمة المنسدلة أسماء مثل "التقويم الميلادي" و"التقويم الهجري" و"التقويم العبري" بدلاً من المعرفات التقنية.
يمكنك عرض أسماء التقويمات بلغات مختلفة عن طريق تغيير اللغة المحلية:
const calendars = ["gregory", "islamic", "hebrew", "buddhist", "chinese"];
const englishNames = new Intl.DisplayNames(["en-US"], { type: "calendar" });
const frenchNames = new Intl.DisplayNames(["fr-FR"], { type: "calendar" });
const arabicNames = new Intl.DisplayNames(["ar-SA"], { type: "calendar" });
calendars.forEach(calendar => {
console.log(`${calendar}:`);
console.log(` English: ${englishNames.of(calendar)}`);
console.log(` French: ${frenchNames.of(calendar)}`);
console.log(` Arabic: ${arabicNames.of(calendar)}`);
});
// Output:
// gregory:
// English: Gregorian Calendar
// French: calendrier grégorien
// Arabic: التقويم الميلادي
// islamic:
// English: Islamic Calendar
// French: calendrier musulman
// Arabic: التقويم الهجري
// ...
يتيح هذا للمستخدمين رؤية أسماء التقويمات باللغة المفضلة لديهم.
التحقق من دعم تقويم معين
قبل استخدام تقويم في تطبيقك، تحقق مما إذا كانت بيئة JavaScript تدعمه. يمنع هذا أخطاء وقت التشغيل ويتيح لك تنفيذ سلوك احتياطي:
function isCalendarSupported(calendar) {
const supported = Intl.supportedValuesOf("calendar");
return supported.includes(calendar);
}
if (isCalendarSupported("islamic")) {
const formatter = new Intl.DateTimeFormat("en-US", {
calendar: "islamic",
year: "numeric",
month: "long",
day: "numeric"
});
console.log(formatter.format(new Date()));
} else {
console.log("Islamic calendar is not supported");
}
يعمل هذا النمط مع أي معرف تقويم. يمكنك استخدامه لإظهار أو إخفاء خيارات التقويم في واجهة المستخدم الخاصة بك، أو للرجوع إلى تقويم افتراضي عندما يكون التقويم المفضل غير متاح.
إنشاء دالة قابلة لإعادة الاستخدام للكشف عن الميزات
قم ببناء دالة عامة للتحقق من دعم التقويم والتعامل مع التقويمات المفقودة بشكل سلس:
function getCalendarOrFallback(preferredCalendar, fallbackCalendar = "gregory") {
const supported = Intl.supportedValuesOf("calendar");
if (supported.includes(preferredCalendar)) {
return preferredCalendar;
}
if (supported.includes(fallbackCalendar)) {
return fallbackCalendar;
}
return supported[0];
}
const calendar = getCalendarOrFallback("islamic", "gregory");
const formatter = new Intl.DateTimeFormat("en-US", {
calendar,
year: "numeric",
month: "long",
day: "numeric"
});
console.log(formatter.format(new Date()));
تحاول هذه الدالة استخدام التقويم المفضل، وتعود إلى التقويم الاحتياطي المحدد إذا كان التقويم المفضل غير متاح، وفي النهاية تُرجع أول تقويم متاح إذا كان كلاهما غير مدعوم.
تصفية التقويمات لتطبيقك
لا تحتاج معظم التطبيقات إلى دعم كل نظام تقويم. قم بتصفية القائمة لتشمل فقط التقويمات ذات الصلة بمستخدميك:
function getRelevantCalendars(allowedCalendars) {
const supported = Intl.supportedValuesOf("calendar");
return allowedCalendars.filter(calendar => supported.includes(calendar));
}
const allowedCalendars = ["gregory", "islamic", "hebrew", "buddhist"];
const availableCalendars = getRelevantCalendars(allowedCalendars);
console.log(availableCalendars);
// Output: ["gregory", "islamic", "hebrew", "buddhist"]
// (assuming all are supported in the current environment)
يضمن هذا أنك تقدم فقط التقويمات التي تلبي متطلباتك وتعمل في متصفح المستخدم.
يمكنك دمج هذا مع اختيار التقويم لإنشاء واجهة مستخدم مركزة:
function buildFilteredCalendarSelector(allowedCalendars, locale = "en-US") {
const supported = Intl.supportedValuesOf("calendar");
const available = allowedCalendars.filter(cal => supported.includes(cal));
const displayNames = new Intl.DisplayNames([locale], { type: "calendar" });
const select = document.createElement("select");
available.forEach(calendar => {
const option = document.createElement("option");
option.value = calendar;
option.textContent = displayNames.of(calendar);
select.appendChild(option);
});
return select;
}
const selector = buildFilteredCalendarSelector(
["gregory", "islamic", "hebrew", "buddhist"],
"en-US"
);
document.body.appendChild(selector);
ينشئ هذا محدداً يعرض فقط التقويمات التي تريد دعمها، بأسماء قابلة للقراءة، ومضمونة للعمل في البيئة الحالية.
تجميع التقويمات حسب الفئة
بالنسبة للتطبيقات التي تدعم العديد من التقويمات، قم بتجميعها حسب النوع أو المنطقة لتحسين سهولة الاستخدام:
function groupCalendars() {
const calendars = Intl.supportedValuesOf("calendar");
const groups = {
solar: ["gregory", "iso8601", "persian", "ethiopic", "coptic"],
lunar: ["islamic", "islamic-civil", "islamic-rgsa", "islamic-tbla", "islamic-umalqura"],
lunisolar: ["hebrew", "chinese", "dangi"],
erasBased: ["japanese", "roc", "buddhist"],
other: []
};
const grouped = {
solar: [],
lunar: [],
lunisolar: [],
erasBased: [],
other: []
};
calendars.forEach(calendar => {
let placed = false;
for (const [group, members] of Object.entries(groups)) {
if (members.includes(calendar)) {
grouped[group].push(calendar);
placed = true;
break;
}
}
if (!placed) {
grouped.other.push(calendar);
}
});
return grouped;
}
const grouped = groupCalendars();
console.log(grouped);
// Output:
// {
// solar: ["gregory", "iso8601", "persian", "ethiopic", "coptic"],
// lunar: ["islamic", "islamic-civil", "islamic-rgsa", ...],
// lunisolar: ["hebrew", "chinese", "dangi"],
// erasBased: ["japanese", "roc", "buddhist"],
// other: ["ethioaa", "indian"]
// }
يساعد هذا التنظيم المستخدمين على فهم خصائص أنظمة التقويم المختلفة والعثور على النظام الذي يحتاجونه.
التعامل مع البيئات غير المدعومة
تمت إضافة الطريقة Intl.supportedValuesOf() إلى JavaScript في عام 2022. المتصفحات القديمة لا تدعمها. تحقق من وجود الطريقة قبل استخدامها:
function getCalendars() {
if (typeof Intl.supportedValuesOf === "function") {
return Intl.supportedValuesOf("calendar");
}
return ["gregory"];
}
const calendars = getCalendars();
console.log(calendars);
يُرجع هذا القائمة الكاملة للتقاويم المدعومة في المتصفحات الحديثة، ويعود إلى التقويم الميلادي فقط في البيئات القديمة.
لتوافق أفضل مع الإصدارات السابقة، قدّم قائمة احتياطية أكثر اكتمالاً:
function getCalendars() {
if (typeof Intl.supportedValuesOf === "function") {
return Intl.supportedValuesOf("calendar");
}
return [
"buddhist",
"chinese",
"coptic",
"ethiopic",
"gregory",
"hebrew",
"indian",
"islamic",
"japanese",
"persian",
"roc"
];
}
يوفر هذا مجموعة معقولة من التقاويم للمتصفحات القديمة، على الرغم من أنك لا تستطيع ضمان عمل جميعها في كل بيئة.
فهم الفرق بين التقويم واللغة المحلية
التقويم واللغة المحلية مفهومان مرتبطان لكنهما منفصلان. تحدد اللغة المحلية اللغة واصطلاحات التنسيق الإقليمية، بينما يحدد التقويم نظام التقويم المستخدم.
يمكن للغة محلية واحدة استخدام تقاويم متعددة. على سبيل المثال، يستخدم الناطقون بالعربية في المملكة العربية السعودية عادةً التقويم الهجري للأغراض الدينية والتقويم الميلادي للأغراض المدنية. يمكنك تنسيق التواريخ بالعربية باستخدام أي من التقويمين:
const date = new Date("2025-10-15");
const arabicGregorian = new Intl.DateTimeFormat("ar-SA", {
calendar: "gregory",
year: "numeric",
month: "long",
day: "numeric"
});
const arabicIslamic = new Intl.DateTimeFormat("ar-SA", {
calendar: "islamic",
year: "numeric",
month: "long",
day: "numeric"
});
console.log(arabicGregorian.format(date));
// Output: "١٥ أكتوبر ٢٠٢٥"
console.log(arabicIslamic.format(date));
// Output: "١٦ ربيع الآخر ١٤٤٧ هـ"
كلاهما يستخدم النص والترقيم العربي، لكنهما يعرضان تواريخ مختلفة وفقاً لتقويميهما المعنيين.
على العكس، يمكنك تنسيق نفس التقويم بلغات مختلفة:
const date = new Date("2025-10-15");
const englishIslamic = new Intl.DateTimeFormat("en-US", {
calendar: "islamic",
year: "numeric",
month: "long",
day: "numeric"
});
const arabicIslamic = new Intl.DateTimeFormat("ar-SA", {
calendar: "islamic",
year: "numeric",
month: "long",
day: "numeric"
});
console.log(englishIslamic.format(date));
// Output: "Rabi' II 16, 1447 AH"
console.log(arabicIslamic.format(date));
// Output: "١٦ ربيع الآخر ١٤٤٧ هـ"
كلاهما يعرض التاريخ الهجري، لكنهما يستخدمان لغات وأنظمة ترقيم مختلفة.
متى تستعلم عن التقاويم المتاحة
استعلم عن التقاويم المتاحة في هذه الحالات:
عند بناء واجهة اختيار التقويم، استدعِ Intl.supportedValuesOf("calendar") لملء الخيارات. يضمن هذا أنك تعرض فقط التقاويم التي تعمل في البيئة الحالية.
عند تنفيذ ميزات قائمة على التقويم، تحقق مما إذا كان التقويم المطلوب مدعوماً قبل استخدامه. يمنع هذا الأخطاء ويسمح بالعودة السلسة إلى تقاويم بديلة.
عند تخزين تفضيلات المستخدم، تحقق من صحة اختيارات التقويم مقابل القائمة المدعومة. يضمن هذا بقاء التفضيلات المحفوظة صالحة عبر الأجهزة والمتصفحات المختلفة.
عند الترحيل بين البيئات، تحقق من دعم التقويم في كل من البيئة المصدر والبيئة الهدف. يمكن أن يختلف دعم التقويم بين إصدارات المتصفح وإصدارات Node.js وبيئات تشغيل JavaScript المختلفة.
عند تحميل البيانات المعتمدة على التقويم، تحقق من توفر التقويم قبل محاولة تحليل التواريخ أو تنسيقها. يمنع هذا أخطاء وقت التشغيل عند العمل مع التواريخ في أنظمة تقويم محددة.