Kurzfassung: Datums-, Zeit-, Zahlen- und Währungsformate variieren je nach Gebietsschema dramatisch – MM/TT vs TT/MM, Kommas vs Punkte als Dezimaltrennzeichen, 12h- vs 24h-Uhr. Nutzen Sie die Intl API für Lokalisierung ohne zusätzliche Abhängigkeiten. Muster von tanstackship.com.
Einführung
Die korrekte Formatierung von Datumsangaben, Zahlen und Währungen nach lokalen Konventionen ist für SaaS-Produkte, die globale Märkte anstreben, unerlässlich. Ein US-Nutzer erwartet „March 5, 2026", ein deutscher Nutzer „5. März 2026" und ein japanischer Nutzer „2026年3月5日". Eine Anleitung zur Erkennung des passenden Gebietsschemas finden Sie in unserem Leitfaden zu Spracherkennungsstrategien.
Regionale Formatunterschiede
| Gebietsschema | Datumsformat | Zeitformat | Dezimaltrennzeichen | Währungssymbol-Position |
|---|---|---|---|---|
| en-US | MM/TT/JJJJ | 12h (3:00 PM) | 1,234.56 | $1,234.56 |
| en-GB | TT/MM/JJJJ | 24h (15:00) | 1,234.56 | £1,234.56 |
| de-DE | TT.MM.JJJJ | 24h (15:00) | 1.234,56 | 1.234,56 € |
| zh-CN | JJJJ/MM/TT | 24h (15:00) | 1,234.56 | ¥1,234.56 |
| ja-JP | JJJJ年MM月TT日 | 24h (15:00) | 1,234.56 | ¥1,234.56 |
| fr-FR | TT/MM/JJJJ | 24h (15:00) | 1 234,56 | 1 234,56 € |
| ar-SA | TT/MM/JJJJ | 12h (٣:٠٠ م) | 1,234.56 | ١٬٢٣٤٫٥٦ ﷼ |
Die Intl API verwenden
// Datumsformatierung
const date = new Date('2026-06-01')
// US: June 1, 2026
new Intl.DateTimeFormat('en-US', {
dateStyle: 'long'
}).format(date) // "June 1, 2026"
// Deutsch: 1. Juni 2026
new Intl.DateTimeFormat('de-DE', {
dateStyle: 'long'
}).format(date) // "1. Juni 2026"
// Japanisch: 2026年6月1日
new Intl.DateTimeFormat('ja-JP', {
dateStyle: 'long'
}).format(date) // "2026年6月1日"
// Relative Zeit (Intl.RelativeTimeFormat)
const rtf = new Intl.RelativeTimeFormat('es', { numeric: 'auto' })
rtf.format(-1, 'day') // "ayer"
rtf.format(-7, 'day') // "hace 7 días"
Zahlen- und Währungsformatierung
// Zahlenformatierung
const price = 1234567.89
new Intl.NumberFormat('en-US').format(price) // "1,234,567.89"
new Intl.NumberFormat('de-DE').format(price) // "1.234.567,89"
new Intl.NumberFormat('ar-SA').format(price) // "١٬٢٣٤٫٥٦٧٫٨٩"
// Währungsformatierung
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(price) // "$1,234,567.89"
new Intl.NumberFormat('de-DE', {
style: 'currency',
currency: 'EUR'
}).format(price) // "1.234.567,89 €"
new Intl.NumberFormat('ja-JP', {
style: 'currency',
currency: 'JPY'
}).format(price) // "¥1,234,568" (JPY hat keine Dezimalstellen)
// Kompakte Notation für Dashboards
new Intl.NumberFormat('en-US', {
notation: 'compact',
compactDisplay: 'short'
}).format(1500000) // "1.5M"
React Hooks für lokalisierte Formatierung
import { useMemo } from 'react'
function useLocaleFormatter(locale: string) {
return useMemo(() => ({
date: (date: Date | string, options?: Intl.DateTimeFormatOptions) =>
new Intl.DateTimeFormat(locale, options).format(new Date(date)),
number: (num: number, options?: Intl.NumberFormatOptions) =>
new Intl.NumberFormat(locale, options).format(num),
currency: (amount: number, currency: string) =>
new Intl.NumberFormat(locale, {
style: 'currency',
currency,
}).format(amount),
relativeTime: (value: number, unit: Intl.RelativeTimeFormatUnit) =>
new Intl.RelativeTimeFormat(locale, { numeric: 'auto' }).format(value, unit),
}), [locale])
}
// Verwendung
function InvoiceRow({ invoice, locale }: Props) {
const f = useLocaleFormatter(locale)
return (
<tr>
<td>{f.date(invoice.createdAt, { dateStyle: 'medium' })}</td>
<td>{f.currency(invoice.amount, invoice.currency)}</td>
<td>{f.number(invoice.items)}</td>
<td>{f.relativeTime(-invoice.daysOverdue, 'day')}</td>
</tr>
)
}
Empfehlungen zur Datenbankspeicherung
| Datentyp | Speicherformat | Anzeige |
|---|---|---|
| Datumsangaben | ISO 8601 (UTC) | Zur Renderzeit formatieren |
| Zeiten | ISO 8601 + Zeitzonen-Offset | In Zeitzone des Nutzers umwandeln |
| Preise | Ganzzahl (Cent) | Mit gebietsschema-aware Währungsformatierung formatieren |
| Prozentsätze | Gleitkommazahl (0-1) | Mit gebietsschema-aware Prozentformatierung formatieren |
| Einheiten | Metrisch/Imperial separat gespeichert | Zur Renderzeit umwandeln |
Fazit
Die integrierte Intl API bewältigt 95 % aller Lokalisierungsanforderungen für Datums-, Zeit-, Zahlen- und Währungsformate ganz ohne zusätzliche Bibliotheken. Speichern Sie Datumsangaben im ISO 8601 UTC-Format, Beträge in kleinen Währungseinheiten (Cent) und formatieren Sie stets zur Renderzeit basierend auf dem Gebietsschema des Nutzers. Testen Sie mit mindestens einem Gebietsschema aus jeder wichtigen Region (USA, Europa, Ostasien, Naher Osten).
Für Überlegungen zu rechtsläufigen Sprachen lesen Sie RTL-Sprachunterstützung in React-Anwendungen. Die Implementierung einer Multi-Währungs-Abrechnung wird im Leitfaden zur Multi-Währungs-Abrechnung behandelt. Die übergreifende i18n-Architektur finden Sie unter i18n für SaaS: Architekturmuster im Vergleich.