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
?
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
?
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 modify
gelten 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');