是否可以通过设置时间戳来重用datetime对象?

时间:2019-07-09 10:07:10

标签: php datetime object

我将时间戳设置为其他日期/时间,并在代码中重新使用datetime对象。仔细阅读后,最好每次创建一个新对象。最佳做法是什么?

似乎工作正常,我没有看到任何问题。

// common values
$timezone = "Australia/Melbourne";
$datetime1 = "2019-06-15 14:13:12+0000";
$datetime2 = "2019-06-10 11:12:13+0000";

$tz  = new DateTimeZone($timezone);
$dt = new DateTime();
$dt->setTimezone($tz);

// then I set a timestamp
$dt->setTimestamp(strtotime($datetime1));
$datetime = $dt->format("Y-m-d H:i:s");
echo $datetime; // 2019-06-16 00:13:12

$dt->setTimestamp(strtotime($datetime2));
$datetime = $dt->format("Y-m-d H:i:s");
echo $datetime; // 2019-06-10 21:12:13

这一切都按预期进行,但是这是正确的方法吗?我需要注意一些事情吗?

1 个答案:

答案 0 :(得分:1)

考虑以下用例:

$start = new DateTime('2019-07-09 13:00:00');
$end = $start->modify('+3 hours');

var_dump($start);
var_dump($end);

结果如下:

object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2019-07-09 16:00:00.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(16) "America/New_York"
}
object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2019-07-09 16:00:00.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(16) "America/New_York"
}

如您所见,当您期望有两个具有不同日期的变量,但最终将相同的对象设置为这两个变量时,您很容易陷入困境。

通过引用传递,无论您稍后修改哪个变量,两个变量将始终包含相同的DateTime对象。

至少有3种可能的方法可以避免这种情况:

  1. 设置变量时创建单独的对象

    $start = new DateTime('2019-07-09 13:00:00');
    $end = new DateTime('2019-07-09 16:00:00');
    
    object(DateTime)#1 (3) {
      ["date"]=>
      string(26) "2019-07-09 13:00:00.000000"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(16) "America/New_York"
    }
    object(DateTime)#2 (3) {
      ["date"]=>
      string(26) "2019-07-09 16:00:00.000000"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(16) "America/New_York"
    }
    
  2. 分配给第二个变量时克隆对象

    $start = new DateTime('2019-07-09 13:00:00');
    $end = (clone $start)->modify('+3 hours');
    
    object(DateTime)#1 (3) {
      ["date"]=>
      string(26) "2019-07-09 13:00:00.000000"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(16) "America/New_York"
    }
    object(DateTime)#2 (3) {
      ["date"]=>
      string(26) "2019-07-09 16:00:00.000000"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(16) "America/New_York"
    }
    
  3. 使用DateTimeImmutable

    $start = new DateTimeImmutable('2019-07-09 13:00:00');
    $end = $start->modify('+3 hours');
    
    object(DateTimeImmutable)#1 (3) {
      ["date"]=>
      string(26) "2019-07-09 13:00:00.000000"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(16) "America/New_York"
    }
    object(DateTimeImmutable)#2 (3) {
      ["date"]=>
      string(26) "2019-07-09 16:00:00.000000"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(16) "America/New_York"
    }
    

对于像您这样的简单用例,无需担心不变性,因为一旦回显日期和时间,您就无需重用任何日期/时间,但是在某些情况下,必须考虑不变性。