如何在 PHP 中重用日期时间和日期时区对象


How can I reuse DateTime and DateTimeZone objects in PHP?

我创建了一个函数将日期字符串转换为其他时区,但我的函数每次调用时都会创建新的日期时间和日期时区对象。这是不好的做法,所以我研究了如何重用这些对象。
DateTime 有一个名为 setDate 的方法,但它需要年、月和日作为参数,而不是日期字符串。日期时区没有这样的方法。

有没有办法重用我的日期时间和日期时区对象?

编辑:此函数将在单个 POST 中调用 4 到数百次,具体取决于从服务器返回的日期数。

/**
 * Converts a datestring to another timezone
 *
 * @arg $ds (String) - The datestring to be converted
 * @arg $tz (String) - The timezone to convert the datestring to
 *
 * @return (String) - The converted datetime
 */
function convertDateTime($ds, $tz) {
  $fooDateTime = new DateTime($ds);
  $fooTimeZone = new DateTimeZone($tz);
  $newDate = $fooDateTime->setTimezone($fooTimeZone);
  return $newDate->format('Y-m-d H:i:s');
}

DateTimeDateTimeZone构造函数中正在进行的工作相比,初始化新对象的开销微不足道。调用这些函数时到底发生了什么?

  1. 输入正在被解析、验证、解构,并且在DateTimeZone的情况下,时区信息正在从某个地方加载。
  2. 该数据存储在某个地方(在对象属性中,但也可能在变量、数组或其他任何内容中(。
  3. 你会得到一个句柄回到刚刚发生的工作结果(你的新对象(。

由于每个日期都是唯一的,因此无论如何都需要为每个日期进行这项工作。无论这是装扮成对象还是返回数组或其他内容的常规函数调用都是无关紧要的,几乎没有区别。

可以说,您可以记住DateTimeZone对象,因为相同的时区无论如何都是相同且不可变的。像这样:

static $timezones = [];
if (!isset($timezones[$tz])) {
    $timezones[$tz] = new DateTimeZone($tz);
}

但实际上,就您所知,PHP 已经在幕后对此进行了优化。在实践中,它可能不会产生任何明显的差异。

你当然不应该做的是改变对象并在其上设置全新的值。如果您再次阅读上面发生的事情列表,那么原因应该有意义;因为你不知道PHP在那里做了什么工作,你可能会创建不一致的对象,由于愚蠢的错误而破坏你的业务逻辑。

首先,确认这是一个问题。使用当前代码对应用进行基准测试,然后更改convertDateTime以返回硬编码字符串:

function convertDateTime($ds, $tz) {
    return '2016-02-03 15:54:00';
}

并衡量差异。

如果有的话,你可能可以记住回答,但它会增加内存消耗,恕我直言,这更有价值。

还有一件事要记住。一个说:

过早优化是万恶之源。

在PHP中,这是非常正确的,因为语言本身远非最佳。

我没有看到创建多个DateObject实例的任何不良做法,但是如果您更喜欢唯一的实例,则可以扩展DateTime类:

class MyDateTime extends DateTime
{
    public function convertDateTime( $ds, $tz )
    {
        $fooTimeZone = new DateTimeZone( $tz );
        $newDate = $this->setTimezone( $fooTimeZone );
        return $newDate->format( 'Y-m-d H:i:s' );
    }
}

这仍然是DateTimeZone阶级的问题...

请注意,这只是一个部分回答您的问题的示例(«如何重用日期时间»(,而无需进入争论

也很容易添加更多代码来重用DateTimeZone,即设置数组,然后在调用新时区时填充它。(编辑:见答案中的示例(