如何在PHP中重用DateTime和DateTimeZone对象?

时间:2016-02-03 15:32:54

标签: php datetime

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

有没有办法可以重用我的DateTime和DateTimeZone对象?

编辑:根据从服务器返回的日期数量,在单个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');
}

3 个答案:

答案 0 :(得分:1)

DateTimeDateTimeZone构造函数中正在进行的工作相比,初始化新对象的开销微乎其微。当你打电话给那些功能时会发生什么?

  1. 正在解析,验证,解构输入,并且在DateTimeZone时区信息正从某处加载时。
  2. 该数据存储在某处(在对象属性中,但也可能在变量,数组或其他任何内容中)。
  3. 你可以回到刚刚发生的工作的结果(你的新对象)。
  4. 由于每个日期都是唯一的,因此无论如何这项工作都需要在每个日期进行。无论是装扮成对象还是作为常规函数调用返回数组或其他东西都无关紧要,并没什么区别。

    可以说你可以记住DateTimeZone个对象,因为无论如何相同的时区是相同的和不可变的。类似的东西:

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

    但实际上,你知道PHP已经在幕后优化了这一点。它可能不会在实践中产生任何明显的差异。

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

答案 1 :(得分:0)

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

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

并衡量差异。

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

还要记住一件事。 One说:

  

过早优化是万恶之源。

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

答案 2 :(得分:0)

我没有看到创建多个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类......

的问题

请注意,这只是部分回答您的问题(«我如何重复使用DateTime»)而不进入参数的一个示例。

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