knuspermagier.de
Er bloggt noch? Krass!

DateTime

Ich bin ja manchmal sehr resistent dagegen, neue Sachen zu lernen. PHP bietet seit Version 5.2.0 die DateTime-Klasse, aber ich benutze eigentlich so gut wie immer, wenn es um Daten und Zeiten geht noch Funktionen wie date, strftime und strtotime. Achja und mktime nicht zu vergessen!

Also, natürlich habe ich auch DateTime schonmal benutzt, in größeren Applikationen, aber ich meine, wenn ich jetzt eben mal schnell ein Script zusammenklöppel dann kommt es mir nicht so leicht aus den Fingern. Weil seit PHP 8.1.0 nun strftime deprecated ist, nehme ich das zum Anlass, mir mal den neuen heißen Scheiß genau anzugucken und Teile meines Gehirns zu überschreiben. Ich versuche es zumindest.

neonbrand-kyxxmtptzek-unsplash.jpg
Normalerweise verzichte ich ja auf nichts sagende Stockfotos, aber eine verdammte Sanduhr, äh ein holistic hourglass, bot sich hier einfach an.

date

Die Funktion von date ist natürlich das Formatieren eines Unix Timestamps, wär hätte das bei dem Funktionsnamen erwartet.

echo date('Y-m-d H:i:s', 1231234514);
// Ergibt zum Beispiel 2009-01-06 09:35:14

Kann ja nicht so schwer sein, dass jetzt mit DateTime zu machen:

$d = new DateTime('@1231234514');
echo $d->format('Y-m-d H:i:s');
// Ergibt zum Beispiel 2009-01-06 09:35:14

Ja gut, die Syntax mit @ ist ja etwas komisch, aber wenn man kein date benutzt, muss man eigentlich auch fast keine Unix Timestamps mehr benutzen, da man eh alles in DateTime hat, oder halt in Date-Strings, und das kann DateTime ja auch einfach direkt:

$d = new DateTime('2010-10-10 12:15:33');
echo $d->format('Y-m-d H:i:s');
// Ergibt zum Beispiel 2010-10-10 12:15:33

Der Format-String ist auf jeden Fall der gleiche Kram wie bei date, das ist schön. Nicht so wie bei strftime, wo man sich absurde Dinge mit Prozentzeichen merken muss!

strftime

Der hässliche kleine Bruder von date, wo man jedes mal Nachschlagen muss, welche Format-Strings man jetzt benutzen muss. Immerhin jetzt deprecated. Doch wozu habe ich strftime benutzt? Immer, wenn bei der QA jemand sagte “Ja in Deutsch heißt das aber gar nicht February XD”. Ja, stimmt. date kann keine Locale. So im Jahr 2006 habe ich da dann noch folgendes gemacht:

$months = ['', 'Januar', 'Februar', 'März', …];
$monthName = $month[date('n', $timestamp)];

$formatted = date('d.', $timestamp) . ' ' . $monthName;

Wie oft ich in meinem jungen Leben damals wohl Arrays mit Monatsnamen tippte. Damals gab es ja auch noch keine Notizapps und Copy-Paste! Naja, vielleicht doch, aber ich brauche immer so lang um mich an Sachen zu gewöhnen.

Jedenfalls benutzt man strftime jetzt ungefähr so:

echo strftime('%A, %e. %B', 1231234514);
// Ergibt: Tuesday,  6. January

setlocale(LC_TIME, 'de_DE');
echo strftime('%A, %e. %B', 1231234514);
// Ergibt: Dienstag,  6. Januar

Tut also das, was man will. Leider ist das handlen der System-Locale und so immer etwas fummelig und je nach Server-Konfiguration funktioniert es auch nicht, weil de_DE zum Beispiel nicht installiert ist. Zudem der komplett andere Format-String. Trotzdem hab ich es jetzt einige Jahre benutzt.

Wie macht man es nun mit DateTime? Gar nicht! Haha, denn DateTime kann auch keine Locale. Seit PHP 5.3.0 gibt es aber den IntlDateFormatter, wenn man die intl-Extension installiert hat.

$d = new DateTime('@1231234514');
$formatter = new IntlDateFormatter(
    'de_DE', 
    IntlDateFormatter::SHORT, 
    IntlDateFormatter::SHORT,
    null,
    null,
    'EEEE, d. LLLL'
);

echo $formatter->format($d);
// Ergibt: Dienstag,  6. Januar

Ist etwas… klobig, aber zeigt mir eine Programmiersprache, in der internationales Daten-Formatieren nicht mega ausführlich ist. Das Pattern ist natürlich auch ein anderes als bei date und dem normalen format von DateTime, man muss nämlich die offiziellen Symbols aus der Tabelle der ICU nehmen. Immerhin kennt man die schon ganz gut, wenn man öfter unter JavaScript Daten mit datefns formatiert.

Fassen wir zusammen: Vorher dumm, nachher bisschen weniger dumm, aber etwas, was man sich immer zusammenkopieren wird.

strtotime

Eine meiner Lieblingsfunktionen, denn sie tut genau das, was man erwartet. Aus 2009-01-06 09:35:14 wird 1231234514. Wie man oben schon gesehen hat, kann DateTime das ja direkt im Konstruktor, das wird also ein einfaches, mir das anzugewöhnen.

mktime

Selten genutzt und jedes mal gehasst, aufgrund der Parameter-Reihenfolge, wer soll sich das merken:

mktime(
    int $hour,
    ?int $minute = null,
    ?int $second = null,
    ?int $month = null,
    ?int $day = null,
    ?int $year = null
): int|false

Da kann DateTime natürlich punkten:

$d = new DateTime();
$d->setTime(12, 0, 0);
$d->setDate(2010, 1, 4);

Fazit

Eigentlich ist es gar nicht so schwer, man müsste sich nur mal darauf committen, wie bei so vielem im Leben. Zahnseide benutzen ist auch gar nicht so schwer, man muss es nur eben machen! Was Laravel-Apps und sowas angeht wird das auch nicht so schwierig, mal sehen, ob ich auch in meinen Quick’n’Dirty-Scripten darauf umschwenken kann.

Bonus: Carbon

Jetzt kommen sicher alle und rufen, halt, stopp, benutz doch einfach Carbon! Ja, guter Einwand. Carbon ist auch echt nett und hat einen ganz großen Haufen von Convenience-Funktionen, zum Beispiel geht das internationale Formatieren wesentlich schnittiger.

Da Laravel soweit ich weiß, zumindest war es früher so, Carbon mitbringt, hatte ich damit auch schon viel Kontakt und habe es hier und da auch eingesetzt, aber, wie schon dreimal gesagt, der Hauptpunkt, wo ich weg will von den Legacy-Kram sind schnelle Scripte und Quatschkram, bei dem ich nicht erstmal eine Third Party Library installieren will. Daher wollte ich mir hier erstmal die eingebauten Möglichkeiten genau angucken.

Kommentare, Feedback und andere Anmerkungen?
Schreib mir eine E-Mail 🤓