Terminzeit

Terminzeit

Lernübung

Einführung

JavaScript hat ein eingebautes Objekt Date, das Datum und Uhrzeit speichert und Methoden für deren Verwaltung bereitstellt.

Caution

Es basiert auf Javas java.util.Date-Klasse, die Anfang der 2010er Jahre ersetzt wurde, aber aus Gründen der Abwärtskompatibilität bleibt JavaScripts Date erhalten.

Weil die Arbeit mit Datumsangaben im Allgemeinen schwierig ist und weil die Zeitzonenbehandlung schlecht oder gar nicht vorhanden ist, gibt es viele Bibliotheken wie moment.js, day.js, date-fns und luxon. Keine davon ist auf Exercism verfügbar.

In deinen eigenen Projekten solltest du kein veraltetes oder nicht mehr gepflegtes Paket wie moment.js verwenden, sondern auf modernere Alternativen wie luxon setzen oder auf das noch nicht weit verbreitete Temporal. Diese Übung konzentriert sich auf Date, das bis zum Ende von JavaScript relevant bleiben wird.

Erstellung

Ein Date-Objekt ist eine Instanz der Klasse Date. Es kann erstellt werden, ohne Argumente an die Konstruktorfunktion zu übergeben. Das ergibt ein Date-Objekt, das das aktuelle Datum und die aktuelle Uhrzeit repräsentiert:

const now = new Date();
// => Thu Apr 14 2022 11:46:08 GMT+0530 (India Standard Time)
// Shows current day, date and time (in your time zone).

Unix-Zeitstempel (Zahl)

Wenn eine Zahl übergeben wird, wird sie als timestamp interpretiert. Ein Zeitstempel ist eine Ganzzahl, die die Anzahl der Millisekunden angibt, die seit dem 1. Januar 1970 UTC+0 vergangen sind.

const epoch = new Date(0);
// Thu Jan 01 1970 01:00:00 GMT+0100 (Central European Standard Time)

const another = new Date(1749508766627);
// Tue Jun 10 2025 00:39:26 GMT+0200 (Central European Summer Time)

Man könnte erwarten, dass new Date(0) das „früheste“ Datumsobjekt erzeugt, aber JavaScript wandelt das Datum in deine lokale Zeitzone um. Das bedeutet, dass nur diejenigen rund um die Zeitzone GMT / mit UTC+0 tatsächlich den Wert der Unix-Epoche erhalten.

ISO-8601-Zeitstempel (String)

Du kannst einen String, der ein Datum repräsentiert, an den Date-Konstruktor übergeben. Das einzige Format, das über alle Implementierungen hinweg konsistent ist, ist die vereinfachte Version der international anerkannten und standardisierten sogenannten ISO-8601-Zeitstempel-Strings.

Ein Zeitpunkt in UTC sieht so aus:

YYYY-MM-DDTHH:mm:ss.mssZ
YYYYMMDDTHHmmss.mssZ

Dabei gelten folgende Ersetzungen:

Schlüssel Beschreibung Standard
YYYY Das Kalenderjahr, dargestellt mit 4 Ziffern
MM Der Kalendermonat, dargestellt mit 2 Ziffern 01
DD Der Kalendertag, dargestellt mit 2 Ziffern 01
T Ein wörtlicher Buchstabe T, der Datum und Uhrzeit trennt
HH Die Stunden im 24-Stunden-Format, 2 Ziffern 00
mm Die Minuten, 2 Ziffern 00
ss Die Sekunden, 2 Ziffern 00
mss Die Millisekunden, 3 Ziffern 000
Z Ein wörtlicher Buchstabe Z oder ein Offset +/-HH:mm

Der wörtliche Buchstabe Z steht für UTC (keine Zeitzone, keine Sommerzeit).

Weil es für die meisten Komponenten Standardwerte gibt, ist es zulässig, Teile am Ende wegzulassen:

YYYY-MM-DD

Standardwert ist die Uhrzeit 00:00:00.000.

Wenn der Zeitstempel nicht auf Z endet und nicht mit +HH:mm oder -HH:mm endet (was einen Zeitzonen-Offset angibt), gilt aus historischen Gründen Folgendes:

