Wie zeigt man lokalisierte Beschriftungen für Datums- und Zeitfelder an?
Verwenden Sie Intl.DisplayNames, um Feldbeschriftungen zu erhalten, und Intl.DateTimeFormat, um Monats- und Wochentagsnamen in jeder Sprache zu erhalten.
Einführung
Wenn Sie Formulare für Datums- und Zeiteingaben erstellen, benötigen Sie Beschriftungen, die jedes Feld beschreiben. Ein Datumsauswahl benötigt Beschriftungen wie "Monat", "Jahr" und "Tag". Eine Zeitauswahl benötigt Beschriftungen wie "Stunde" und "Minute". Diese Beschriftungen müssen in der Sprache des Benutzers erscheinen.
Diese Beschriftungen fest in Englisch zu codieren, funktioniert nicht für internationale Anwendungen. Ein französischer Benutzer erwartet "Mois" und "Année" zu sehen, während ein spanischer Benutzer nach "Mes" und "Año" sucht. Sie benötigen ein System, das diese Beschriftungen automatisch in jeder Sprache bereitstellt.
JavaScript bietet zwei komplementäre APIs dafür. Die Intl.DisplayNames-API liefert Ihnen Feldbeschriftungen wie "Monat" und "Jahr". Die Intl.DateTimeFormat-API liefert Ihnen die tatsächlichen Werte für diese Felder, wie Monatsnamen und Wochentagsnamen.
Verständnis von Datums- und Zeitfeldbeschriftungen
Datums- und Zeitschnittstellen erfordern zwei Arten von Beschriftungen. Feldbeschriftungen beschreiben, welche Art von Daten in jedes Eingabefeld gehört. Feldwerte sind die tatsächlichen Daten, die in Dropdown-Menüs und Auswahlfeldern erscheinen.
Feldbeschriftungen umfassen Wörter wie "Jahr", "Monat", "Tag", "Stunde", "Minute" und "Sekunde". Diese beschriften die Formularfelder selbst.
Feldwerte umfassen Monatsnamen wie "Januar" und "Februar", Wochentagsnamen wie "Montag" und "Dienstag" und Zeitraumbezeichnungen wie "AM" und "PM". Diese füllen Dropdown-Menüs und Auswahllisten.
Ein vollständiges Datumsformular benötigt beide Arten von Beschriftungen.
<label>Monat</label>
<select>
<option>Januar</option>
<option>Februar</option>
<option>März</option>
<!-- weitere Monate -->
</select>
<label>Jahr</label>
<input type="number" />
Sowohl "Monat" als auch "Januar" müssen lokalisiert werden, erfordern jedoch unterschiedliche Ansätze.
Feldbeschriftungen mit Intl.DisplayNames abrufen
Der Intl.DisplayNames-Konstruktor mit type: "dateTimeField" gibt lokalisierte Beschriftungen 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 und gibt dessen lokalisierte Beschriftung zurück. Die Beschriftung entspricht den Konventionen des angegebenen Gebietsschemas.
Sie können Beschriftungen in jeder Sprache erhalten, indem Sie das Gebietsschema ändern.
// Spanische Beschriftungen
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"
// Französische Beschriftungen
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"
// Japanische Beschriftungen
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'));
// "分"
Jedes Gebietsschema stellt Beschriftungen in seiner eigenen Sprache und Schrift bereit.
Verfügbare Datums- und Uhrzeitfeldcodes
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 zu erhalten, die Ihre Benutzeroberfläche benötigt.
Lokalisierte Monatsnamen abrufen
Die Intl.DateTimeFormat API stellt Monatsnamen für Dropdown-Menüs und Auswahllisten bereit. Erstellen Sie einen Formatierer mit der Option month auf "long" gesetzt 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. Die Einstellung timeZone: 'UTC' gewährleistet konsistente Ergebnisse über alle 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 erzeugen Januar, Juni und Juli alle "J".
Lokalisierte Wochentagsnamen abrufen
Verwenden Sie das gleiche Muster, um Wochentagsnamen zu erhalten. 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 erhalten.
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-Zeitdarstellung 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-Zeitdarstellung und enthalten keine Zeitraumbezeichnungen. Sie können die 12-Stunden-Zeitdarstellung mit der Option hour12: true erzwingen.
Ein vollständig lokalisiertes Datumsformular erstellen
Kombinieren Sie all 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
};
}
// Hilfsfunktion aus dem vorherigen Beispiel
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 zur Darstellung eines lokalisierten Datumsformulars in HTML benötigt wird.
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'));
// Rendert Formular mit englischen Bezeichnungen und Monatsnamen
console.log(renderDateForm('fr-FR'));
// Rendert Formular mit französischen Bezeichnungen und Monatsnamen
Das Formular passt sich automatisch an jede angegebene Locale an.
Erstellen eines lokalisierten Zeitformulars
Wenden Sie den gleichen Ansatz an, um ein Zeiteingabeformular mit Stunden-, Minuten- und Periodenauswahl 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 }
]
};
}
// Hilfsfunktion aus dem vorherigen Beispiel
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 liefert alle Daten, die zur Darstellung einer lokalisierten Zeitauswahl benötigt werden.
Wann Datums- und Zeitfeldbezeichnungen verwendet werden sollten
Datums- und Zeitfeldbezeichnungen erscheinen in verschiedenen Arten von Benutzeroberflächen.
Benutzerdefinierte Datums- und Zeitauswahlelemente
Verwenden Sie lokalisierte Bezeichnungen beim Erstellen von Datumsauswahlelementen, Kalender-Widgets oder Zeitauswahlelementen.
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')
};
Formularfeldbezeichnungen
Wenden Sie Bezeichnungen auf Standard-Formulareingabefelder 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');
Barrierefreiheitsbezeichnungen
Stellen Sie lokalisierte ARIA-Bezeichnungen für Screenreader und Hilfstechnologien 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'));
Datentabellenüberschriften
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 den wichtigsten 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 überprü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 auf Englisch
}
Für ältere Browser müssen Sie Fallback-Bezeichnungen 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" (von API wenn unterstützt, andernfalls vom Fallback)
Dies stellt sicher, dass Ihre Formulare in allen Browsern funktionieren und gleichzeitig die native Lokalisierung nutzen, wenn verfügbar.
Die Intl.DateTimeFormat-API zum Abrufen von Monats- und Wochentagsnamen hat 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 Funktionserkennung verwenden.