Comment afficher les libellés localisés pour les champs de date et d'heure ?
Utilisez Intl.DisplayNames pour obtenir les libellés de champs et Intl.DateTimeFormat pour obtenir les noms de mois et de jours de la semaine dans n'importe quelle langue.
Introduction
Lorsque vous créez des formulaires de saisie de date et d'heure, vous avez besoin de libellés qui décrivent chaque champ. Un sélecteur de date nécessite des libellés tels que "Mois", "Année" et "Jour". Un sélecteur d'heure nécessite des libellés tels que "Heure" et "Minute". Ces libellés doivent apparaître dans la langue de l'utilisateur.
Coder en dur ces libellés en anglais ne fonctionne pas pour les applications internationales. Un utilisateur français s'attend à voir "Mois" et "Année", tandis qu'un utilisateur espagnol recherche "Mes" et "Año". Vous avez besoin d'un système qui fournit ces libellés automatiquement dans n'importe quelle langue.
JavaScript fournit deux API complémentaires pour cela. L'API Intl.DisplayNames vous donne les libellés de champs tels que "Mois" et "Année". L'API Intl.DateTimeFormat vous donne les valeurs réelles pour ces champs, comme les noms de mois et les noms de jours de la semaine.
Comprendre les libellés de champs de date et d'heure
Les interfaces de date et d'heure nécessitent deux types de libellés. Les libellés de champs décrivent quel type de données va dans chaque champ de saisie. Les valeurs de champs sont les données réelles qui apparaissent dans les listes déroulantes et les sélecteurs.
Les libellés de champs incluent des mots tels que "Année", "Mois", "Jour", "Heure", "Minute" et "Seconde". Ceux-ci étiquettent les champs de formulaire eux-mêmes.
Les valeurs de champs incluent les noms de mois tels que "Janvier" et "Février", les noms de jours de la semaine tels que "Lundi" et "Mardi", et les libellés de période tels que "AM" et "PM". Ceux-ci remplissent les listes déroulantes et les listes de sélection.
Un formulaire de date complet nécessite les deux types de libellés.
<label>Month</label>
<select>
<option>January</option>
<option>February</option>
<option>March</option>
<!-- more months -->
</select>
<label>Year</label>
<input type="number" />
"Mois" et "Janvier" nécessitent tous deux une localisation, mais ils requièrent des approches différentes.
Obtenir les libellés de champs avec Intl.DisplayNames
Le constructeur Intl.DisplayNames avec type: "dateTimeField" renvoie les libellés localisés pour les composants de date et d'heure.
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"
La méthode of() prend un code de champ et renvoie son libellé localisé. Le libellé correspond aux conventions de la locale spécifiée.
Vous pouvez obtenir des libellés dans n'importe quelle langue en changeant la locale.
// 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'));
// "分"
Chaque locale fournit des libellés dans sa propre langue et son propre système d'écriture.
Codes de champs de date et d'heure disponibles
L'API Intl.DisplayNames prend en charge ces codes de champs.
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"
Utilisez ces codes pour obtenir des libellés pour n'importe quel composant de date ou d'heure dont votre interface a besoin.
Obtenir les noms de mois localisés
L'API Intl.DateTimeFormat fournit les noms de mois pour remplir les listes déroulantes et les listes de sélection. Créez un formateur avec l'option month définie sur "long", puis formatez les dates représentant chaque mois.
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"]
La fonction crée des dates pour chaque mois de l'année et les formate pour extraire le nom du mois. Définir timeZone: 'UTC' garantit des résultats cohérents entre les fuseaux horaires.
Vous pouvez obtenir les noms de mois dans n'importe quelle langue.
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月"]
Chaque locale formate les noms de mois selon ses propres conventions.
Contrôler la longueur des noms de mois
L'option month accepte différentes valeurs qui contrôlent la longueur des noms de mois.
La valeur "long" renvoie les noms de mois complets.
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"
La valeur "short" renvoie les noms de mois abrégés.
const shortFormatter = new Intl.DateTimeFormat('en-US', {
month: 'short',
timeZone: 'UTC'
});
console.log(shortFormatter.format(date));
// "Jan"
La valeur "narrow" renvoie les noms de mois les plus courts possibles, généralement une seule lettre.
const narrowFormatter = new Intl.DateTimeFormat('en-US', {
month: 'narrow',
timeZone: 'UTC'
});
console.log(narrowFormatter.format(date));
// "J"
Utilisez "narrow" avec précaution, car plusieurs mois peuvent partager la même lettre. En anglais, janvier, juin et juillet produisent tous « J ».
Obtenir les noms de jours de la semaine localisés
Utilisez le même modèle pour obtenir les noms de jours de la semaine. Définissez l'option weekday pour contrôler le format.
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"]
Vous pouvez obtenir les noms de jours de la semaine dans n'importe quelle langue.
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'));
// ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"]
Différentes locales peuvent commencer la semaine à des jours différents. Cette fonction renvoie toujours du dimanche au samedi dans l'ordre.
Obtenir les libellés de période localisés
Les libellés de période sont les indicateurs AM et PM utilisés avec l'heure sur 12 heures. Utilisez formatToParts() pour extraire ces libellés.
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: "午後" }
La méthode formatToParts() renvoie un tableau d'objets représentant chaque partie de l'heure formatée. L'objet avec type: "dayPeriod" contient le libellé AM ou PM.
Certaines locales utilisent l'heure sur 24 heures par défaut et n'incluent pas de libellés de période. Vous pouvez forcer l'heure sur 12 heures avec l'option hour12: true.
Créer un formulaire de date entièrement localisé
Combinez toutes ces techniques pour créer un formulaire de saisie de date entièrement localisé.
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"
Cette structure fournit tout ce qui est nécessaire pour afficher un formulaire de date localisé en 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
Le formulaire s'adapte automatiquement à n'importe quelle locale que vous spécifiez.
Créer un formulaire d'heure localisé
Appliquez la même approche pour créer un formulaire de saisie d'heure avec des sélecteurs d'heure, de minute et de période.
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: "午後" }]
Cela fournit toutes les données nécessaires pour afficher un sélecteur d'heure localisé.
Quand utiliser les libellés de champs de date et d'heure
Les étiquettes de champs de date et d'heure apparaissent dans plusieurs types d'interfaces.
Sélecteurs de date et d'heure personnalisés
Utilisez des étiquettes localisées lors de la création de sélecteurs de date, de widgets de calendrier ou de sélecteurs d'heure.
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')
};
Étiquettes de champs de formulaire
Appliquez des étiquettes aux champs de saisie standard pour les données de date et d'heure.
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');
Étiquettes d'accessibilité
Fournissez des étiquettes ARIA localisées pour les lecteurs d'écran et les technologies d'assistance.
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'));
En-têtes de tableaux de données
Étiquetez les colonnes dans les tableaux qui affichent des composants de date et d'heure.
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>
`;
Compatibilité des navigateurs
L'API Intl.DisplayNames avec type: "dateTimeField" est prise en charge depuis mars 2022 dans les principaux navigateurs.
Chrome et Edge la prennent en charge à partir de la version 99. Firefox la prend en charge à partir de la version 99. Safari la prend en charge à partir de la version 15.4.
Vous pouvez vérifier si la fonctionnalité est disponible avant de l'utiliser.
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
}
Pour les navigateurs plus anciens, vous devez fournir des étiquettes de secours. Créez un simple objet de correspondance pour les champs courants.
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)
Cela garantit que vos formulaires fonctionnent dans tous les navigateurs tout en tirant parti de la localisation native lorsqu'elle est disponible.
L'API Intl.DateTimeFormat pour obtenir les noms de mois et de jours de la semaine bénéficie d'une prise en charge plus large, remontant à Internet Explorer 11 et tous les navigateurs modernes. Vous pouvez l'utiliser sans détection de fonctionnalité dans la plupart des cas.