Specially for students of the Backend Developer in PHP course , they prepared a translation of an interesting article about the side effect of a popular tool. 
      
        
        
        
      
    
      
        
        
        
      
     
      
        
        
        
      
    
      
        
        
        
      
    
      
        
        
        
      
      Working with dates and times in PHP is sometimes annoying because it leads to unexpected bugs in the code: 
      
        
        
        
      
    
      
        
        
        
      
    $startedAt = new DateTime('2019-06-30 10:00:00'); $finishedAt = $startedAt->add(new DateInterval('PT3M')); var_dump($startedAt->format('Ymd H:i:s')); 
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
 
      
        
        
        
      
      Both the 
$startdate
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     and 
$finishdate
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     are in a hurry for three minutes, because methods like 
add ()
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     , 
sub()
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     or 
modify()
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     also modify the DateTime object they are called for before returning it.  The above example, of course, shows unwanted behavior. 
      
        
        
        
      
    
      
        
        
        
      
      We can fix this error by copying the object referenced before interacting with it, for example: 
      
        
        
        
      
    
      
        
        
        
      
     $startedAt = new DateTime('2019-06-30 10:00:00'); $finishedAt = clone $startedAt; $finishedAt->add(new DateInterval('PT3M'));
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
 
      
        
        
        
      
      Every time I come across a clone in PHP code, it smells like a hack of someone's failed code architecture.  In this case, we used cloning to avoid changing behavior, but at the same time, the code became ugly and acquired a lot of unnecessary noise. 
      
        
        
        
      
    
      
        
        
        
      
      Alternatively, the problem can be resolved by converting the original 
DateTime
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     instance to 
DateTimeImmutable
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     : 
      
        
        
        
      
    
      
        
        
        
      
     $startedAt = new DateTime('2019-06-30 10:00:00'); $finishedAt = DateTimeImmutable::createFromMutable($startedAt)->add(new DateInterval('PT3M'));
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
 
      
        
        
        
      
      Why not use 
DateTimeImmutable
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     from the very beginning? 
      
        
        
        
      
    
      
        
        
        
      
      Uncompromising Use of DateTimeImmutable 
      
        
        
        
      
      Instead of manually applying security methods to prevent unexpected changes when passing date / time objects, use 
DateTimeImmutable
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     , which encapsulates methods, making your code more reliable. 
      
        
        
        
      
    
      
        
        
        
      
     $startedAt = new DateTimeImmutable('2019-06-30 10:00:00'); $finishedAt = $startedAt->add(new DateInterval('PT3M')); var_dump($startedAt->format('Ymd H:i:s')); 
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
 
      
        
        
        
      
      In most cases, the concept of a date is considered as a value, we compare the dates by their values, and when we change the date, it becomes a different date.  All this correlates perfectly with the concept of 
Value Object , and one of the important characteristics of value objects is that they are immutable. 
      
        
        
        
      
    
      
        
        
        
      
      Detailed coding style 
      
        
        
        
      
      Immutability forces you to explicitly reassign a 
DateTimeImmutable
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     object every time you interact with it, since it never changes its value, instead returning a copy.  After many years of working with DateTime and because mutability is the default value in many imperative programming languages, itโs hard to get rid of the habit of using it and conform to a new style of writing code that promotes remapping: 
      
        
        
        
      
    
      
        
        
        
      
     $this->expiresAt = $this->expiresAt->modify('+1 week');
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
 
      
        
        
        
      
      Statistical analysis tools such as 
PHPStan and 
one of its extensions can warn us if we omit the assignment and use 
DateTimeImmutable
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     incorrectly. 
      
        
        
        
      
    
      
        
        
        
      
      However, such a cognitive bias towards variability is suppressed when we perform arithmetic operations on the values โโof primitives, for example: 
$a + 3;
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      .  In itself, this is perceived as a meaningless statement that clearly lacks a reassignment: 
$a = $a + 3;
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      or 
$A += 3;
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      .  It would be cool to use something like this in the case of value objects, right? 
      
        
        
        
      
    
      
        
        
        
      
      Some programming languages โโhave syntactic sugar called 
operator overloading, which allows you to implement operators in user-defined types and classes so that they behave just like primitive data types.  I would not mind if PHP borrowed this trick from some other programming language, and we could write as follows: 
      
        
        
        
      
    
      
        
        
        
      
     $this->expiresAt += '1 week';
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
 
      
        
        
        
      
      One-time calculations 
      
        
        
        
      
      Some people argue that in terms of performance, it is better to use 
DateTime
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     , since the calculations are performed within the same execution area.  This is acceptable, however, if you do not need to perform hundreds of operations, and you remember that links to old 
DateTimeImmutable
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     objects will be collected by the garbage collector, in most cases, in practice, memory consumption will not be a problem. 
      
        
        
        
      
    
      
        
        
        
      
      Date / time libraries 
      
        
        
        
      
      Carbon is an extremely popular library that extends the Date / Time API in PHP, adding a rich feature set.  More precisely, it extends the API of the 
DateTime
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     mutable class, the use of which is contrary to the topic of this article. 
      
        
        
        
      
    
      
        
        
        
      
      Therefore, if you enjoy working with Carbon but prefer immutability, I suggest you familiarize yourself with 
Chronos .  This is a standalone library, which was originally based on Carbon, paying particular attention to providing immutable default date / time objects, but it also includes mutable options in case of need. 
      
        
        
        
      
      Edited (07/05/2019): It turned out that Carbon has an immutable date / time option, which is a big plus.  However, the reason I prefer Chronos is that, unlike Carbon, it encourages and promotes default immutability, both in code and in documentation, and these are decisive factors in the context of this article. 
      
        
        
        
      
      Last thought 
      
        
        
        
      
      DateTimeImmutable
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     was first introduced back in ancient PHP 5.5, but to my surprise, many developers are discovering it just now.  Use 
DateTimeImmutable
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     by default whenever possible, but keep in mind some of the trade-offs that I talked about that I think are more a matter of habit and a shift in mindset. 
      
        
        
        
      
    
      
        
        
        
      
      That's all.  By tradition, we are waiting for your comments, friends.