Tutorials › Teil 2: Daten
Kapitel 11 von 16
Datum und Uhrzeit
const jetzt = new Date();
zeige(jetzt.getFullYear());
zeige("Monat:", jetzt.getMonth());
zeige("Tag im Monat:", jetzt.getDate());
zeige("Wochentag:", jetzt.getDay());
Schau dir die zweite Zeile an. Wenn wir August haben, steht dort eine Sieben.
Die Monatsfalle
Monate zählen von null. Januar ist 0, Dezember ist 11. Tage im Monat zählen dagegen ab eins, wie man es erwartet.
Das ist keine Logik, das ist ein Erbe aus der Programmiersprache C, das seit 1995 in JavaScript steckt und aus Rücksicht auf bestehenden Code nie geändert wurde.
const heiligabend = new Date(2026, 11, 24);
zeige(heiligabend.toDateString());
const falsch = new Date(2026, 12, 24);
zeige("Monat 12 gibt es nicht:", falsch.toDateString());
Die zweite Variante läuft ins nächste Jahr über, ohne sich zu beschweren. Das ist manchmal sogar nützlich, etwa um „einen Monat später" auszurechnen, aber als Überraschung ist es unangenehm.
getDay liefert den Wochentag, ebenfalls ab null, und die Null ist der Sonntag.
const tage = ["Sonntag", "Montag", "Dienstag", "Mittwoch",
"Donnerstag", "Freitag", "Samstag"];
zeige("Heute ist", tage[new Date().getDay()]);
Ein Datum bauen
Es gibt mehrere Wege, und einer davon ist unzuverlässig.
zeige(new Date(2026, 7, 30).toDateString());
zeige(new Date("2026-08-30").toDateString());
zeige(new Date(1788000000000).toDateString());
Die erste Form mit einzelnen Zahlen ist eindeutig. Die zweite mit einem Text im Format Jahr-Monat-Tag funktioniert zuverlässig, weil sie im Standard festgelegt ist.
Andere Textformate sind Glückssache. new Date("30.08.2026") liefert je nach Browser ein Datum, ein falsches Datum oder Invalid Date. Verlass dich nicht darauf.
Die dritte Form ist ein Zeitstempel: Millisekunden seit dem 1. Januar 1970. Diese Zahl ist die eigentliche Grundlage, alles andere ist Verpackung.
const stempel = Date.now();
zeige(stempel);
zeige("als Datum:", new Date(stempel).toDateString());
Rechnen mit Zeit
Weil ein Datum intern eine Zahl ist, lassen sich zwei Daten voneinander abziehen. Heraus kommen Millisekunden.
const heute = new Date();
const weihnachten = new Date(heute.getFullYear(), 11, 24);
if (weihnachten < heute) weihnachten.setFullYear(heute.getFullYear() + 1);
const millis = weihnachten - heute;
const tage = Math.ceil(millis / 1000 / 60 / 60 / 24);
zeige("Noch", tage, "Tage bis Heiligabend.");
Die Zeile mit setFullYear fängt den Fall ab, dass Weihnachten dieses Jahr schon vorbei ist. Ohne sie käme im Januar eine negative Zahl heraus, im Dezember eine Null. Das Werkzeug Tage bis Weihnachten im Archiv hat genau diesen Fehler.
Die Kette / 1000 / 60 / 60 / 24 wandelt Millisekunden in Tage. Man sieht sie oft als eine Zahl geschrieben, 86400000, aber die einzelnen Divisionen sind lesbarer.
function tageZwischen(a, b) {
const eins = new Date(a.getFullYear(), a.getMonth(), a.getDate());
const zwei = new Date(b.getFullYear(), b.getMonth(), b.getDate());
return Math.round((zwei - eins) / 86400000);
}
const start = new Date(2026, 2, 1);
const ende = new Date(2026, 2, 31);
zeige(tageZwischen(start, ende), "Tage im März");
Verschieben
setDate und Verwandte verändern das Datum und rechnen dabei über Monats- und Jahresgrenzen hinweg richtig.
const d = new Date(2026, 0, 31);
zeige("Start:", d.toDateString());
d.setDate(d.getDate() + 1);
zeige("Ein Tag später:", d.toDateString());
d.setDate(d.getDate() + 30);
zeige("Dreißig Tage später:", d.toDateString());
Beachte, dass diese Methoden das vorhandene Objekt ändern. Willst du das Original behalten, mach vorher eine Kopie mit new Date(d).
Deutsche Ausgabe
toString liefert etwas Unleserliches auf Englisch. Für Menschen gibt es Besseres:
const d = new Date(2026, 7, 30, 14, 5);
zeige(d.toLocaleDateString("de-DE"));
zeige(d.toLocaleTimeString("de-DE"));
zeige(d.toLocaleDateString("de-DE", { dateStyle: "full" }));
zeige(d.toLocaleDateString("de-DE", { day: "2-digit", month: "long", year: "numeric" }));
zeige(d.toLocaleString("de-DE", { weekday: "short", hour: "2-digit", minute: "2-digit" }));
Alles, was man für eine Anzeige braucht, steckt schon im Browser. Eigene Monatsnamen-Arrays und padStart-Bastelei sind dafür nicht nötig.
Für Datumsangaben im HTML gibt es ein maschinenlesbares Format:
const d = new Date(2026, 7, 30);
zeige(d.toISOString().slice(0, 10));
Das gehört in ein <time datetime="...">, damit Suchmaschinen und Vorleseprogramme das Datum verstehen.
Eine laufende Uhr
const anzeige = document.createElement("div");
anzeige.style.font = "600 32px ui-monospace, monospace";
document.body.appendChild(anzeige);
function ticken() {
anzeige.textContent = new Date().toLocaleTimeString("de-DE");
}
ticken();
setInterval(ticken, 1000);
setInterval ruft eine Funktion immer wieder auf, mit dem angegebenen Abstand in Millisekunden. Der erste Aufruf von ticken() steht extra davor, sonst bliebe die Anzeige eine Sekunde lang leer.
Ein Intervall läuft, bis man es abstellt:
let rest = 5;
const kennung = setInterval(() => {
zeige(rest);
rest--;
if (rest === 0) {
clearInterval(kennung);
zeige("Start.");
}
}, 300);
Ohne clearInterval läuft das ewig weiter und zählt in negative Zahlen. Merk dir den Rückgabewert von setInterval, sonst kommst du an das Intervall nicht mehr heran.
Wenn es genauer sein muss
Für Zeitmessungen ist Date.now() zu grob und kann durch Zeitumstellungen springen. Dafür gibt es eine eigene Uhr:
const start = performance.now();
let summe = 0;
for (let i = 0; i < 500000; i++) summe += i;
const dauer = performance.now() - start;
zeige("Gerechnet in", dauer.toFixed(2), "Millisekunden");
performance.now() zählt seit dem Laden der Seite, läuft immer vorwärts und hat Bruchteile von Millisekunden. Der Reaktionstest im Archiv misst mit Date, was für Zehntelsekunden reicht, aber nicht die feinste Methode ist.
Damit ist Teil zwei durch. Ab jetzt verlässt der Code die Konsole und fasst die Seite an.