Mit IntlDateFormatter ein Datum in PHP formatieren
Veröffentlicht am Dienstag, den 13. September 2022
Einführung
Im letzten Artikel wurde mit strtotime()
und strftime()
ein Datum formatiert.
In zukünftigen Versionen ist die Funktion strftime()
jedoch veraltet. Deswegen verwenden wir stattdessen den IntlDateFormatter
in diesem Artikel.
In PHP kann man ganz einfach einen vorgegebenen String, welches ein Datum enthält, so umwandeln, dass er für einen Nutzer einfach zu lesen ist. Auch kann man damit den Wochentag automatisch bestimmen und sogar die Sprache des formatierten Datums einstellen. Ich gehe davon aus, dass der übergebene String kein sauberer String mit Datum ist, sondern neben dem Datum auch noch weitere Informationen enthält. Diesen gilt es dann vorzubereiten, bevor er in PHP-Funktionen übergeben werden kann.
Funktion
Zuerst schreiben wir eine Funktion format_date
,
die einen String akzeptiert und das Datum im gewünschten Format zurückgibt.
function format_date($str) {
$res = preg_match('/(\d{4}-\d{2}-\d{2})/', $str, $matches);
if (!$res)
return null;
$date = date_create($matches[1]);
$fmt = datefmt_create(
locale: 'de-DE',
pattern: 'EEEE, \'den\' d. MMMM y'
);
return datefmt_format($fmt,$date);
}
Gehen wir das Ganze Schritt für Schritt durch.
-
Mit REGEX wird aus dem übergebenen String das Datum gefiltert. Der gematchte Ausdruck wird in
$matches
gespeichert. Das Format für das übergebene Datum soll YYYY-MM-DD sein, damit hier was gematcht wird. -
Anschließend wird geprüft, dass überhaupt ein zutreffendes Wort gefunden wurde, also ein Datum in dem String. Ist
$res
0 oder fehlerhaft, dann geben wirnull
zurück. -
Mit der
date_create()
Funktion erstellen wir aus dem Wort ein DateTime Objekt. Das werden wir dann im letzten Schritt verwenden. -
Neben dem Datum müssen wir ein Format angeben, wie das Datum ausgegeben werden soll. Das machen wir mit dem
IntlDateFormatter
. Die zwei wichtigsten Parameter hier sind der erste Parameterlocale: 'de-DE'
und der letzte Parameterpattern: 'EEEE, \'den\' d. MMMM y'
.Das
locale
, auf Deutsch Gebietsschema, sagt aus welches Land und welche Sprache verwendet werden soll. Eine komplette Liste der möglichen Werte ist in der ICU Dokumentation zu sehen. Das verändert bei der Ausgabe z.B. die Sprache des Wochentags und des Monats.Das
pattern
gibt die Vorlage für die Ausgabe vor. Schauen wir uns jeden Teil kurz an. MitEEEE, \'den\'
wird der Wochentag gefolgt von einem Komma, Leerzeichen und das Wort den ausgegeben.EEEE
steht dabei für den Wochentag völlig ausgeschrieben. Es ist auchE|EE|EEE
möglich. Kommata haben keine besondere Bedeutung, genauso wie Leerzeichen. Diese werden einfach so ausgegeben. Anders ist es bei dem Wort 'den'. Damit die Buchstaben nicht interpretiert werden, müssen diese mit einfachen Anführungszeichen ' umschlossen werden. Damit wiederrum der PHP-String nicht vorzeitig beendet wird, werden die Anführungszeichen mit einem \ vorangestellt. Man kann das auch umgehen, indem das Pattern-String mit doppelten, statt einfachen, Anführungszeichen geschrieben wird. Dann werden die \ nicht gebraucht.
d. MMMM y
gibt den Monatstag, gefolgt von einem Punkt, den Monat völlig ausgeschrieben und das Jahr in YYYY Schreibweise. Auch hier sind der Punkt und das Leerzeichen kein Problem. NebenMMMM
kann man auchM|MM|MMM
geschrieben werden. Wobei bei den ersten beiden Schreibweisen die Zahl des Monats geschrieben wird.
Die Syntax ist in der ICU Dokumentation geschrieben. -
Sind das Format und das Datum bestimmt, kann mit der
datefmt_format()
Funktion im letzten Schritt das Datum ausgegeben werden. Die Funktion gibt das formatierte Datum als String zurück, welches in unserer Funktion direkt zurückgegeben wird.
Ausgabe
Diese Funktion können wir nun benutzen:
$date = '2022-02-28';
echo format_date($date);
#Ausgabe: Montag, den 28. Februar 2022
Bei 2022-02-28
ist die Ausgabe Montag, den 28. Februar 2022.
Überblick: Uhrzeiten
Wenn man den regulären Ausdruck etwas verändert, und das gewünschte pattern in datefmt_create
abändert, kann man auch Uhrzeiten ausgeben.
Bei der Eingabe des Strings $str
wäre dann sowas wie 2022-02-28-12:22
vorstellbar.
Dann matcht man /(\d{4}-\d{2}-\d{2}-\d{2}\:\d{2})/
.
Das pattern
ist dann EEEE, \'den\' d. MMMM y \'um\' H:m \'Uhr\'
, welches bei der Ausgabe folglich das ausgibt: Montag, den 8. August 2022 um 12:22 Uhr
Fazit
Wie man sehen kann, ist es im Vergleich zum letzten Artikel recht anders.
Die wichtigsten Funktionen sind hier datefmt_create()
und datefmt_format()
.
Die Funktionen können explizit angegebene Gebietsschemata verarbeiten und setzen somit weniger auf die globalen PHP-Einstellungen.
Ein Vorteil ist z.B. für Unternehmen, die ihre Dienstleistung im Internet global anbieten, besser auf die unterschiedlichen Sprachen ihrer Nutzer eingehen können.
Man verändert nicht mehr global irgendwelche Einstellungen, sondern nur für den einen Fall die gewünschte Ausgabe.
Das ist auch gerade für Mehrbenutzersynchronisation besser, da nicht mehr irgendwann und irgendwo das Gebietsschema geändert wird.