How do I deep copy a DateTime object?

Clone the date with the clone operator:

$date1 = new DateTime();
$date2 = clone $date1;
$date2->add(new DateInterval('P3Y'));

Clones are shallow by default, but deep enough for a DateTime. In your own objects, you can define the __clone() magic method to clone the properties (i.e. child objects) that make sense to be cloned when the parent object changes.

(I'm not sure why the documentation thinks a good example of needing to clone an object is GTK. Who uses GTK in PHP?)


PHP 5.5.0 introduced DateTimeImmutable. add and modify methods of this class return new objects.

$date1 = new DateTimeImmutable();
$date2 = $date1->add(new DateInterval('P3Y'));

TLDR (PHP 5.5+ / 7.0.0+ / 8.0.0+):

Use DateTimeImmutable: it does not alter the original instance :-)

<?php
$date1 = new DateTimeImmutable(); // Immutable => VERY IMPORTANT
$date2 = $date1->modify('+3years');
// see that $date1 still has the original year
echo $date1->format('Y-m-d H:i:s'); // outputs 2022-05-01 12:59:50
echo PHP_EOL;
echo $date2->format('Y-m-d H:i:s'); // outputs 2025-05-01 12:59:50

BTW: If you use Carbon there is also CarbonImmutable

PHP docs: https://www.php.net/manual/en/class.datetimeimmutable.php

Simple as that :)

Old answer(rewritten) (don't recommend anymore!):

Shallow copy used to be enough - Deep copy-ing DateTime didn't make sense back then, since we could easily introspect the DateTime instance and see that there were only simple types that are copied by value (there were no references).

Following code however stopped working in PHP7.4 (most likely the future solution will be somewhere around Reflection class/object),

class TestDateTime extends DateTime{
  public function test(){
   //*this* way also outputs private variables if any...
   var_dump( get_object_vars($this) );    
  }
}
$test = (new TestDateTime())->test();

used to output

array(3) {
  ["date"]=>
  string(26) "2019-08-21 11:38:48.760390"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(3) "UTC"
}

so there are no references, just simple types => there was no real reason to deep copy, however I don't recommend using this anymore in the future.


$date1 = new DateTime();
$date2 = new DateTime();
$date2->add(new DateInterval('P3Y'));

Update:

If you want to copy rather than reference an existing DT object, use clone, not =.

$a = clone $b;

Tags:

Datetime

Php