Wenn der Zeitzonen-Offset fehlt, werden reine Datumsformen als UTC-Zeit und Datum-Uhrzeit-Formen als lokale Zeit interpretiert. Die Interpretation als UTC-Zeit geht auf einen historischen Fehler in der Spezifikation zurück, der nicht mit ISO 8601 übereinstimmte, aber aufgrund der Web-Kompatibilität nicht geändert werden konnte. Siehe Broken Parser – A Web Reality Issue.

Caution

Andere Formate, die von Date.parse akzeptiert werden, funktionieren möglicherweise oder auch nicht. Wenn du in JavaScript mit Datumsangaben arbeitest, verwende beim Umwandeln von einem string in ein Date immer einen ISO-8601-Zeitstempel.

Reine Datumsformen sind erlaubt, aber nicht alle ISO-8601-Formate werden unterstützt. Sieh dir die Erklärungsseite zur vereinfachten Version auf MDN an.

Date-Objekt

Ein bestehendes Datumsobjekt kann ebenfalls als Argument an den Konstruktor übergeben werden. Dabei wird eine Kopie des bestehenden Date-Objekts mit demselben Datum und derselben Uhrzeit erstellt.

const t1 = new Date();
const t2 = new Date(t1);
// Values of t1 and t2 will be the same.

Einzelne Datums- und Uhrzeitkomponenten übergeben

Ein Datumsobjekt, das nur ein Datum repräsentiert, kann durch Übergabe von drei Zahlen erstellt werden. Ein Datumsobjekt, das Datum und Uhrzeit repräsentiert, kann durch Übergabe von 6 Zahlen erstellt werden.

const date1 = new Date(95, 11, 17);
// Creates Date for Dec 17 1995 00:00 if your local timezone is equivalent to UTC.

const date2 = new Date(2013, 12, 5, 13, 24, 0);
// Creates Date for Jan 5 2014 13:24 if your local timezone is equivalent to UTC.

Der zweite Wert ist der month, der bei 0 für Januar beginnt und bis 11 für Dezember reicht.

Date.parse()

Möglicherweise stößt du auf Erwähnungen oder Verweise auf eine Funktion zum Parsen von Datumsangaben, Date.parse. Weil es für diese Funktion nur wenige Invarianten (Wahrheiten) gibt und der Rest der Implementierung nicht spezifiziert (und damit nicht standardisiert) ist, solltest du sie nicht verwenden.

Zugriff auf Date-Komponenten

Es gibt verschiedene Methoden auf Datumsobjekten, die die Komponenten des Datums zurückgeben:

getFullYear(); // Get the year (4 digits)
getMonth(); // Get the month, from 0 to 11.
getDate(); // Get the day of month, from 1 to 31.
getHours(); // Get the hour in a 24 clock, from 0 to 23
getMinutes(); // Get the minutes, from 0 to 59
getSeconds(); // Get the seconds, from 0 to 59
getMilliseconds(); // Get the milliseconds, from 0 and 999
getDay(); // Get the day of week, from 0 (Sunday) to 6 (Saturday).

Jede dieser Methoden hat eine passende set-Variante (z. B. setFullYear), um den Wert zu aktualisieren. Jeder überlaufende Wert geht auf die nächste Komponente über:

const date = new Date('2025-02-28T12:42:00Z');
// => Fri Feb 28 2025 13:42:00 GMT+0100 (Central European Standard Time)

date.setDate(29);
// there was no February 29th in 2025.

date.getDate();
// => 1

date.toString();
// => Sat Mar 01 2025 13:42:00 GMT+0100 (Central European Standard Time)

Für alle Methoden gibt es UTC-Varianten, die die lokale Zeitzone ignorieren.

Umwandlung eines Datums

Datumsobjekte haben eine Methode getTime(), die den UNIX-Zeitstempel in Millisekunden zurückgibt, also die Anzahl der Millisekunden seit Mitternacht am Beginn des 1. Januar 1970 UTC. Zusätzlich gibt es eine Methode toISOString(), um ein Datumsobjekt in einen ISO-8601-Zeitstempel-String umzuwandeln.

Datumsangaben vergleichen

Größer als (>) und größer oder gleich (>=) sowie kleiner als (<) und kleiner oder gleich (<=) können direkt zwischen zwei Datumsangaben oder zwischen einem Datum und einer Zahl verwendet werden. Das funktioniert, weil JavaScript versucht, das Datum in einen primitiven Wert umzuwandeln.

