# 5.5.1 Datum ausgeben mit DateTime

Bereits im Unterkapitel Datum ausgeben mit date() hatten wir gesehen, wie man mit der PHP-Funktion `date()` ein Datum formatieren und ausgeben kann.

Hier wollen wir nun die objektorientierte Version der Datumsausgabe zeigen, denn PHP hat eine vordefinierte Klasse DateTime, die man ohne zu "importieren" direkt nutzen kann.

Anmerkung

Wenn wir mit vordefinierten Klassen arbeiten, dann müssen wir uns zunächst einen ersten Überblick über die vorhandenen Eigenschaften und Methoden machen, die man nutzen kann. Viele vordefinierte Klassen können auch "statisch" aufgerufen werden. Wir bevorzugen in diesen Beispielen aber die Bildung von Objekten.

Die Klasse DateTime bietet sehr viele Möglichkeiten und Methoden, von denen wir hier nur eine kleine Auswahl verwenden:

- Beim Instanzieren die Klasse DateTime werden Daten an den Konstruktor übergeben.
- Die Methode format() wird zur formatierten Ausgabe genutzt.
- Die Methode modify() wird zur Änderung des Datums genutzt, beispielsweise um Wochen hinzuzählen oder Stunden abziehen.
- Die Methode getTimestamp() wird zur Bestimmung der Sekunden seit Beginn der Unix-Zeitrechnung am 01.01.1970 genutzt.

Beginnen wir mit dem einfachen Beispiel der Ermittlung und Ausgabe des aktuellen Datums.

    1
    2
    3
    4
    5
    <?php
    $dt = new DateTime("now");

    // Deutsches Standardformat
    echo $dt->format("d.m.Y H:i:s");

Ausgabe des heutigen Formats in der Form:
02.05.2024 12:02:27

Man kann aber bereits beim Instanzieren andere Datumsangaben angeben.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?php
    // Festes Datum angeben.
    // Es sind verschiedene Formate im Konstruktor möglich.
    // Die Ausgabe wird unabhängig mit 'format()' festgelegt.
    $dt = new DateTime("31.01.2025");
    echo $dt->format("d.m.Y") . "<br>";

    $dt = new DateTime("2025-01-31");
    echo $dt->format("d.m.Y") . "<br>";

Ausgabe:
31.01.2025
31.01.2025

Man kann aber bereits beim Instanzieren schon Berechnungen durchführen.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    <?php
    // Immer englischsprachig angeben
    $dt = new DateTime("now + 1 day");
    echo "Morgen: " . $dt->format("d.m.Y H:i:s") . "<br>";

    $dt = new DateTime("yesterday 10:00");
    echo "Gestern um 10:00 Uhr: " . $dt->format("d.m.Y H:i:s") . "<br>";

    $dt = new DateTime("now - 3 weeks");
    echo "Vor 3 Wochen: " . $dt->format("d.m.Y H:i:s") . "<br>";

    $dt = new DateTime("next Sunday");
    echo "Nächster Sonntag: " . $dt->format("d.m.Y H:i:s") . "<br>";

    $dt = new DateTime("First Sunday May 2024");
    echo "Erster So. im Mai 2024: " . $dt->format("d.m.Y H:i:s") . "<br>";

Ausgabe:
Morgen: 03.05.2024 12:02:27
Gestern um 10:00 Uhr: 01.05.2024 10:00:00
Vor 3 Wochen: 11.04.2024 12:02:27
Nächster Sonntag: 05.05.2024 00:00:00
Erster So. im Mai 2024: 05.05.2024 00:00:00

Wichtiger ist aber, dass mit modify() Datumsangaben ändern kann.

    1
    2
    3
    4
    <?php
    $dt = new DateTime("now");
    $dt->modify("+2 weeks -1 hours");
    echo "In 2 Wochen (minus 1 Stunde): " . $dt->format("d.m.Y H:i:s");

Ausgabe:
In 2 Wochen (minus 1 Stunde): 16.05.2020 11:02:27

## Formatierungsanweisungen

Bereits im Unterkapitel Datum ausgeben mit date() haben wir gesehen, dass viel mehr Formatierungen möglich sind, nicht nur "tt.mm.jjjj". Die Formatangaben gelten auch hier.

date()-Parameter

Zeichen | Beschreibung | Beispiel
--- | --- | ---
Y | Vierstellige Jahresangabe | 1946 oder 2007
y | Zweistellige Jahresangabe | 46 oder 07
m | Monat mit führender Null | 01 bis 12
n | Monat | 1 bis 12
M | Monat, 3 Buchstaben | Jan oder Dec
F | Monat ausgeschrieben | January oder December
d | Tag des Monats mit führender Null | 01 bis 31
j | Tag des Monats ohne Null | 1 bis 31
D | Wochentag in 3 Buchstaben | Sun oder Mon
l | Wochentag ausgeschrieben | Sunday oder Monday
h | Stunde im 12er Format mit führender Null | 01 bis 12
H | Stunde im 24er Format mit führender Null | 00 bis 24
g | Stunde im 12er Format ohne Null | 1 bis 12
G | Stunde im 24er Format ohne Null | 0 bis 24
i | Minuten mit führender Null | 00 bis 59
s | Sekunden mit führender Null | 00 bis 59
t | Anzahl der Tage im Monat | 28 bis 31
z | Tag eines Jahres | 0 bis 365

