DateTime 实例 属性 由于 var_dump() 或 print_r() 而发生变化

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

我有以下代码:

<?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' (!!)

显示以下输出:

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"

为什么当我做一个简单的 var_dump($date)$date->timezone 从 'Europe/Madrid' 变回 'UTC'???

使用 print_r() 而不是 var_dump() 具有相同的结果。

timezone 不是新 DateTime class 的 属性。您可以通过在创建 DateTime 对象后立即尝试访问它来验证这一点。

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

这会给你一个未定义的 属性 通知。

PHP 创建 timezone 属性 以在您对对象执行 print_rvar_dump 时显示,但修改 属性不修改基础数据。

下次您 var_dumpprint_r 对象时,将重新生成显示属性,覆盖您的更改。

如果确实需要更改时区,可以使用 setTimezone 方法。

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

(或者在您的 PHP 配置中设置时区。)


有趣的是,直接引用 timezone 属性 仍然显示旧值,即使您使用 setTimezone 更新它。显然,您需要 var_dump 整个对象才能重新创建这些属性。

$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'