Advanced

Beim Vergleich zwischen zwei Datumsangaben oder zwischen einem Datum und einer Zahl ruft JavaScript [Symbol.toPrimitive]("number") auf, was intern date.valueOf() aufruft. Letzteres entspricht einem Aufruf von date.getTime().

Wenn du dich nicht auf dieses Verhalten verlassen möchtest, wandle den Wert zuerst mit getTime() in eine Zahl um.

Datumsangaben können nicht mit Gleichheit verglichen werden (== und ===), aber das Ergebnis von .getTime() kann es.

Anleitung

In dieser Übung arbeitest du an einigen Funktionen, um Termine zu verwalten. Das System speichert alles in Strings im ISO-8601-Format, aber so benutzen Menschen den Kalender nicht. Um zwischen den verschiedenen Formaten umzurechnen, brauchst du verschiedene Funktionen.

1. Einen Termin erstellen

Erstelle einen Termin n Tage ab jetzt zur aktuellen Uhrzeit. Die Funktion nimmt n Tage entgegen und gibt die Terminzeit in n Tagen zurück.

createAppointment(4, now);
// Given now is Sun Oct 05 2022 23:28:43 GMT+0600 (Bangladesh Standard Time)
// => Sun Oct 09 2022 23:28:43 GMT+0600 (Bangladesh Standard Time)

Wenn der zweite Parameter now nicht verwendet wird, soll stattdessen die aktuelle Zeit verwendet werden.

2. Ein Datum in einen Zeitstempel umwandeln

Verschiedene Tools arbeiten nur mit dem international standardisierten ISO-8601-Format. Schreibe die Funktion getAppointmentTimestamp, die ein Datum entgegennimmt und einen String in diesem Format zurückgibt.

const appointment = new Date(Date.UTC(2010, 6, 16, 12, 42, 0, 0));

getAppointmentTimestamp(appointment);
// => '2010-07-16T12:42:00.000Z'

3. Die Details eines Termins abrufen

Zeitstempel sind schwer zu lesen; eine Funktion, die die Details eines Termins liefert, soll dabei helfen. Die Funktion getAppointmentDetails nimmt einen Zeitstempel im ISO-8601-Format entgegen und gibt das Jahr, den Monat, den Tag, die Stunde und die Minute zurück.

getAppointmentDetails('2022-04-24T08:15:00.000');
// => { year: 2022, month: 3, date: 24, hour: 8, minute: 15 }

4. Einen Termin mit den angegebenen Optionen aktualisieren

Die Funktion erhält als erstes Argument die Terminzeit und als zweites Argument ein Objekt mit einigen Optionen. Du musst den Termin entsprechend den Optionen im Objekt aktualisieren und das neue Datum des Termins zurückgeben. Das Optionsobjekt kann mehrere Optionen enthalten.

updateAppointment('2022-02-09T09:20:00.000', { month: 6 });
// => { year: 2022, month: 6, date: 9, hour: 10, minute: 20 }

5. Die verfügbare Zeit zwischen zwei Terminen ermitteln

Die Funktion erhält zwei Termine (Zeitstempel) als Argumente. Du musst die Differenz zwischen diesen beiden Zeiten in Sekunden zurückgeben.

Da eine halbe Sekunde fast bedeutungslos ist, runde die Zahl, bevor du sie zurückgibst.

timeBetween('2022-12-12T09:20:00.000', '2022-12-18T08:30:00.000');
// => 515400

6. Prüfen, ob ein Termin jetzt gültig ist oder nicht

Schließlich muss das System beim Erstellen eines Termins prüfen, ob er gültig ist. Mit anderen Worten: Der Termin muss in der Zukunft liegen und nicht in der Vergangenheit.

Schreibe die Funktion isValid, die zwei Argumente entgegennimmt, einen Termin-Zeitstempel (String) und die aktuelle Zeit als Zeitstempel (String), und true zurückgibt, wenn der Termin angesichts der aktuellen Zeit in der Zukunft liegt.

isValid('2022-02-11T23:00:00.000', '2022-02-08T23:00:00.000');
// => true
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
JavaScript Exercism

Bereit, mit Terminzeit zu starten?

Melde dich bei Exercism an, um JavaScript mit 37 Konzepte159 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.