DateTimeImmutable vs. DateTime

Lesezeit: 4 Minuten

Benutzeravatar von hbengamra
hbengamra

Die 2 Klassen DateTime und DateTimeImmutable implementieren die gleiche Schnittstelle DateTimeInterface. Deshalb will ich wissen:

Was ist der Unterschied zwischen diesen 2 Klassen DateTime und DateTimeImmutable?

Benutzeravatar von El_Vanja
El_Vanja

Der Kern des Unterschieds ist in der beschrieben Dokumentation des DateTime Klasse:

Diese Klasse verhält sich genauso wie DateTimeImmutable, außer dass Objekte selbst geändert werden, wenn Änderungsmethoden wie DateTime::modify() aufgerufen werden.

Betrachten wir diesen Unterschied an einem konkreten Beispiel:

$date = new DateTime();
$tomorrow = $date->modify('+1 day');
echo $date->format('Y-m-d');
echo $tomorrow->format('Y-m-d');

Dies wird ausgeben:

2021-05-15
2021-05-15

Was hier passiert ist, ist, dass die modify gab die gleiche Instanz von zurück DateTime Objekt. Die Variable $tomorrow enthält kein anderes Objekt, sondern einen Verweis auf das Original. Durch das Aktualisieren der neuen Variablen wurde auch die ursprüngliche geändert.

Wenn wir die gleiche Modifikation ausführen, aber auf der unveränderlichen Version:

$date = new DateTimeImmutable();
$tomorrow = $date->modify('+1 day');
echo $date->format('Y-m-d');
echo $tomorrow->format('Y-m-d');

Dies wird ausgeben:

2021-05-14
2021-05-15

Weil in DateTimeImmutable, die Änderungsmethoden geben nicht dieselbe Instanz zurück, sie geben Ihnen eine neue (auch unveränderliche). Das bedeutet auch, dass Sie sein Ergebnis einer Variablen (wie im vorherigen Beispiel) für die unveränderliche Version zuweisen müssen, um es zu verwenden:

$date = new DateTime('2021-05-14');
$date->modify('+1 day');
echo $date->format('Y-m-d'); // 2021-05-15

$date = new DateTimeImmutable('2021-05-14');
$date->modify('+1 day');
echo $date->format('Y-m-d'); // 2021-05-14; original is untouched

Aufgrund dieses Verhaltens sollte die unveränderliche Version praktisch immer der veränderlichen vorgezogen werden. Das versehentliche Ändern einer Instanz eines Datums, das Sie nicht ändern wollten, ist ein ziemlich häufig auftretender Fehler.

Möglicherweise bevorzugen Sie die änderbare Version, um den Schritt der Zuweisung in Situationen zu vermeiden, in denen Sie zuverlässig feststellen können, dass keine Gefahr besteht, den Status Ihrer Anwendung zu gefährden, aber das sollten Sie am besten abschätzen, sobald Sie die Konzepte fest im Griff haben.

Abgesehen von modifygelten auch die folgenden Methoden als mutierend:

  • add
  • sub
  • setDate
  • setISODate
  • setTime
  • setTimezone

  • Es ist ein bisschen versteckt in der Dokumentationalso vielleicht gut, das zu beachten Immutable->modify() gibt ein neues zurück Unveränderlich Objekt. Also jede weitere modify() auf dem neuen Objekt muss ebenfalls einer Variablen zugewiesen werden. Es dauerte eine Weile, bis ich es herausfand.

    – Michel

    21. Januar 2022 um 9:42 Uhr

  • @Michel Ich habe explizit hinzugefügt, dass es eine unveränderliche Version zurückgibt. Aber wenn man darüber nachdenkt, würde es keinen Sinn machen, wenn es anders wäre. Wenn Ihre unveränderliche Instanz plötzlich veränderlich würde, würde der ganze Zweck der Unveränderlichkeit verloren gehen.

    – El_Vanja

    22. Januar 2022 um 11:43 Uhr

  • Dieser Herr, ist eine wirklich gute Antwort. Danke dir! Jetzt frage ich mich, warum ich das nicht schon immer benutze…

    – Näderio

    13. April 2022 um 18:53 Uhr

  • Sehr guter Artikel! Vielen Dank!

    – Timo K.

    15. Mai 2022 um 10:28 Uhr

Der Unterschied liegt im „unveränderlichen“ Teil, was bedeutet, dass sich das Objekt nach seiner Erstellung niemals ändern kann (Wiki für weitere Informationen). Dies bedeutet, dass immer dann, wenn Sie a ändern würden DateTime dieselbe Instanz wird geändert, aber wenn Sie a DateTimeImmutable stattdessen wird eine neue modifizierte Instanz zurückgegeben.

Im Allgemeinen ändert ein unveränderliches Objekt niemals seinen Zustand, nachdem es erstellt wurde. Wenn eine Änderung erforderlich ist, wird stattdessen eine neue Instanz derselben Klasse mit dem geänderten Zustand zurückgegeben.

Die Tatsache, dass diese beide dasselbe implementieren DateTimeInterface ist etwas verwirrend, lässt sich aber dadurch erklären, dass die Oberfläche nicht alle verfügbaren Funktionen beschreibt, die die Terminzeit und DateTimeUnveränderlich bieten. Genauer gesagt deckt die Schnittstelle keine Methoden ab, die Zustandsänderungen ermöglichen.

Der Anwendungsfall für die Auswahl des einen oder anderen hängt hauptsächlich von den Vorlieben, den Codierungsstandards und bis zu einem gewissen Grad vom Bedarf an Codequalität im Vergleich zum Bedarf an Entwicklungsgeschwindigkeit ab.

Nur eine kurze Anmerkung: Wenn Sie den Zuweisungsprozess vermeiden möchten, können Sie Folgendes verketten: echo $date->modify('+1 day')->format('Y-m-d'); vorausgesetzt, dass $date ist der DateTimeImmutable Objekt.

Beispiel:

$date = new DateTimeImmutable('2022-05-01');
$days = rand(2, 10);

echo "Date is: " . $date->format('d/m/Y')."\r\n";
echo "Now adding " .$days." days\r\n";
echo "Date now is: " . $date->modify('+'.$days.' day')->format('d/m/Y');

1440740cookie-checkDateTimeImmutable vs. DateTime

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy