واجهة برمجة التطبيقات Intl.DateTimeFormat
تنسيق التواريخ والأوقات لأي لغة محلية دون مكتبات خارجية
مقدمة
تُعرض التواريخ بشكل مختلف حول العالم. يظهر 15 يناير 2024 كـ 1/15/2024 في الولايات المتحدة، و15/1/2024 في المملكة المتحدة، و2024/1/15 في اليابان. تختلف تنسيقات الوقت أيضًا. يستخدم الأمريكيون ساعات 12 ساعة مع AM وPM، بينما يستخدم معظم العالم نظام 24 ساعة.
بناء منطق تنسيق التواريخ يدويًا للغات المحلية المختلفة معقد وعرضة للأخطاء. تحتاج إلى التعامل مع ترتيب اليوم والشهر، والفواصل، وتنسيقات الوقت، وتحويلات المناطق الزمنية، والحالات الخاصة مثل التقويمات غير الميلادية.
تحل واجهة برمجة التطبيقات Intl.DateTimeFormat هذه المشكلة. توفر تنسيقًا مدمجًا للتاريخ والوقت يدعم اللغات المحلية في جميع المتصفحات الحديثة. لا حاجة لمكتبات خارجية.
الاستخدام الأساسي
أبسط طريقة لتنسيق تاريخ هي إنشاء نسخة من Intl.DateTimeFormat واستدعاء طريقة format() الخاصة بها.
const date = new Date(2024, 0, 15, 14, 30);
const formatter = new Intl.DateTimeFormat("en-US");
formatter.format(date);
// "1/15/2024"
غيّر اللغة المحلية لرؤية اصطلاحات تنسيق مختلفة.
const ukFormatter = new Intl.DateTimeFormat("en-GB");
ukFormatter.format(date);
// "15/01/2024"
const japanFormatter = new Intl.DateTimeFormat("ja-JP");
japanFormatter.format(date);
// "2024/1/15"
نفس التاريخ، منسق بثلاث طرق مختلفة بناءً على الاصطلاحات المحلية.
فهم اللغات المحلية
اللغة المحلية هي سلسلة نصية تحدد لغة وتفضيلات إقليمية. يتبع التنسيق معيار BCP 47: رمز اللغة، متبوعًا اختياريًا برمز المنطقة.
أنماط اللغات المحلية الشائعة:
"en" // English (generic)
"en-US" // English (United States)
"en-GB" // English (United Kingdom)
"es" // Spanish (generic)
"es-MX" // Spanish (Mexico)
"es-ES" // Spanish (Spain)
"zh-CN" // Chinese (China, Simplified)
"zh-TW" // Chinese (Taiwan, Traditional)
إذا حذفت معامل اللغة المحلية، يستخدم المتصفح اللغة المحلية الافتراضية للمستخدم.
const formatter = new Intl.DateTimeFormat();
formatter.format(date);
// Output varies based on user's browser locale
يمكنك أيضًا توفير مصفوفة من اللغات المحلية. يستخدم المتصفح أول لغة محلية مدعومة.
const formatter = new Intl.DateTimeFormat(["es-MX", "es", "en"]);
// Uses Spanish (Mexico) if available, falls back to generic Spanish, then English
نظرة عامة على خيارات التنسيق
يقبل منشئ Intl.DateTimeFormat كائن خيارات يتحكم في ما يظهر في الناتج المنسق. هناك نهجان للتنسيق.
يستخدم النهج الأول اختصارات الأنماط. توفر هذه تنسيقًا سريعًا وتقليديًا.
const formatter = new Intl.DateTimeFormat("en-US", {
dateStyle: "full",
timeStyle: "short"
});
formatter.format(date);
// "Monday, January 15, 2024 at 2:30 PM"
يستخدم النهج الثاني خيارات المكونات. توفر هذه تحكمًا دقيقًا في كل جزء من التاريخ.
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
minute: "numeric"
});
formatter.format(date);
// "January 15, 2024 at 2:30 PM"
لا يمكنك دمج اختصارات الأنماط مع خيارات المكونات. اختر نهجًا واحدًا لكل منسق.
اختصارات الأنماط
يوفر خيارا dateStyle و timeStyle أربعة مستويات تنسيق محددة مسبقًا.
ينسق خيار dateStyle جزء التاريخ.
const date = new Date(2024, 0, 15);
const full = new Intl.DateTimeFormat("en-US", { dateStyle: "full" });
full.format(date);
// "Monday, January 15, 2024"
const long = new Intl.DateTimeFormat("en-US", { dateStyle: "long" });
long.format(date);
// "January 15, 2024"
const medium = new Intl.DateTimeFormat("en-US", { dateStyle: "medium" });
medium.format(date);
// "Jan 15, 2024"
const short = new Intl.DateTimeFormat("en-US", { dateStyle: "short" });
short.format(date);
// "1/15/24"
ينسق خيار timeStyle جزء الوقت.
const date = new Date(2024, 0, 15, 14, 30, 45);
const full = new Intl.DateTimeFormat("en-US", { timeStyle: "full" });
full.format(date);
// "2:30:45 PM Eastern Standard Time"
const long = new Intl.DateTimeFormat("en-US", { timeStyle: "long" });
long.format(date);
// "2:30:45 PM EST"
const medium = new Intl.DateTimeFormat("en-US", { timeStyle: "medium" });
medium.format(date);
// "2:30:45 PM"
const short = new Intl.DateTimeFormat("en-US", { timeStyle: "short" });
short.format(date);
// "2:30 PM"
ادمج كلا الخيارين لتنسيق التاريخ والوقت معًا.
const formatter = new Intl.DateTimeFormat("en-US", {
dateStyle: "medium",
timeStyle: "short"
});
formatter.format(date);
// "Jan 15, 2024, 2:30 PM"
تتكيف اختصارات الأنماط مع اصطلاحات اللغة تلقائيًا.
const usFormatter = new Intl.DateTimeFormat("en-US", {
dateStyle: "short",
timeStyle: "short"
});
usFormatter.format(date);
// "1/15/24, 2:30 PM"
const deFormatter = new Intl.DateTimeFormat("de-DE", {
dateStyle: "short",
timeStyle: "short"
});
deFormatter.format(date);
// "15.1.24, 14:30"
يستخدم التنسيق الألماني النقاط كفواصل، ويعكس ترتيب اليوم والشهر، ويعرض الوقت بنظام 24 ساعة. يستخدم التنسيق الأمريكي الشرطات المائلة، وترتيب الشهر أولاً، والوقت بنظام 12 ساعة مع AM/PM. نفس الخيارات، مخرجات مختلفة بناءً على اللغة.
خيارات المكونات
توفر خيارات المكونات تحكمًا دقيقًا فيما يُعرض وكيفية عرضه. يحدد كل خيار جزءًا من التاريخ أو الوقت.
يعرض خيار year السنة.
const formatter = new Intl.DateTimeFormat("en-US", { year: "numeric" });
formatter.format(date);
// "2024"
const twoDigit = new Intl.DateTimeFormat("en-US", { year: "2-digit" });
twoDigit.format(date);
// "24"
يعرض خيار month الشهر بتنسيقات مختلفة.
const numeric = new Intl.DateTimeFormat("en-US", { month: "numeric" });
numeric.format(date);
// "1"
const twoDigit = new Intl.DateTimeFormat("en-US", { month: "2-digit" });
twoDigit.format(date);
// "01"
const long = new Intl.DateTimeFormat("en-US", { month: "long" });
long.format(date);
// "January"
const short = new Intl.DateTimeFormat("en-US", { month: "short" });
short.format(date);
// "Jan"
const narrow = new Intl.DateTimeFormat("en-US", { month: "narrow" });
narrow.format(date);
// "J"
يعرض خيار day يوم الشهر.
const formatter = new Intl.DateTimeFormat("en-US", { day: "numeric" });
formatter.format(date);
// "15"
const twoDigit = new Intl.DateTimeFormat("en-US", { day: "2-digit" });
twoDigit.format(date);
// "15"
يعرض خيار weekday يوم الأسبوع.
const long = new Intl.DateTimeFormat("en-US", { weekday: "long" });
long.format(date);
// "Monday"
const short = new Intl.DateTimeFormat("en-US", { weekday: "short" });
short.format(date);
// "Mon"
const narrow = new Intl.DateTimeFormat("en-US", { weekday: "narrow" });
narrow.format(date);
// "M"
ادمج خيارات المكونات المتعددة لبناء تنسيقات تاريخ مخصصة.
const formatter = new Intl.DateTimeFormat("en-US", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric"
});
formatter.format(date);
// "Monday, January 15, 2024"
يتعامل المتصفح مع المسافات وعلامات الترقيم بناءً على اصطلاحات اللغة المحلية.
تنسيق الوقت
تتحكم خيارات مكونات الوقت في عرض الساعة والدقيقة والثانية.
const date = new Date(2024, 0, 15, 14, 30, 45);
const formatter = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
second: "numeric"
});
formatter.format(date);
// "2:30:45 PM"
يتحكم خيار hour12 في عرض الوقت بنظام 12 ساعة مقابل 24 ساعة.
const hour12 = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
hour12: true
});
hour12.format(date);
// "2:30 PM"
const hour24 = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
hour12: false
});
hour24.format(date);
// "14:30"
يوفر خيار hourCycle تحكمًا أدق في عرض الساعة. توجد أربعة خيارات.
// h11: 0-11
const h11 = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
hourCycle: "h11"
});
h11.format(new Date(2024, 0, 15, 0, 30));
// "0:30 AM"
// h12: 1-12
const h12 = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
hourCycle: "h12"
});
h12.format(new Date(2024, 0, 15, 0, 30));
// "12:30 AM"
// h23: 0-23
const h23 = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
hourCycle: "h23"
});
h23.format(new Date(2024, 0, 15, 0, 30));
// "0:30"
// h24: 1-24
const h24 = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
hourCycle: "h24"
});
h24.format(new Date(2024, 0, 15, 0, 30));
// "24:30"
يهم الفرق عند منتصف الليل. تستخدم دورة h11 الرقم 0، بينما تستخدم h12 الرقم 12. وبالمثل، تستخدم h23 الرقم 0، بينما تستخدم h24 الرقم 24.
يضيف خيار dayPeriod علامات فترة وصفية للوقت بنظام 12 ساعة.
const morning = new Date(2024, 0, 15, 10, 30);
const afternoon = new Date(2024, 0, 15, 14, 30);
const night = new Date(2024, 0, 15, 22, 30);
const formatter = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
dayPeriod: "long"
});
formatter.format(morning);
// "10:30 in the morning"
formatter.format(afternoon);
// "2:30 in the afternoon"
formatter.format(night);
// "10:30 at night"
يعمل خيار dayPeriod فقط مع تنسيقات الوقت بنظام 12 ساعة.
يعرض خيار fractionalSecondDigits الدقة الأقل من الثانية.
const date = new Date(2024, 0, 15, 14, 30, 45, 123);
const oneDigit = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
second: "numeric",
fractionalSecondDigits: 1
});
oneDigit.format(date);
// "2:30:45.1 PM"
const threeDigits = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
second: "numeric",
fractionalSecondDigits: 3
});
threeDigits.format(date);
// "2:30:45.123 PM"
يمكنك تحديد رقم عشري واحد أو اثنين أو ثلاثة.
التعامل مع المنطقة الزمنية
يحول خيار timeZone التواريخ إلى مناطق زمنية محددة.
const date = new Date("2024-01-15T14:30:00Z"); // UTC time
const newYork = new Intl.DateTimeFormat("en-US", {
timeZone: "America/New_York",
dateStyle: "full",
timeStyle: "long"
});
newYork.format(date);
// "Monday, January 15, 2024 at 9:30:00 AM EST"
const tokyo = new Intl.DateTimeFormat("ja-JP", {
timeZone: "Asia/Tokyo",
dateStyle: "full",
timeStyle: "long"
});
tokyo.format(date);
// "2024年1月15日月曜日 23:30:00 日本標準時"
const london = new Intl.DateTimeFormat("en-GB", {
timeZone: "Europe/London",
dateStyle: "full",
timeStyle: "long"
});
london.format(date);
// "Monday, 15 January 2024 at 14:30:00 GMT"
تعرض نفس اللحظة الزمنية بشكل مختلف بناءً على المنطقة الزمنية. استخدم معرفات المناطق الزمنية IANA مثل America/New_York أو Europe/London أو Asia/Tokyo.
يعرض خيار timeZoneName اسم المنطقة الزمنية.
const formatter = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
timeZone: "America/New_York",
timeZoneName: "short"
});
formatter.format(date);
// "9:30 AM EST"
const long = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
timeZone: "America/New_York",
timeZoneName: "long"
});
long.format(date);
// "9:30 AM Eastern Standard Time"
const shortOffset = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
timeZone: "America/New_York",
timeZoneName: "shortOffset"
});
shortOffset.format(date);
// "9:30 AM GMT-5"
const longOffset = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
timeZone: "America/New_York",
timeZoneName: "longOffset"
});
longOffset.format(date);
// "9:30 AM GMT-05:00"
توفر قيم timeZoneName المختلفة مستويات مختلفة من التفاصيل.
أنظمة التقويم وأنظمة الترقيم
يدعم الخيار calendar التقويمات غير الميلادية.
const date = new Date(2024, 0, 15);
const gregorian = new Intl.DateTimeFormat("en-US", {
calendar: "gregory",
year: "numeric",
month: "long",
day: "numeric"
});
gregorian.format(date);
// "January 15, 2024"
const japanese = new Intl.DateTimeFormat("ja-JP", {
calendar: "japanese",
year: "numeric",
month: "long",
day: "numeric"
});
japanese.format(date);
// "令和6年1月15日"
const islamic = new Intl.DateTimeFormat("ar-SA", {
calendar: "islamic",
year: "numeric",
month: "long",
day: "numeric"
});
islamic.format(date);
// "٦ رجب ١٤٤٥"
const chinese = new Intl.DateTimeFormat("zh-CN", {
calendar: "chinese",
year: "numeric",
month: "long",
day: "numeric"
});
chinese.format(date);
// "2023甲辰年腊月初五"
يتم تحويل نفس التاريخ إلى أنظمة تقويم مختلفة. تشمل التقويمات المتاحة gregory، japanese، islamic، islamic-umalqura، islamic-tbla، islamic-civil، islamic-rgsa، chinese، hebrew، indian، persian، وغيرها.
يعرض الخيار numberingSystem الأرقام بنصوص مختلفة.
const date = new Date(2024, 0, 15);
const western = new Intl.DateTimeFormat("en-US", {
numberingSystem: "latn",
year: "numeric",
month: "numeric",
day: "numeric"
});
western.format(date);
// "1/15/2024"
const arabic = new Intl.DateTimeFormat("en-US", {
numberingSystem: "arab",
year: "numeric",
month: "numeric",
day: "numeric"
});
arabic.format(date);
// "١/١٥/٢٠٢٤"
const devanagari = new Intl.DateTimeFormat("en-US", {
numberingSystem: "deva",
year: "numeric",
month: "numeric",
day: "numeric"
});
devanagari.format(date);
// "१/१५/२०२४"
const bengali = new Intl.DateTimeFormat("en-US", {
numberingSystem: "beng",
year: "numeric",
month: "numeric",
day: "numeric"
});
bengali.format(date);
// "১/১৫/২০২৪"
تشمل أنظمة الترقيم المتاحة latn (الأرقام الغربية)، arab (الأرقام العربية الهندية)، arabext (الأرقام العربية الهندية الممتدة)، beng (الأرقام البنغالية)، deva (أرقام الديفاناغاري)، والعديد من الأنظمة الأخرى.
تنسيق نطاقات التاريخ
تقوم الدالة formatRange() بتنسيق نطاق تاريخ مع حذف ذكي للمعلومات الزائدة.
const start = new Date(2024, 0, 15);
const end = new Date(2024, 0, 20);
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric"
});
formatter.formatRange(start, end);
// "January 15 – 20, 2024"
يحذف المنسق المعلومات المكررة. كلا التاريخين في يناير 2024، لذلك يتضمن الناتج الشهر والسنة مرة واحدة فقط.
عندما يمتد النطاق عبر أشهر مختلفة، يتم عرض كليهما.
const start = new Date(2024, 0, 15);
const end = new Date(2024, 1, 20);
formatter.formatRange(start, end);
// "January 15 – February 20, 2024"
عندما يمتد النطاق عبر سنوات مختلفة، يتم عرض جميع المعلومات.
const start = new Date(2024, 0, 15);
const end = new Date(2025, 1, 20);
formatter.formatRange(start, end);
// "January 15, 2024 – February 20, 2025"
تعمل الدالة formatRange() مع نطاقات الوقت أيضاً.
const start = new Date(2024, 0, 15, 14, 30);
const end = new Date(2024, 0, 15, 16, 45);
const formatter = new Intl.DateTimeFormat("en-US", {
month: "long",
day: "numeric",
hour: "numeric",
minute: "numeric"
});
formatter.formatRange(start, end);
// "January 15, 2:30 – 4:45 PM"
يتم عرض التاريخ مرة واحدة لأن كلا الوقتين يحدثان في نفس اليوم.
الوصول إلى الأجزاء المنسقة
تُرجع الدالة formatToParts() مصفوفة من الكائنات تمثل كل جزء من التاريخ المنسق. يتيح ذلك منطق تنسيق مخصص.
const date = new Date(2024, 0, 15, 14, 30);
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
minute: "numeric"
});
const parts = formatter.formatToParts(date);
يحتوي كل كائن في المصفوفة على خاصية type و value.
[
{ type: "month", value: "January" },
{ type: "literal", value: " " },
{ type: "day", value: "15" },
{ type: "literal", value: ", " },
{ type: "year", value: "2024" },
{ type: "literal", value: " at " },
{ type: "hour", value: "2" },
{ type: "literal", value: ":" },
{ type: "minute", value: "30" },
{ type: "literal", value: " " },
{ type: "dayPeriod", value: "PM" }
]
يمكنك تصفية هذه الأجزاء ومعالجتها لبناء تنسيقات مخصصة.
const dateParts = parts.filter(part =>
["month", "day", "year"].includes(part.type)
);
const dateString = dateParts.map(part => part.value).join("/");
// "January/15/2024"
توفر طريقة formatRangeToParts() نفس الوظيفة لنطاقات التواريخ.
const start = new Date(2024, 0, 15);
const end = new Date(2024, 0, 20);
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric"
});
const parts = formatter.formatRangeToParts(start, end);
يتضمن كل كائن جزء خاصية source تشير إلى ما إذا كان قد جاء من تاريخ البداية أو النهاية.
[
{ type: "month", value: "January", source: "startRange" },
{ type: "literal", value: " ", source: "startRange" },
{ type: "day", value: "15", source: "startRange" },
{ type: "literal", value: " – ", source: "shared" },
{ type: "day", value: "20", source: "endRange" },
{ type: "literal", value: ", ", source: "shared" },
{ type: "year", value: "2024", source: "shared" }
]
أفضل الممارسات
أعد استخدام مثيلات المنسق عند تنسيق تواريخ متعددة بنفس الخيارات. يتضمن إنشاء منسق التفاوض على اللغة المحلية وحل الخيارات، مما يترتب عليه تكلفة أداء صغيرة.
// Less efficient
dates.forEach(date => {
const formatted = new Intl.DateTimeFormat("en-US").format(date);
console.log(formatted);
});
// More efficient
const formatter = new Intl.DateTimeFormat("en-US");
dates.forEach(date => {
const formatted = formatter.format(date);
console.log(formatted);
});
استخدم لغة متصفح المستخدم المحلية عندما يكون ذلك ممكناً عن طريق حذف معامل اللغة المحلية. يحترم هذا تفضيلات المستخدم.
const formatter = new Intl.DateTimeFormat();
// Uses browser locale automatically
وفر لغات محلية احتياطية عند استهداف مناطق محددة. إذا لم تكن اللغة المحلية المفضلة متاحة، يستخدم المتصفح الخيار التالي.
const formatter = new Intl.DateTimeFormat(["fr-CA", "fr", "en"]);
// Prefers French (Canada), falls back to French, then English
استخدم اختصارات الأنماط لعروض التاريخ والوقت الشائعة. تتكيف تلقائياً مع اصطلاحات اللغة المحلية وتتطلب تكويناً أقل.
const formatter = new Intl.DateTimeFormat("en-US", {
dateStyle: "medium",
timeStyle: "short"
});
استخدم خيارات المكونات عندما تحتاج إلى تحكم دقيق في تنسيق الإخراج.
const formatter = new Intl.DateTimeFormat("en-US", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric"
});
حدد دائماً المنطقة الزمنية عند عرض الأوقات للمستخدمين عن بُعد أو للأحداث المجدولة. بدون منطقة زمنية، يتم تنسيق التواريخ في المنطقة الزمنية المحلية للمستخدم، والتي قد لا تتطابق مع نيتك.
const formatter = new Intl.DateTimeFormat("en-US", {
timeZone: "America/New_York",
dateStyle: "full",
timeStyle: "long"
});
استخدم {/* INLINE_CODE_PLACEHOLDER_330ca599771a20ddd99b4b6a6515a77e2 */} لنطاقات التواريخ بدلاً من تنسيق كل تاريخ على حدة وربطها. تتعامل الطريقة مع الحذف الذكي للمعلومات الزائدة.
// Less clear
const startFormatted = formatter.format(start);
const endFormatted = formatter.format(end);
const range = `${startFormatted} to ${endFormatted}`;
// Better
const range = formatter.formatRange(start, end);
تحقق من توافق المتصفح للميزات المتقدمة مثل dayPeriod، fractionalSecondDigits، وقيم timeZoneName معينة. تدعم جميع المتصفحات الحديثة الوظائف الأساسية، لكن الخيارات الأحدث قد تتطلب بدائل للمتصفحات الأقدم.