Tracks
/
Julia
Julia
/
Übungen
/
Termine für die Schönheit
Termine für die Schönheit

Termine für die Schönheit

Lernübung

Einführung

„Datum und Uhrzeit bringen wir schon kleinen Kindern bei. Wie schwer kann das schon sein?"

Viele Programmierer haben diesen Fehler gemacht, und die anschließende Erfahrung wirkt sich meist schlecht auf ihre Gesundheit und ihr Wohlbefinden aus.

Wer nicht ganz trivial mit Datum und Uhrzeit programmiert, sollte zumindest bereit sein, mögliche Probleme zu verstehen und ihnen vorzubeugen.

Dieses Dokument versucht, einen Überblick darüber zu geben, wie Julia mit Datum und Uhrzeit umgeht, aber für weitere Details ist ein Blick in das Handbuch notwendig. Es gibt außerdem ein Wikibook, dessen Erklärungen manche Leser klarer finden, und das ein hilfreiches Diagramm der Typhierarchie enthält.

Das Modul Dates

Der Großteil der grundlegenden Funktionalität steckt in Dates, einem Modul, das in einer Standardinstallation enthalten ist, aber nicht Teil der Standardbibliothek ist.

Um das Modul zu nutzen, gibt es zwei Möglichkeiten:

  1. Füge import Dates hinzu und stelle allen Funktionsaufrufen Dates. voran.
  2. Füge using Dates hinzu, wodurch das gesamte Modul in den aktuellen Namensraum gelangt (bis auf ein paar problematische Namen).
# option 1
julia> import Dates

julia> Dates.now()
2025-06-21T16:02:39.080

julia> now()  # wrong: need to include `Dates.` after an import
ERROR: UndefVarError: `now` not defined in `Main`


# option 2
julia> using Dates

julia> now()  # functions are now in the namespace
2025-06-21T16:03:04.161

Das Modul Dates ist groß und kompliziert, aber es bietet vier Hauptarten von Funktionalität:

  • Dates.Date, was Tag, Monat und Jahr enthält, aber keine Uhrzeit.
  • Dates.Time, was die Uhrzeit enthält, aber kein Datum.
  • Dates.DateTime, was Datum und Uhrzeit kombiniert.
  • Dates.Period, was Zeit- und Datumsintervalle behandelt.

