Wie zeigt man lokalisierte Bezeichnungen für Datums- und Zeitfelder an?
Verwenden Sie Intl.DisplayNames, um Feldbezeichnungen zu erhalten, und Intl.DateTimeFormat, um Monats- und Wochentagsnamen in jeder Sprache anzuzeigen.
Einführung
Beim Erstellen von Eingabeformularen für Datum und Uhrzeit benötigen Sie Bezeichnungen, die jedes Feld beschreiben. Ein Datumswähler benötigt Labels wie „Monat“, „Jahr“ und „Tag“. Ein Zeitwähler braucht Bezeichnungen wie „Stunde“ und „Minute“. Diese Labels müssen in der Sprache der Nutzer:innen angezeigt werden.
Das Festschreiben dieser Labels auf Englisch funktioniert nicht für internationale Anwendungen. Französische Nutzer:innen erwarten „Mois“ und „Année“, während spanische Nutzer:innen nach „Mes“ und „Año“ suchen. Sie benötigen ein System, das diese Bezeichnungen automatisch in jeder Sprache bereitstellt.
JavaScript stellt dafür zwei sich ergänzende APIs bereit. Die Intl.DisplayNames-API liefert Ihnen Feldbezeichnungen wie „Monat“ und „Jahr“. Die Intl.DateTimeFormat-API liefert die tatsächlichen Werte für diese Felder, wie Monats- und Wochentagsnamen.
Verständnis von Datums- und Zeitfeldbezeichnungen
Benutzeroberflächen für Datum und Uhrzeit benötigen zwei Arten von Bezeichnungen. Feldbezeichnungen beschreiben, welche Art von Daten in jedes Eingabefeld gehört. Feldwerte sind die tatsächlichen Daten, die in Dropdowns und Auswahllisten erscheinen.
Feldbezeichnungen sind Begriffe wie „Jahr“, „Monat“, „Tag“, „Stunde“, „Minute“ und „Sekunde“. Sie beschriften die eigentlichen Formularfelder.
Feldwerte umfassen Monatsnamen wie „Januar“ und „Februar“, Wochentagsnamen wie „Montag“ und „Dienstag“ sowie Zeitangaben wie „AM“ und „PM“. Diese füllen Dropdowns und Auswahllisten.
Ein vollständiges Datumsformular benötigt beide Arten von Bezeichnungen.
<label>Month</label>
<select>
<option>January</option>
<option>February</option>
<option>March</option>
<!-- more months -->
</select>
<label>Year</label>
<input type="number" />
Sowohl „Monat“ als auch „Januar“ müssen lokalisiert werden, benötigen aber unterschiedliche Ansätze.
Feldbezeichnungen mit Intl.DisplayNames abrufen
Der Intl.DisplayNames-Konstruktor mit type: "dateTimeField" gibt lokalisierte Bezeichnungen für Datums- und Zeitkomponenten zurück.
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"
Die of()-Methode nimmt einen Feldcode entgegen und gibt dessen lokalisierte Bezeichnung zurück. Die Bezeichnung entspricht den Konventionen der angegebenen Locale.
Sie können Bezeichnungen in jeder Sprache abrufen, indem Sie die Locale ändern.
// 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'));
// "分"
Jede Locale stellt Bezeichnungen in ihrer eigenen Sprache und Schrift bereit.
Verfügbare Datums- und Zeitfeldcodes
Die Intl.DisplayNames-API unterstützt diese Feldcodes.
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"
Verwenden Sie diese Codes, um Bezeichnungen für jede Datums- oder Zeitkomponente abzurufen, die Ihre Benutzeroberfläche benötigt.
Lokalisierte Monatsnamen abrufen
Die Intl.DateTimeFormat-API stellt Monatsnamen zum Befüllen von Dropdowns und Auswahllisten bereit. Erstellen Sie einen Formatter mit der auf "long" gesetzten Option month und formatieren Sie dann Datumsangaben, die jeden Monat repräsentieren.
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"]
Die Funktion erstellt Datumsangaben für jeden Monat des Jahres und formatiert sie, um den Monatsnamen zu extrahieren. Das Setzen von timeZone: 'UTC' gewährleistet konsistente Ergebnisse über Zeitzonen hinweg.
Sie können Monatsnamen in jeder Sprache abrufen.
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月"]
Jede Locale formatiert Monatsnamen gemäß ihren eigenen Konventionen.
Länge der Monatsnamen steuern
Die Option month akzeptiert verschiedene Werte, die die Länge der Monatsnamen steuern.
Der Wert "long" gibt vollständige Monatsnamen zurück.
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"
Der Wert "short" gibt abgekürzte Monatsnamen zurück.
const shortFormatter = new Intl.DateTimeFormat('en-US', {
month: 'short',
timeZone: 'UTC'
});
console.log(shortFormatter.format(date));
// "Jan"
Der Wert "narrow" gibt die kürzestmöglichen Monatsnamen zurück, typischerweise einen einzelnen Buchstaben.
const narrowFormatter = new Intl.DateTimeFormat('en-US', {
month: 'narrow',
timeZone: 'UTC'
});
console.log(narrowFormatter.format(date));
// "J"
Verwenden Sie "narrow" mit Vorsicht, da mehrere Monate denselben Buchstaben haben können. Im Englischen ergeben January, June und July alle "J".
Lokalisierte Wochentagsnamen abrufen
Verwenden Sie dasselbe Muster, um Wochentagsnamen abzurufen. Setzen Sie die Option weekday, um das Format zu steuern.
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"]
Sie können Wochentagsnamen in jeder Sprache abrufen.
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'));
// ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"]
Verschiedene Locales können die Woche an unterschiedlichen Tagen beginnen. Diese Funktion gibt immer Sonntag bis Samstag in dieser Reihenfolge zurück.
Lokalisierte Zeitraumbezeichnungen abrufen
Zeitraumbezeichnungen sind die AM- und PM-Indikatoren, die bei der 12-Stunden-Zeit verwendet werden. Verwenden Sie formatToParts(), um diese Bezeichnungen zu extrahieren.
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: "午後" }
Die Methode formatToParts() gibt ein Array von Objekten zurück, die jeden Teil der formatierten Zeit repräsentieren. Das Objekt mit type: "dayPeriod" enthält die AM- oder PM-Bezeichnung.
Einige Locales verwenden standardmäßig die 24-Stunden-Zeit und enthalten keine Zeitraumbezeichnungen. Sie können die 12-Stunden-Zeit mit der Option hour12: true erzwingen.
Ein vollständiges lokalisiertes Datumsformular erstellen
Kombinieren Sie alle diese Techniken, um ein vollständig lokalisiertes Datumseingabeformular zu erstellen.
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"
Diese Struktur bietet alles, was benötigt wird, um ein lokalisiertes Datumsformular in HTML zu rendern.
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
Das Formular passt sich automatisch an jedes von Ihnen angegebene Locale an.
Ein lokalisiertes Zeitformular erstellen
Wenden Sie denselben Ansatz an, um ein Zeiteingabeformular mit Stunden-, Minuten- und Zeitraumauswahl zu erstellen.
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: "午後" }]
Dies bietet alle Daten, die benötigt werden, um einen lokalisierten Time-Picker zu rendern.
Wann Datums- und Zeitfeldbezeichnungen verwendet werden sollten
Datums- und Zeitfeldbeschriftungen erscheinen in verschiedenen Arten von Benutzeroberflächen.
Benutzerdefinierte Datums- und Zeitauswahl
Verwenden Sie lokalisierte Beschriftungen beim Erstellen von Datumsauswahlen, Kalender-Widgets oder Zeitselektoren.
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')
};
Formularfeldbeschriftungen
Wenden Sie Beschriftungen auf Standard-Formulareingaben für Datums- und Zeitdaten an.
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');
Barrierefreiheitsbeschriftungen
Stellen Sie lokalisierte ARIA-Beschriftungen für Screenreader und unterstützende Technologien bereit.
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'));
Datentabellenkopfzeilen
Beschriften Sie Spalten in Tabellen, die Datums- und Zeitkomponenten anzeigen.
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>
`;
Browser-Unterstützung
Die Intl.DisplayNames-API mit type: "dateTimeField" wird seit März 2022 in allen gängigen Browsern unterstützt.
Chrome und Edge unterstützen sie ab Version 99. Firefox unterstützt sie ab Version 99. Safari unterstützt sie ab Version 15.4.
Sie können prüfen, ob die Funktion verfügbar ist, bevor Sie sie verwenden.
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
}
Für ältere Browser müssen Sie Fallback-Beschriftungen bereitstellen. Erstellen Sie ein einfaches Mapping-Objekt für gängige Felder.
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)
Dies stellt sicher, dass Ihre Formulare in allen Browsern funktionieren und gleichzeitig die native Lokalisierung nutzen, wenn sie verfügbar ist.
Die Intl.DateTimeFormat-API zum Abrufen von Monats- und Wochentagsnamen verfügt über eine breitere Unterstützung, die bis zum Internet Explorer 11 und allen modernen Browsern zurückreicht. Sie können sie in den meisten Fällen ohne Feature-Erkennung verwenden.