【问题标题】:PHP DateTime with TimeZone to MongoDB\BSON\UTCDateTimePHP DateTime 与 TimeZone 到 MongoDB\BSON\UTCDateTime
【发布时间】:2018-12-29 07:38:40
【问题描述】:

我需要 PHP DateTime 的帮助,将 TimeZone 转换为 MongoDB\BSON\UTCDateTime。 如果我有字符串 "2015-10-20T04:02:00.608000+01:00" 它会给我一个 DateTime

$date = DateTime::createFromFormat( 'Y-m-d\TH:i:s.uT', $string );

DateTime
date => "2015-10-20 04:02:00.608000"
timezone_type => 1
timezone => "+01:00"

如果我将其转换为 MongoDB\BSON\UTCDateTime 并转换回 PHP DateTime

$mDate = new \MongoDB\BSON\UTCDateTime( $date->format('U') * 1000 );
$mDate->toDateTime()->setTimeZone(new DateTimeZone('Europe/Bratislava'))

我会得到正确的结果05:02

DateTime
date => "2015-10-20 05:02:00.000000"
timezone_type => 3
timezone => "Europe/Bratislava"

但如果输入字符串具有 +02:00 TimeZone "2015-10-20T04:02:00.608000+02:00" 并使用相同的方法得到结果是

DateTime
date => "2015-10-20 04:02:00.000000"
timezone_type => 3
timezone => "Europe/Bratislava"

如果我预期 06:02,为什么第二个结果是 04:02?

【问题讨论】:

  • 您能告诉我们您是如何创建您的第一个 PHP DateTime 的吗?
  • 问题已更新。就在那里。

标签: php mongodb datetime bson


【解决方案1】:

回答是正确的。当您在时间戳上添加+ 时区时,您实际上是从UTC 向东移动。您不是 添加 到 UTC 时间,您实际上是 减去 UTC 时间。这意味着2015-10-20T04:02:00.608000+01:00 是世界标准时间凌晨 3 点。 2015-10-20T04:02:00.608000+02:00 是世界标准时间凌晨 2 点。如果您的时区偏移量不断增加,您可以更轻松地看到这一点

$date = DateTime::createFromFormat( 'Y-m-d\TH:i:s.uT', "2015-10-20T04:02:00.608000+01:00");
$mDate = new \MongoDB\BSON\UTCDateTime( $date->format('U') * 1000 );
var_dump($date, $mDate->toDateTime());

object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2015-10-20 04:02:00.608000"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+01:00"
}
object(DateTime)#3 (3) {
  ["date"]=>
  string(26) "2015-10-20 03:02:00.000000"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+00:00"
}


$date = DateTime::createFromFormat( 'Y-m-d\TH:i:s.uT', "2015-10-20T04:02:00.608000+02:00");
$mDate = new \MongoDB\BSON\UTCDateTime( $date->format('U') * 1000 );
var_dump($date, $mDate->toDateTime());

object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2015-10-20 04:02:00.608000"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+02:00"
}
object(DateTime)#3 (3) {
  ["date"]=>
  string(26) "2015-10-20 02:02:00.000000"
  ["timezone_type"]=>
  int(1)
  ["timezone"]=>
  string(6) "+00:00"
}

MongoDB 存储 UTC 时间戳。当您添加 Europe/Bratislava 时区时,您是在说“这个 UTC 时间戳在布拉迪斯拉发的时间是什么时候”。对于 10 月(夏令时),相差 1 小时。

附带说明。尝试永远不要混合使用 +XXXX 和 Unicode/Olson 时区 (Europe/Bratislava)。由于夏令时,您最终会遇到一些非常奇怪的错误。如果您需要记录用户的本地时间以在某个时间点显示回来,请使用可选的第三个参数创建您的 DateTime 对象,例如:

$customerTz = 'Europe/Bratislava';
$date = DateTime::createFromFormat( 'Y-m-d\TH:i:s.u', $dateString, $customerTz);

还要检查您是否真的需要创建一个DateTime,或者只是一个带有时间戳的新UTCDateTime,并处理显示逻辑中的tz。

【讨论】:

  • 非常感谢。所以你说我在我的问题中得到的所有结果都是正确的?我有点困惑,因为 2015-10-20T04:02:00.608000+01:00 其中 +01:00 不正确,因为该日期的日光是 +02:00。出于测试原因,我手动添加了 +01:00。因此 php 引擎正确地添加了 +02:00 小时并使得时间为 05:02。我说的对吗?
猜你喜欢
  • 2014-01-23
  • 1970-01-01
  • 2015-08-24
  • 1970-01-01
  • 2017-04-16
  • 2011-12-04
  • 2011-09-29
  • 2022-12-01
  • 2016-10-05
相关资源
最近更新 更多