Bitte beachte, dass ein DateTime im Allgemeinen keine Zeitzoneninformationen enthält (Python würde das einen „naiven" Datetime nennen). Eine Ausnahme ist now(), das die lokale Zeit von deiner Systemuhr bezieht und bei Bedarf in UTC umrechnen kann.

Die vielleicht häufigsten Anforderungen sind:

  • Ein passendes Eingabeformat parsen, um einen Dates-Typ zu konstruieren.
  • Das gewünschte numerische oder String-Format aus einem Dates-Typ gewinnen.
  • Einen Offset auf einen Date-, Time- oder DateTime-Wert anwenden.
  • Das Intervall zwischen zwei solchen Werten berechnen.
  • Das aktuelle Datum (mit today()) und/oder die aktuelle Uhrzeit (mit now()) abrufen.
Note

Um visuelle Ablenkung zu verringern, geht der meiste Beispielcode im Rest dieses Dokuments von using Dates aus und vermeidet den Modulnamen Dates. in Funktionsaufrufen.

Datums- und Zeitformate

Es gibt viele Arten, Datum und Uhrzeit zu schreiben, die oft kulturspezifisch sind. Rein numerische Datumsangaben wie „7/6/23" sind mehrdeutig, verwirrend und haben in multinationalen Organisationen zu vielen teuren Fehlern geführt (der Autor spricht hier aus bitterer eigener Erfahrung).

Der internationale Standard ist in ISO 8601 definiert und hat zwei Hauptvorteile:

  • Das Parsen ist schnell und eindeutig.
  • Das Sortieren ist einfach, da das Datetime wie normaler Text behandelt und alphabetisch sortiert werden kann.

In einem vorherigen Beispiel haben wir gesehen, dass Date.now() 2025-06-21T16:03:04.161 zurückgegeben hat.

Das setzt sich aus verschiedenen Teilen zusammen:

  • YYYY-MM-DD für den Datumsteil.
  • hh:mm:ss für den Zeitteil.
  • Optional Millisekunden (oder eine noch kleinere Einheit) nach dem Dezimalpunkt.

Andere String-Formate werden in einem späteren Abschnitt behandelt.

Datumsangaben

Dates.Date ist ein relativ einfacher, reiner Datumstyp, der nichts über Uhrzeiten oder Zeitzonen weiß.

# constructor with year, month, day arguments
julia> date1 = Date(2025, 06, 23)
2025-06-23

# constructor with ISO 8601 string
julia> date2 = Date("2025-06-23")
2025-06-23

julia> date1 == date2
true

julia> typeof(date1)
Date

Für einzelne Teile des Datums gibt es Zugriffsfunktionen, und diese treten paarweise auf, unterschieden durch die Groß- und Kleinschreibung.

# lowercase returns an integer
julia> month(date1)
6

julia> typeof(month(date1))
Int64

# Propercase returns a Period type
julia> Month(date1)
6 months

julia> typeof(Month(date1))
Month

Abfragefunktionen

Es gibt eine Vielzahl von Funktionen, die ein gewisses Verständnis des Kalenders mitbringen. Das nächste Beispiel zeigt nur ein paar davon.

julia> date1
2025-06-23

julia> dayofweek(date1) # 1 = Monday, 7 = Sunday
1

julia> dayname(date1)
"Monday"

julia> daysinmonth(date1)
30

julia> isleapyear(date1)
false

julia> lastdayofmonth(date1)
2025-06-30

Uhrzeiten

Dates.Time ist der grundlegende reine Uhrzeittyp. Er kennt keine Datumsangaben: Uhrzeiten gehen um Mitternacht automatisch auf Time(0, 0, 0) über.

Das vollständige Konstruktorformat ist Time(hour, min, sec, millisec, microsec) oder das ISO-8601-Äquivalent.

Alle Parameter sind optional und haben den Standardwert 0.

julia> Time(14, 57, 25, 142)
14:57:25.142

julia> Time("14:57:25.142")
14:57:25.142

julia> Time(14, 57, 25, 142, 32)
14:57:25.142032

Wie bei Date sind einzelne Teile über Zugriffsfunktionen verfügbar:

julia> minute(t) # => integer
57

julia> Minute(t) # => Period
57 minutes

Datums- und Uhrzeitangaben

Dates.DateTime kombiniert die meisten Eigenschaften der Typen Date und Time.

julia> dt1 = DateTime(2025, 6, 23, 14, 57, 25, 142)
2025-06-23T14:57:25.142

# date1 and t were defined in previous examples
julia> dt2 = DateTime(date1, t)
2025-06-23T14:57:25.142

Die Parameter für Jahr, Monat und Tag haben den Standardwert 1, die Zeitparameter alle den Standardwert 0.

All diese Parameter in der richtigen Reihenfolge zu behalten, kann eine Herausforderung sein, deshalb ist das ISO-Format für die Eingabe möglicherweise vorzuziehen.

Alternativ kann ein DateTime aus einem Date und einem Time konstruiert werden, wie im obigen Beispiel.

Perioden

Jede der Datums- und Zeitkomponenten hat ihren eigenen Period-Typ, von Year bis hinunter zu Nanosecond, der ein Zeitintervall darstellt. Diese sind besonders nützlich für die Arithmetik.

julia> dt1
2025-06-23T14:57:25.142

julia> Year(21)
21 years

julia> Second(61)
61 seconds

julia> dt1 + Year(21) - Second(61)
2046-06-23T14:56:24.142

julia> Date(2025, 07, 03) - Date(2025, 04, 25)
69 days

Beim Arbeiten mit Period-Typen versucht Julia, clever mit Kalenderunregelmäßigkeiten wie der Monatslänge umzugehen, und rundet nach Bedarf.

# February has fewer days than January
julia> Date(2025, 1, 31) + Month(1) 
2025-02-28

String-Darstellungen

Wir haben bereits den ISO-8601-Standard erwähnt, der Julias Standarddarstellung für Datum und Uhrzeit beim Formatieren oder Parsen von Strings ist.

Natürlich sind viele andere Formate häufig in Gebrauch, oft auf kulturspezifische Weise. Um diese zu behandeln, hat Julia den DateFormat-Typ, der aus einem Formatstring beliebiger Komplexität konstruiert werden kann.

# dateformat"" string syntax
julia> dtfmt = dateformat"d/m/y"
dateformat"d/m/y"

julia> typeof(dtfmt)
DateFormat{Symbol("d/m/y"), Tuple{Dates.DatePart{'d'}, Dates.Delim{Char, 1}, Dates.DatePart{'m'}, Dates.Delim{Char, 1}, Dates.DatePart{'y'}}}

# DateFormat constructor
julia> DateFormat("d/m/y")
dateformat"d/m/y"

Das obige Beispiel ist sehr einfach, nur ein Datum im in Europa üblichen Format Tag/Monat/Jahr. Es werden zwei Varianten der Syntax gezeigt, aber das Ergebnis ist identisch.

Ein DateFormat kann dann verwendet werden, um jeden geeigneten String zu parsen:

julia> DateTime("14/7/2023", dtfmt)
2023-07-14T00:00:00

Das Erstellen eines DateFormat ist mit erheblichem Aufwand verbunden, deshalb ist es hilfreich, diesen Schritt nur einmal auszuführen (wie hier mit dtfmt), wenn du über viele Datums- und Zeitstrings schleifst.

Formate können viel komplexer sein als dieses, daher sieh im Handbuch nach Einzelheiten.

Dasselbe DateFormat kann auch verwendet werden, um ein Datum oder eine Uhrzeit in einem beliebigen gewünschten String-Format auszugeben, und zwar mit der Funktion Dates.format().

Leider scheint es einen Namensraumkonflikt mit format zu geben (zumindest in Julia 1.11.5), deshalb ist es am besten, das Präfix Dates. auch nach using Dates anzugeben.

julia> dt1
2025-06-23T14:57:25.142

julia> Dates.format(dt1, dateformat"e, u d")
"Mon, Jun 23"

Wie in der Dokumentation beschrieben, liefert "e, u d" die abgekürzte Textdarstellung für Wochentag und Monat.

Die Textdarstellung ist standardmäßig Englisch. Andere Sprachen können hinzugefügt werden, obwohl die Unterstützung dafür derzeit nicht optimal ist.

Anleitung

In dieser Übung arbeitest du an einem Terminplaner für einen Schönheitssalon in New York, der am 15. September 2012 eröffnet wurde.

Du hast fünf Aufgaben, bei denen es jedes Mal um Termindaten geht. Die Uhrzeiten sind im 24-Stunden-Format (kein AM/PM).

1. Termindatum im Zahlenformat parsen

Implementiere die Funktion schedule_appointment(), um eine textliche Darstellung eines Termindatums in das entsprechende DateTime-Format zu parsen.

Beachte, dass die Eingabe im US-amerikanischen Format Monat/Tag/Jahr vorliegt.

julia> schedule_appointment("07/25/2023 13:45:00")
2023-07-25T13:45:00

2. Prüfen, ob ein Termin bereits vorbei ist

Implementiere die Funktion has_passed(), die ein Termindatum entgegennimmt und prüft, ob der Termin irgendwann in der Vergangenheit lag:

julia> has_passed(DateTime(1999, 12, 31, 9, 0, 0))
true

3. Prüfen, ob ein Termin am Nachmittag liegt

Implementiere die Funktion is_afternoon_appointment(), die ein Termindatum entgegennimmt und prüft, ob der Termin am Nachmittag liegt (>= 12:00 und < 18:00):

julia> is_afternoon_appointment(DateTime(2023, 3, 29, 15, 0, 0))
true

4. Uhrzeit und Datum des Termins beschreiben

Implementiere die Funktion description(), die ein Termindatum entgegennimmt und eine Beschreibung dieses Datums und dieser Uhrzeit zurückgibt:

julia> describe(DateTime(2023, 3, 29, 15, 0, 0))
"You have an appointment on Wednesday, March 29, 2023 at 15:00"

5. Das Jubiläumsdatum zurückgeben

Implementiere die Funktion anniversary_date(), die das Jubiläumsdatum dieses Jahres zurückgibt, also den 15. September:

julia> anniversary_date()  # run during 2025
2025-09-15
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
Julia Exercism

Bereit, mit Termine für die Schönheit zu starten?

Melde dich bei Exercism an, um Julia mit 35 Konzepte128 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.