带时区的 PHP DateTime 到 MongoDB\BSON\UTCDateTime

标签 php mongodb datetime bson

我需要有关将时区转换为 MongoDB\BSON\UTCDateTime 的 PHP DateTime 的帮助。 如果我有字符串 "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?

最佳答案

回答正确。当您将 + 时区添加到时间戳时,您实际上是从 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 .

关于带时区的 PHP DateTime 到 MongoDB\BSON\UTCDateTime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53962322/

相关文章:

php - 产品网格中的自定义 SQL

php - 用Symfony 2用Elasticsearch填充索引

node.js - 在 Node.js API 中显示整个 MongoDB 内容

mongodb - 时间线注释线在 mongodb atlas Metrics 中实际代表什么?

javascript - 如何在javascript中获取两个日期时间之间的时差?

php - 如何通过 PHP 将 3 张图像合并为 1 张图像?

php - 在 Centos 6.3 中使用 php-ldap

javascript - Mongoose 内部的 `_doc` 是什么(console.log 显示使用它和不使用它的结果相同)

python - 在 Python 中获取自午夜以来的秒数

javascript - 在 JS 中获取特定时区的当前日期时间