Search code examples
phpdatetimevar-dump

DateTime instance property changes due to a var_dump() or print_r()


I have the following code:

<?php

$date = new DateTime;
var_dump($date);
$date->timezone = 'Europe/Madrid';
var_dump($date->timezone);  // Shows 'Europe/Madrid'
var_dump($date);            // Shows 'UTC' (!)
var_dump($date->timezone);  // Shows 'UTC' (!!)

which shows the following output:

object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2017-11-08 21:21:15.596968"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(3) "UTC"
}
string(13) "Europe/Madrid"
object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2017-11-08 21:21:15.596968"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(3) "UTC"
}
string(3) "UTC"

Why $date->timezone changes back from 'Europe/Madrid' to 'UTC' when I do a simple var_dump($date)???

Using print_r() instead of var_dump() has the same result.


Solution

  • timezone is not a property of a new DateTime class. You can verify that by trying to access it immediately after creating the DateTime object.

    $date = new DateTime;
    echo $date->timezone;
    

    This will get you an undefined property notice.

    PHP creates the timezone property to display when you do print_r or var_dump on the object, but modifying that property does not modify the underlying data.

    The next time you var_dump or print_r the object, the display properties will be regenerated, overwriting your changes.

    You can use the setTimezone method instead if you really do need to change the timezone.

    $date->setTimezone(new DateTimeZone('Europe/Madrid'));
    

    (Or set the timezone in your PHP configuration.)


    Interestingly enough, referring directly to the timezone property still shows the old value even after you update it with setTimezone. Apparently you need to var_dump the whole object for it to recreate those properties.

    $date = new DateTime;
    var_dump($date);     // Shows 'UTC'
    $date->setTimezone(new DateTimeZone('Europe/Madrid'));
    var_dump($date->timezone);  // Still shows 'UTC' (!)
    var_dump($date);            // Shows 'Europe/Madrid'
    var_dump($date->timezone);  // Shows 'Europe/Madrid'