## Deutschsprachige Monate und Tage ausgeben

Solange wir reine Zahlenformate verwenden, fällt uns nicht auf, dass alle Monate und Wochentage englischsprachig sind.

    1
    2
    3
    4
    5
    6
    <?php
    $dt = new DateTime("now");
    // Problem mit DateTime: alles englischsprachig
    echo $dt->format("d. F Y") . "<br>";
    // Format auf einem Briefkopf
    echo $dt->format("l, d F Y ");

Ausgabe:
2. May 2024
Thursday, 02 May 2024

Dieses Problem kann man lösen, indem wir eine andere Datumsdarstellung nehmen, die auf das lokale Computerdatum mit der PHP-Funktion strftime() direkt zugreift und wir zuvor sagen, dass die deutschsprachigen Begriffe mit setlocale() gesetzt werden.

- Wir nutzen `setlocale(LC_TIME, "de_DE", "de_DE.utf-8", "deu", "german");` Der erste Parameter `LC_TIME` gibt an, dass die lokalen Zeitbegriffe genutzt werden sollen. Danach wird angegeben, wo die Begriffe auf dem lokalen Computer vorhanden sind und dies ist abhängig vom Betriebssystem.

  - Für Linux und MAC sind dies normalerweise "de_DE" bzw. "de_DE.utf-8".

  - Für Windows sind dies normalerweise "deu" bzw. "german".

- Wir nutzen `strftime()` zur Ausgabe des Datumsformats. Aber Achtung, `strftime()` hat andere Abkürzungen als die Klasse DateTime. Und außerdem gelten nicht alle Abkürzungen auf allen Betriebssystemen.

    1
    2
    3
    4
    <?php
    setlocale(LC_TIME, "de_DE", "de_DE.utf-8", "deu", "german");
    // Heutiges Datum ausgeben mit strftime()
    echo "Heute ist " . strftime("%A, der %d %B %Y um %H:%M");

Ausgabe:
Heute ist Donnerstag, der 02 Mai 2024 um 12:02

## Die Klasse DateTime verwenden und mit strftime() auf deutsch ausgeben

Zusammenfassend kann man sagen, dass die Klasse `DateTime` sehr gute Möglichkeiten zur Manipulation von Datumsangaben ermöglicht und es mit `strftime()` möglich ist, diese auf deutsch formatier darzustellen. In beiden Fällen wird intern immer eine Integer-Zahl in Sekunden ab dem 01.01.1970 verwendet.

Somit können wir `DateTime` nutzen und müssen am Ende die Ausgabe mit `strftime()` vornehmen.

Mit der Methode `getTimestamp()` erhalten wir die Sekunden des im Objekt gespeicherten Datums und geben diese als Parameter an `strftime()` zur formatierten Ausgabe weiter.

    1
    2
    3
    4
    5
    <?php
    setlocale(LC_TIME, "de_DE", "de_DE.utf-8", "deu", "german");
    $dt = new DateTime("now - 3 weeks");
    echo "Vor 3 Wochen war "
         . strftime("%A, der %d %B %Y um %H:%M", $dt->getTimestamp());

Ausgabe:
Vor 3 Wochen war Donnerstag, der 11 April 2024 um 12:02

## Ein Beispiel und eine Aufgabe

Bereits im Unterkapitel Vererbung - weiteres Beispiel wurde ein Objekt von DateTime mit in den Sourcecode "geschmuggelt". Auch wurde der Hinweis gegeben, dass man ein Objekt nicht per `echo` ausgeben kann. Aber nun können Sie die Ausgabe des Geburtstags schaffen, denn Sie wissen, dass `DateTime` eine vordefinierte Klasse ist und dass die Methode `format()` zur Formatierung genutzt werden kann.

Übung

Nutzen Sie den Sourcecode Vererbung2.zip aus dem Unterkapitel Vererbung - weiteres Beispiel und geben Sie den Geburtstag des Professors auf dem Browser aus.

Lösung

    1
    2
    3
    4
    5
    6
    <?php

    $dt = $professor->getBirthday(); // Dies ist das Objekt von DateTime

    // Formatierung mit der Methode format() der vordefinierten PHP-Klasse DateTime
    echo $dt->format("d.m.Y");

Alternative Schreibweise

    <?php
    echo $professor->getBirthday()->format("d.m.Y");

Was kann man hieraus alles erkennen? - Man kann erkennen, dass $professor ein Objekt ist.

- `$professor->getBirthday()` ruft eine Methode (einen Getter) im Objekt `$professor` auf.

- Die Rückgabe dieser Methode ist wieder ein Objekt. Und in dem zurückgegebenen Objekt wird die Methode `format()` aufgerufen.

- Vermutlich handelt es sich um ein Objekt der Klasse `DateTime` mit der entsprechenden Methode `format()`.

- Die Rückgabe der Methode format() ist mit echo darstellbar, also ist es ein String (oder ein Integer).

Wichtig

Sie haben hier also drei Dinge gelernt:

- Sie können externe Klassen instanzieren und die Methoden verwenden.

- Datum und Uhrzeit können Sie nun bearbeiten und ausgeben.

- Sie können die deutschen Datumsbegriffe verwenden, indem Sie zwar die Klasse DateTime verwenden, aber die Ausgabe an die Methode `strftime()` umleiten.