PHP - 无法将正确的 DateTimeZone 设置为 DateTime

标签 php datetime timezone datetime-conversion

背景


我有一个设置为特定(英国)时间的事件列表。我想让用户看到他们本地时间的事件时间。例如:如果事件在英国时间 20:30 开始,荷兰用户应该看到开始时间为 21:30


问题


我已经设置好所有内容,并且正在创建新的 DateTime 对象来设置我的事件。但是,当我指定我的 DateTimeZone 对象时,它显示 +00:00 而不是我为其创建的 DateTimeZone。这意味着新时间不正确。因此,设置为 20:30 英国时间的时间仍会显示为 20:30 NL 时间,而不是 21:30

代码


这是我写的代码。据我所知,我所做的一切都是正确的,但是 DateTimeZone 在分配给 DateTime 对象时仍然不正确。

默认设置:

date_default_timezone_set('Europe/London');

应该将 DateTime 对象转换为本地时间的代码:

$user_timezone = Helper::get_user_timezone(); //contains "Europe/Amsterdam"
foreach($events as $event){
    $timestamp = $event->getDatetime()->getTimestamp();
    $local_datetime = new DateTime('@'.$timestamp, new DateTimeZone($user_timezone));
}

输入


我将使用以下 DateTime 对象作为输入:

DateTime Object
(
    [date] => 2015-02-14 19:30:00.000000
    [timezone_type] => 3
    [timezone] => Europe/London
)

输出


这会为我输出以下 DateTime 对象:

DateTime Object
(
    [date] => 2015-02-14 19:30:00.000000
    [timezone_type] => 1
    [timezone] => +00:00
)

我尝试了什么


我试过很多东西。主要是关于我设置 DateTimeZone 的顺序。

  1. 我尝试在创建 DateTime 对象之前创建一个 DateTimeZone。我确保它是一个正确的对象,然后将其设置在 DateTime 构造函数中。
  2. 我尝试首先使用时间戳作为参数创建一个 DateTime 对象,然后设置 DateTimeZone 对象(我知道有/曾经有一个 bug 导致了一些奇怪的问题直接设置 DateTimeZone 的行为)。
  3. 我已确定我要设置的时区 (Europe/Amsterdam) 根据 docs 是合法的.

我开始怀疑使用timestamp时是否不能转换日期?

我也看过这些问题的基本要点,但他们没有这样的问题:
1. Converting between timezones in PHP
2. How to convert between time zones in PHP using the DateTime class?

我又关注了几个,但现在找不到了。

问题


为什么我的 DateTime 对象得到一个不正确的 DateTimeZone

编辑


再次检查我的 DateTimeZone 对象是否正确后,我得到以下信息:

DateTimeZone Object
(
    [timezone_type] => 3
    [timezone] => Europe/Amsterdam
)

但是当我将它设置为新的 DateTime 对象时,timezone_typetimezone 都更改为:

DateTime Object
(
    [date] => 2015-02-14 19:30:00.000000
    [timezone_type] => 1
    [timezone] => +00:00
)

您会注意到不同的 timezone_typetimezone

最佳答案

使用方法DateTime::setTimeZone() :

date_default_timezone_set('Europe/London');

$date = new DateTime('2015-02-14 19:30:00');
print_r($date);
echo("Local time in London: ".$date->format('Y-m-d H:i:s')."\n");

$date->setTimeZone(new DateTimeZone('Europe/Amsterdam'));
print_r($date);
echo("Local time in Amsterdam: ".$date->format('Y-m-d H:i:s')."\n");

上面脚本的输出:

DateTime Object
(
    [date] => 2015-02-14 19:30:00.000000
    [timezone_type] => 3
    [timezone] => Europe/London
)
Local time in London: 2015-02-14 19:30:00
DateTime Object
(
    [date] => 2015-02-14 20:30:00.000000
    [timezone_type] => 3
    [timezone] => Europe/Amsterdam
)
Local time in Amsterdam: 2015-02-14 20:30:00

如果您不想修改原始的$date 对象,那么您可以克隆 并修改克隆的时区:

$roDate = clone $date;
$roDate->setTimeZone(new DateTimeZone('Europe/Bucharest'));
echo("Local time in Bucharest: ".$roDate->format('Y-m-d H:i:s')."\n");

显示:

Local time in Bucharest: 2015-02-14 21:30:00

备注

我在 OSX 上使用 PHP 5.6.6 运行代码。

DateTime 和相关类在其早期版本(PHP 5.2、PHP 5.3)中有很多错误。其中大部分已在最新版本中修复(但仍有一些隐藏的小问题)。

我的建议是使用您可以在系统上安装的最新版本的 PHP。

关于PHP - 无法将正确的 DateTimeZone 设置为 DateTime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29019927/

相关文章:

Java 8 LocalDateTime - 如何在字符串转换中保持 .000 毫秒

python - 在 Python 中设置时区

c# - .Net TimeZoneInfo ID - 它是特定于 Windows 语言的吗?

php将换行符的单引号转换为双引号

php - 如何在没有注册和对象管理器的情况下在 Magento 2 中获取当前产品?

php - 读取Excel数据(Rich Excel Data)

.net - 字符串中的日期时间格式?

php - 使用 php 从变量中获取第五个值

ruby-on-rails - 我怎样才能以 ruby 开始当前的工作日?

php - 如何使用 MariaDB 返回本地时间 SQL 结果