Zum Inhalt springen

Zahlen und Daten formatieren

Die App zeigt Beträge, Daten und Uhrzeiten. Wie sie aussehen, hängt von Sprache und Land ab. In der Schweiz steht vor einem Betrag CHF, ein Apostroph trennt die Tausender, und ein Datum schreibt man mit Punkten. JavaScript bringt dafür das Objekt Intl mit, das diese Regeln kennt.

Lernziele

Nach dieser Einheit kannst du

  • Beträge in Franken und Prozente mit Intl.NumberFormat formatieren,
  • Datum und Uhrzeit mit Intl.DateTimeFormat und Abstände wie «gestern» anzeigen,
  • erklären, warum ein Datum in einer anderen Zeitzone auf den Vortag fallen kann,
  • Datumswerte ohne Uhrzeit so formatieren, dass überall der richtige Tag erscheint.

Intl.NumberFormat bekommt eine Sprache mit Region und Optionen. de-CH steht für Deutsch in der Schweiz.

money.mjs
const chf = new Intl.NumberFormat('de-CH', { style: 'currency', currency: 'CHF' })
console.log(chf.format(20))
console.log(chf.format(1234.5))
const percent = new Intl.NumberFormat('de-CH', { style: 'percent' })
console.log(percent.format(0.35))

Mit style: 'currency' und currency: 'CHF' steht der Code der Währung vor dem Betrag, und es gibt immer zwei Stellen nach dem Punkt. Grosse Beträge bekommen einen Apostroph als Tausendertrennzeichen. Mit style: 'percent' wird aus 0.35 der Text 35%. Einen Formatierer kannst du für viele Zahlen verwenden, du legst ihn deshalb nur einmal an.

toFixed(2) aus den anderen Einheiten genügt für einfache Fälle, setzt aber weder Tausendertrennzeichen noch eine Währung.

Ein Date speichert einen Zeitpunkt als Anzahl Millisekunden seit dem 1. Januar 1970 in UTC. Wie dieser Zeitpunkt aussieht, bestimmt erst die Formatierung.

dates.mjs
const date = new Date('2026-11-12T00:00:00Z')
console.log(date.toLocaleDateString('de-CH', { timeZone: 'UTC' }))
const long = new Intl.DateTimeFormat('de-CH', { weekday: 'long', day: 'numeric', month: 'long', timeZone: 'UTC' })
console.log(long.format(date))
const relative = new Intl.RelativeTimeFormat('de-CH', { numeric: 'auto' })
console.log(relative.format(-1, 'day'), relative.format(3, 'day'))

toLocaleDateString liefert das Datum in der Schreibweise der Sprache, für de-CH mit Punkten. Intl.DateTimeFormat nimmt Optionen, welche Teile erscheinen sollen, hier den ausgeschriebenen Wochentag, den Tag und den Monat. Intl.RelativeTimeFormat formuliert Abstände wie «gestern» oder «in 3 Tagen». Mit numeric: 'auto' sagt es «gestern» statt «vor 1 Tag».

Ein Datum ohne Uhrzeit wie '2026-11-12' liest JavaScript als Mitternacht in UTC. Formatierst du es in einer Zeitzone westlich von UTC, liegt dieser Zeitpunkt dort noch am Vortag.

timezones.mjs
// A date without a time is read as midnight UTC
const date = new Date('2026-11-12')
const format = (timeZone) => date.toLocaleDateString('de-CH', { timeZone })
console.log(format('UTC'), format('Europe/Zurich'), format('America/New_York'))

In UTC und in Zürich ist es der 12. November, in New York noch der Abend des 11. November. Ohne die Option timeZone nimmt der Browser die Zeitzone des Geräts. Bei Mitgliedern in der Schweiz ginge das gut, auf einem Server in Amerika oder bei Tests auf einem Rechner mit anderer Zeitzone aber nicht. Für reine Datumswerte wie ein Rückgabedatum setzt du deshalb timeZone: 'UTC', wie im Kapitel Props. Für Zeitpunkte wie den Beginn einer Öffnungszeit nimmst du timeZone: 'Europe/Zurich'.

FehlerWas hilft
Ein Datum ohne Uhrzeit erscheint in manchen Zeitzonen als Vortag.Mit timeZone: 'UTC' formatieren.
Beträge werden mit 'CHF ' + deposit zusammengesetzt, und aus 12.5 wird CHF 12.5.Intl.NumberFormat mit style: 'currency' verwenden.
Der Monat ist um eins verschoben, new Date(2026, 11, 12) liegt im Dezember.Bei new Date(jahr, monat, tag) zählen die Monate ab 0. Ein Text wie '2026-11-12' ist eindeutiger.
Für jede Zahl entsteht ein neuer Intl.NumberFormat.Den Formatierer einmal anlegen und wiederverwenden.
Ein KI-Assistent schlägt für das Formatieren eine Bibliothek wie Moment.js vor.Für die Anzeige genügt Intl. Moment.js wird nicht mehr weiterentwickelt.

Aufgabe Einstieg

Formatiere die Pfänder 20, 50 und 12.5 als Beträge in Franken und gib jeden auf einer eigenen Zeile aus.

Lösung
solution-1.mjs
const chf = new Intl.NumberFormat('de-CH', { style: 'currency', currency: 'CHF' })
const deposits = [20, 50, 12.5]
for (const deposit of deposits) console.log(chf.format(deposit))

Der Formatierer entsteht einmal vor der Schleife und formatiert danach alle drei Beträge. Aus 12.5 wird CHF 12.50, weil Beträge in Franken immer zwei Stellen nach dem Punkt haben.

Aufgabe Vertiefung

Die Öffnungszeit am Mittwoch beginnt am 4. November 2026 um 16 Uhr UTC. Zeig sie als Wochentag und Uhrzeit in der Zeitzone der Schweiz an.

Lösung
solution-2.mjs
const opening = new Date('2026-11-04T16:00:00Z')
const time = new Intl.DateTimeFormat('de-CH', { weekday: 'long', hour: 'numeric', minute: '2-digit', timeZone: 'Europe/Zurich' })
console.log(time.format(opening))

Die Ausgabe ist Mittwoch, 17:00. Im November gilt in der Schweiz die Winterzeit, eine Stunde vor UTC. timeZone: 'Europe/Zurich' rechnet diese Verschiebung aus und berücksichtigt auch den Wechsel zur Sommerzeit.

Aufgabe Knobelei

Gib die Namen Zelt, Äxte und Bohrmaschine als Aufzählung aus, wie man sie in einem Satz schreibt, mit Kommas und einem «und» vor dem letzten Namen. Formatiere ausserdem die Zahl 1234567.891 mit Tausendertrennzeichen für die Schweiz.

Lösung
solution-3.mjs
const names = ['Zelt', 'Äxte', 'Bohrmaschine']
const list = new Intl.ListFormat('de-CH', { style: 'long', type: 'conjunction' })
console.log(list.format(names))
console.log(new Intl.NumberFormat('de-CH').format(1234567.891))

Intl.ListFormat kennt die Regeln der Sprache. Im Deutschen steht vor dem «und» kein Komma, im amerikanischen Englisch schon. Intl.NumberFormat ohne Optionen zeigt bis zu drei Stellen nach dem Punkt und trennt die Tausender mit Apostrophen.

Texte und Abbildungen stehen unter CC BY-SA 4.0, der Code unter der MIT-Lizenz und die Daten des Kurses unter CC0 1.0. Die Schrift der Abbildungen ist Kalam unter der SIL Open Font License 1.1. Die Quellen liegen auf GitHub.