كيف تعرض التسميات المترجمة لحقول التاريخ والوقت؟
استخدم Intl.DisplayNames للحصول على تسميات الحقول و Intl.DateTimeFormat للحصول على أسماء الأشهر وأيام الأسبوع بأي لغة.
مقدمة
عند إنشاء نماذج إدخال التاريخ والوقت، تحتاج إلى تسميات توضح كل حقل. يحتاج منتقي التاريخ إلى تسميات مثل "الشهر" و"السنة" و"اليوم". يحتاج منتقي الوقت إلى تسميات مثل "الساعة" و"الدقيقة". يجب أن تظهر هذه التسميات بلغة المستخدم.
كتابة هذه التسميات بشكل ثابت باللغة الإنجليزية لا يعمل مع التطبيقات الدولية. يتوقع المستخدم الفرنسي رؤية "Mois" و"Année"، بينما يبحث المستخدم الإسباني عن "Mes" و"Año". تحتاج إلى نظام يوفر هذه التسميات تلقائياً بأي لغة.
توفر JavaScript واجهتي برمجة تطبيقات متكاملتين لهذا الغرض. تمنحك واجهة Intl.DisplayNames تسميات الحقول مثل "الشهر" و"السنة". تمنحك واجهة Intl.DateTimeFormat القيم الفعلية لتلك الحقول، مثل أسماء الأشهر وأسماء أيام الأسبوع.
فهم تسميات حقول التاريخ والوقت
تتطلب واجهات التاريخ والوقت نوعين من التسميات. تصف تسميات الحقول نوع البيانات التي تدخل في كل حقل إدخال. قيم الحقول هي البيانات الفعلية التي تظهر في القوائم المنسدلة والمنتقيات.
تتضمن تسميات الحقول كلمات مثل "السنة" و"الشهر" و"اليوم" و"الساعة" و"الدقيقة" و"الثانية". هذه تسمي حقول النموذج نفسها.
تتضمن قيم الحقول أسماء الأشهر مثل "يناير" و"فبراير"، وأسماء أيام الأسبوع مثل "الاثنين" و"الثلاثاء"، وتسميات الفترة مثل "ص" و"م". هذه تملأ القوائم المنسدلة وقوائم الاختيار.
يحتاج نموذج التاريخ الكامل إلى كلا النوعين من التسميات.
<label>Month</label>
<select>
<option>January</option>
<option>February</option>
<option>March</option>
<!-- more months -->
</select>
<label>Year</label>
<input type="number" />
كل من "الشهر" و"يناير" يحتاجان إلى الترجمة، لكنهما يتطلبان أساليب مختلفة.
الحصول على تسميات الحقول باستخدام Intl.DisplayNames
يُرجع المُنشئ Intl.DisplayNames مع type: "dateTimeField" تسميات محلية لمكونات التاريخ والوقت.
const labels = new Intl.DisplayNames('en-US', { type: 'dateTimeField' });
console.log(labels.of('year'));
// "year"
console.log(labels.of('month'));
// "month"
console.log(labels.of('day'));
// "day"
console.log(labels.of('hour'));
// "hour"
console.log(labels.of('minute'));
// "minute"
console.log(labels.of('second'));
// "second"
تأخذ الدالة of() رمز حقل وتُرجع تسميته المحلية. تتطابق التسمية مع اصطلاحات اللغة المحددة.
يمكنك الحصول على التسميات بأي لغة عن طريق تغيير اللغة.
// Spanish labels
const esLabels = new Intl.DisplayNames('es-ES', { type: 'dateTimeField' });
console.log(esLabels.of('year'));
// "año"
console.log(esLabels.of('month'));
// "mes"
console.log(esLabels.of('day'));
// "día"
console.log(esLabels.of('hour'));
// "hora"
console.log(esLabels.of('minute'));
// "minuto"
// French labels
const frLabels = new Intl.DisplayNames('fr-FR', { type: 'dateTimeField' });
console.log(frLabels.of('year'));
// "année"
console.log(frLabels.of('month'));
// "mois"
console.log(frLabels.of('day'));
// "jour"
console.log(frLabels.of('hour'));
// "heure"
console.log(frLabels.of('minute'));
// "minute"
// Japanese labels
const jaLabels = new Intl.DisplayNames('ja-JP', { type: 'dateTimeField' });
console.log(jaLabels.of('year'));
// "年"
console.log(jaLabels.of('month'));
// "月"
console.log(jaLabels.of('day'));
// "日"
console.log(jaLabels.of('hour'));
// "時"
console.log(jaLabels.of('minute'));
// "分"
توفر كل لغة التسميات بلغتها ونظام كتابتها الخاص.
رموز حقول التاريخ والوقت المتاحة
تدعم واجهة برمجة التطبيقات Intl.DisplayNames رموز الحقول هذه.
const labels = new Intl.DisplayNames('en-US', { type: 'dateTimeField' });
console.log(labels.of('era'));
// "era"
console.log(labels.of('year'));
// "year"
console.log(labels.of('quarter'));
// "quarter"
console.log(labels.of('month'));
// "month"
console.log(labels.of('weekOfYear'));
// "week"
console.log(labels.of('weekday'));
// "day of the week"
console.log(labels.of('day'));
// "day"
console.log(labels.of('dayPeriod'));
// "AM/PM"
console.log(labels.of('hour'));
// "hour"
console.log(labels.of('minute'));
// "minute"
console.log(labels.of('second'));
// "second"
console.log(labels.of('timeZoneName'));
// "time zone"
استخدم هذه الرموز للحصول على تسميات لأي مكون تاريخ أو وقت تحتاجه واجهتك.
الحصول على أسماء الأشهر المحلية
توفر واجهة برمجة التطبيقات Intl.DateTimeFormat أسماء الأشهر لملء القوائم المنسدلة وقوائم الاختيار. أنشئ مُنسِّقاً مع تعيين الخيار month إلى "long"، ثم نسِّق التواريخ التي تمثل كل شهر.
function getMonthNames(locale) {
const formatter = new Intl.DateTimeFormat(locale, {
month: 'long',
timeZone: 'UTC'
});
const months = [];
for (let month = 0; month < 12; month++) {
const date = new Date(Date.UTC(2000, month, 1));
months.push(formatter.format(date));
}
return months;
}
console.log(getMonthNames('en-US'));
// ["January", "February", "March", "April", "May", "June",
// "July", "August", "September", "October", "November", "December"]
تُنشئ الدالة تواريخ لكل شهر من السنة وتنسِّقها لاستخراج اسم الشهر. يضمن تعيين timeZone: 'UTC' نتائج متسقة عبر المناطق الزمنية.
يمكنك الحصول على أسماء الأشهر بأي لغة.
console.log(getMonthNames('es-ES'));
// ["enero", "febrero", "marzo", "abril", "mayo", "junio",
// "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"]
console.log(getMonthNames('fr-FR'));
// ["janvier", "février", "mars", "avril", "mai", "juin",
// "juillet", "août", "septembre", "octobre", "novembre", "décembre"]
console.log(getMonthNames('ja-JP'));
// ["1月", "2月", "3月", "4月", "5月", "6月",
// "7月", "8月", "9月", "10月", "11月", "12月"]
تنسِّق كل لغة أسماء الأشهر وفقاً لاصطلاحاتها الخاصة.
التحكم في طول اسم الشهر
يقبل الخيار month قيماً مختلفة تتحكم في طول أسماء الأشهر.
تُرجع القيمة "long" أسماء الأشهر الكاملة.
const longFormatter = new Intl.DateTimeFormat('en-US', {
month: 'long',
timeZone: 'UTC'
});
const date = new Date(Date.UTC(2000, 0, 1));
console.log(longFormatter.format(date));
// "January"
تُرجع القيمة "short" أسماء الأشهر المختصرة.
const shortFormatter = new Intl.DateTimeFormat('en-US', {
month: 'short',
timeZone: 'UTC'
});
console.log(shortFormatter.format(date));
// "Jan"
تُرجع القيمة "narrow" أقصر أسماء ممكنة للأشهر، عادةً حرف واحد.
const narrowFormatter = new Intl.DateTimeFormat('en-US', {
month: 'narrow',
timeZone: 'UTC'
});
console.log(narrowFormatter.format(date));
// "J"
استخدم "narrow" بحذر، حيث يمكن أن تشترك عدة أشهر في نفس الحرف. في الإنجليزية، ينتج عن يناير ويونيو ويوليو جميعاً الحرف "J".
الحصول على أسماء أيام الأسبوع المترجمة
استخدم نفس النمط للحصول على أسماء أيام الأسبوع. اضبط خيار weekday للتحكم في التنسيق.
function getWeekdayNames(locale, format = 'long') {
const formatter = new Intl.DateTimeFormat(locale, {
weekday: format,
timeZone: 'UTC'
});
const weekdays = [];
// Start from a Sunday (January 2, 2000 was a Sunday)
for (let day = 0; day < 7; day++) {
const date = new Date(Date.UTC(2000, 0, 2 + day));
weekdays.push(formatter.format(date));
}
return weekdays;
}
console.log(getWeekdayNames('en-US'));
// ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
console.log(getWeekdayNames('en-US', 'short'));
// ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
console.log(getWeekdayNames('en-US', 'narrow'));
// ["S", "M", "T", "W", "T", "F", "S"]
يمكنك الحصول على أسماء أيام الأسبوع بأي لغة.
console.log(getWeekdayNames('es-ES'));
// ["domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"]
console.log(getWeekdayNames('fr-FR'));
// ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"]
console.log(getWeekdayNames('ja-JP'));
// ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"]
قد تبدأ اللغات المختلفة الأسبوع في أيام مختلفة. تُرجع هذه الدالة دائماً من الأحد إلى السبت بالترتيب.
الحصول على تسميات الفترة المترجمة
تسميات الفترة هي مؤشرات صباحاً ومساءً المستخدمة مع الوقت بنظام 12 ساعة. استخدم formatToParts() لاستخراج هذه التسميات.
function getPeriodLabels(locale) {
const formatter = new Intl.DateTimeFormat(locale, {
hour: 'numeric',
hour12: true,
timeZone: 'UTC'
});
const amDate = new Date(Date.UTC(2000, 0, 1, 0, 0, 0));
const pmDate = new Date(Date.UTC(2000, 0, 1, 12, 0, 0));
const amParts = formatter.formatToParts(amDate);
const pmParts = formatter.formatToParts(pmDate);
const am = amParts.find(part => part.type === 'dayPeriod').value;
const pm = pmParts.find(part => part.type === 'dayPeriod').value;
return { am, pm };
}
console.log(getPeriodLabels('en-US'));
// { am: "AM", pm: "PM" }
console.log(getPeriodLabels('es-ES'));
// { am: "a. m.", pm: "p. m." }
console.log(getPeriodLabels('fr-FR'));
// { am: "AM", pm: "PM" }
console.log(getPeriodLabels('ja-JP'));
// { am: "午前", pm: "午後" }
تُرجع طريقة formatToParts() مصفوفة من الكائنات التي تمثل كل جزء من الوقت المنسق. يحتوي الكائن الذي يحمل type: "dayPeriod" على تسمية صباحاً أو مساءً.
تستخدم بعض اللغات نظام 24 ساعة افتراضياً ولا تتضمن تسميات الفترة. يمكنك فرض نظام 12 ساعة باستخدام خيار hour12: true.
إنشاء نموذج تاريخ مترجم كامل
ادمج كل هذه التقنيات لإنشاء نموذج إدخال تاريخ مترجم بالكامل.
function createDateForm(locale) {
const fieldLabels = new Intl.DisplayNames(locale, { type: 'dateTimeField' });
const monthNames = getMonthNames(locale);
const currentYear = new Date().getFullYear();
return {
monthLabel: fieldLabels.of('month'),
months: monthNames.map((name, index) => ({
value: index + 1,
label: name
})),
dayLabel: fieldLabels.of('day'),
yearLabel: fieldLabels.of('year'),
yearPlaceholder: currentYear
};
}
// Helper function from previous example
function getMonthNames(locale) {
const formatter = new Intl.DateTimeFormat(locale, {
month: 'long',
timeZone: 'UTC'
});
const months = [];
for (let month = 0; month < 12; month++) {
const date = new Date(Date.UTC(2000, month, 1));
months.push(formatter.format(date));
}
return months;
}
const enForm = createDateForm('en-US');
console.log(enForm.monthLabel);
// "month"
console.log(enForm.months[0]);
// { value: 1, label: "January" }
console.log(enForm.dayLabel);
// "day"
console.log(enForm.yearLabel);
// "year"
const esForm = createDateForm('es-ES');
console.log(esForm.monthLabel);
// "mes"
console.log(esForm.months[0]);
// { value: 1, label: "enero" }
console.log(esForm.dayLabel);
// "día"
console.log(esForm.yearLabel);
// "año"
يوفر هذا الهيكل كل ما هو مطلوب لعرض نموذج تاريخ مترجم في HTML.
function renderDateForm(locale) {
const form = createDateForm(locale);
return `
<div class="date-form">
<div class="form-field">
<label>${form.monthLabel}</label>
<select name="month">
${form.months.map(month =>
`<option value="${month.value}">${month.label}</option>`
).join('')}
</select>
</div>
<div class="form-field">
<label>${form.dayLabel}</label>
<input type="number" name="day" min="1" max="31" />
</div>
<div class="form-field">
<label>${form.yearLabel}</label>
<input type="number" name="year" placeholder="${form.yearPlaceholder}" />
</div>
</div>
`;
}
console.log(renderDateForm('en-US'));
// Renders form with English labels and month names
console.log(renderDateForm('fr-FR'));
// Renders form with French labels and month names
يتكيف النموذج تلقائياً مع أي لغة تحددها.
إنشاء نموذج وقت مترجم
طبق نفس النهج لإنشاء نموذج إدخال وقت مع محددات الساعة والدقيقة والفترة.
function createTimeForm(locale) {
const fieldLabels = new Intl.DisplayNames(locale, { type: 'dateTimeField' });
const periods = getPeriodLabels(locale);
const hours = [];
for (let hour = 1; hour <= 12; hour++) {
hours.push({ value: hour, label: hour.toString() });
}
const minutes = [];
for (let minute = 0; minute < 60; minute += 5) {
minutes.push({
value: minute,
label: minute.toString().padStart(2, '0')
});
}
return {
hourLabel: fieldLabels.of('hour'),
hours: hours,
minuteLabel: fieldLabels.of('minute'),
minutes: minutes,
periodLabel: fieldLabels.of('dayPeriod'),
periods: [
{ value: 'am', label: periods.am },
{ value: 'pm', label: periods.pm }
]
};
}
// Helper function from previous example
function getPeriodLabels(locale) {
const formatter = new Intl.DateTimeFormat(locale, {
hour: 'numeric',
hour12: true,
timeZone: 'UTC'
});
const amDate = new Date(Date.UTC(2000, 0, 1, 0, 0, 0));
const pmDate = new Date(Date.UTC(2000, 0, 1, 12, 0, 0));
const amParts = formatter.formatToParts(amDate);
const pmParts = formatter.formatToParts(pmDate);
const am = amParts.find(part => part.type === 'dayPeriod').value;
const pm = pmParts.find(part => part.type === 'dayPeriod').value;
return { am, pm };
}
const enTime = createTimeForm('en-US');
console.log(enTime.hourLabel);
// "hour"
console.log(enTime.minuteLabel);
// "minute"
console.log(enTime.periodLabel);
// "AM/PM"
console.log(enTime.periods);
// [{ value: "am", label: "AM" }, { value: "pm", label: "PM" }]
const jaTime = createTimeForm('ja-JP');
console.log(jaTime.hourLabel);
// "時"
console.log(jaTime.minuteLabel);
// "分"
console.log(jaTime.periodLabel);
// "午前/午後"
console.log(jaTime.periods);
// [{ value: "am", label: "午前" }, { value: "pm", label: "午後" }]
يوفر هذا جميع البيانات اللازمة لعرض منتقي وقت مترجم.
متى تستخدم تسميات حقول التاريخ والوقت
تظهر تسميات حقول التاريخ والوقت في عدة أنواع من الواجهات.
منتقيات التاريخ والوقت المخصصة
استخدم التسميات المحلية عند بناء منتقيات التاريخ أو عناصر التقويم أو محددات الوقت.
const locale = navigator.language;
const labels = new Intl.DisplayNames(locale, { type: 'dateTimeField' });
const datePicker = {
yearLabel: labels.of('year'),
monthLabel: labels.of('month'),
dayLabel: labels.of('day')
};
تسميات حقول النماذج
طبّق التسميات على حقول الإدخال القياسية لبيانات التاريخ والوقت.
const labels = new Intl.DisplayNames('en-US', { type: 'dateTimeField' });
document.querySelector('#birthdate-month-label').textContent =
labels.of('month');
document.querySelector('#birthdate-year-label').textContent =
labels.of('year');
تسميات إمكانية الوصول
وفّر تسميات ARIA محلية لقارئات الشاشة والتقنيات المساعدة.
const locale = navigator.language;
const labels = new Intl.DisplayNames(locale, { type: 'dateTimeField' });
const input = document.querySelector('#date-input');
input.setAttribute('aria-label', labels.of('year'));
رؤوس جداول البيانات
ضع تسميات للأعمدة في الجداول التي تعرض مكونات التاريخ والوقت.
const labels = new Intl.DisplayNames('en-US', { type: 'dateTimeField' });
const table = `
<table>
<thead>
<tr>
<th>${labels.of('year')}</th>
<th>${labels.of('month')}</th>
<th>${labels.of('day')}</th>
</tr>
</thead>
</table>
`;
دعم المتصفحات
واجهة برمجة التطبيقات Intl.DisplayNames مع type: "dateTimeField" مدعومة منذ مارس 2022 في المتصفحات الرئيسية.
يدعمها Chrome وEdge من الإصدار 99. يدعمها Firefox من الإصدار 99. يدعمها Safari من الإصدار 15.4.
يمكنك التحقق من توفر الميزة قبل استخدامها.
function supportsDateTimeFieldLabels() {
try {
const labels = new Intl.DisplayNames('en', { type: 'dateTimeField' });
labels.of('year');
return true;
} catch (error) {
return false;
}
}
if (supportsDateTimeFieldLabels()) {
const labels = new Intl.DisplayNames('en-US', { type: 'dateTimeField' });
console.log(labels.of('month'));
} else {
console.log('month'); // Fallback to English
}
بالنسبة للمتصفحات الأقدم، تحتاج إلى توفير تسميات احتياطية. أنشئ كائن تعيين بسيط للحقول الشائعة.
const fallbackLabels = {
en: {
year: 'year',
month: 'month',
day: 'day',
hour: 'hour',
minute: 'minute',
second: 'second'
},
es: {
year: 'año',
month: 'mes',
day: 'día',
hour: 'hora',
minute: 'minuto',
second: 'segundo'
},
fr: {
year: 'année',
month: 'mois',
day: 'jour',
hour: 'heure',
minute: 'minute',
second: 'seconde'
}
};
function getFieldLabel(field, locale) {
if (supportsDateTimeFieldLabels()) {
const labels = new Intl.DisplayNames(locale, { type: 'dateTimeField' });
return labels.of(field);
}
const language = locale.split('-')[0];
return fallbackLabels[language]?.[field] || fallbackLabels.en[field];
}
console.log(getFieldLabel('month', 'es-ES'));
// "mes" (from API if supported, from fallback otherwise)
يضمن هذا عمل النماذج في جميع المتصفحات مع الاستفادة من الترجمة الأصلية عند توفرها.
واجهة برمجة التطبيقات Intl.DateTimeFormat للحصول على أسماء الأشهر وأيام الأسبوع لها دعم أوسع، يعود إلى Internet Explorer 11 وجميع المتصفحات الحديثة. يمكنك استخدامها دون اكتشاف الميزة في معظم الحالات.