Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DateTimeImmutable vs DateTime

The 2 classes DateTime and DateTimeImmutable implement the same interface DateTimeInterface. Therefore I want to know :

What is the difference between these 2 classes DateTime and DateTimeImmutable?

like image 579
hbengamra Avatar asked May 14 '21 14:05

hbengamra


People also ask

What is the difference between DateTime and DateTimeImmutable?

The difference is in the 'immutable' part, which means once the object is created it can never change (wiki for more info). What this means is that whenever you'd modify a DateTime the same instance will be changed, but when you modify a DateTimeImmutable a new modified instance will be return instead.

What is DateTimeImmutable PHP?

The DateTimeImmutable class ¶ Representation of date and time. This class behaves the same as DateTime except new objects are returned when modification methods such as DateTime::modify() are called.


Video Answer


3 Answers

The core of the difference is described in the documentation of the DateTime class:

This class behaves the same as DateTimeImmutable except objects are modified itself when modification methods such as DateTime::modify() are called.

Let's observe this difference on a concrete example:

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

This will output:

2021-05-15
2021-05-15

What happened here is that the modify returned the same instance of the DateTime object. The variable $tomorrow doesn't contain a different object, it contains a reference to the original one. Updating the new variable modified the original one as well.

If we execute the same modification, but on the immutable version:

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

This will output:

2021-05-14
2021-05-15

Because in DateTimeImmutable, the modification methods don't return the same instance, they give you a fresh one (also immutable). This also means that you must assign its result to a variable (like in the previous example) for the immutable version in order to use it:

$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

Due to this behaviour, the immutable version should be preferred over the mutable one virtually always. Accidentally modifying an instance of a date you didn't mean to modify is quite a commonly occurring bug.

You might prefer the mutable version to avoid the step of assignment in situations where you can reliably determine there is no danger of compromising the state of your application, but that is best left to be estimated once you have a firm grasp on the concepts.

Aside from modify, the following methods are also considered as mutating:

  • add
  • sub
  • setDate
  • setISODate
  • setTime
  • setTimezone
like image 194
El_Vanja Avatar answered Nov 15 '22 03:11

El_Vanja


The difference is in the 'immutable' part, which means once the object is created it can never change (wiki for more info). What this means is that whenever you'd modify a DateTime the same instance will be changed, but when you modify a DateTimeImmutable a new modified instance will be return instead.

In general an immutable object will never change it's state after being created. Instead when a modification is needed it will return a new instance of the same class with the modified state.

The fact that these both implement the same DateTimeInterface is a bit confusing, but can be explained by the fact that the interface does not describe all available functions that the DateTime and DateTimeImmutable offer. More precisely the interface does not cover methods which allow for state changes.

The use case for picking either one or the other mostly depends on preference, coding standards and, to some degree, need for code quality vs need for speed of development.

like image 44
PtrTon Avatar answered Nov 15 '22 04:11

PtrTon


Just a quick note: if you want to avoid the assignment process you can concatenate: echo $date->modify('+1 day')->format('Y-m-d'); assuming that $date is the DateTimeImmutable object.

Example:

$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');
like image 21
Alberto Ar3s Avatar answered Nov 15 '22 04:11

Alberto Ar3s