php:按UTC偏移量设置时区

时间:2011-09-01 20:46:11

标签: php datetime timezone

使用javascript我知道我的用户时区是UTC +3。

现在我想用这个知识创建DateTime对象:

$usersNow = new DateTime('now', new DateTimeZone("+3"));

我作为一个响应者收到:

'Unknown or bad timezone (+2)'

我做错了什么?我该如何解决?

10 个答案:

答案 0 :(得分:35)

这个怎么样......

$original = new DateTime("now", new DateTimeZone('UTC'));
$timezoneName = timezone_name_from_abbr("", 3*3600, false);
$modified = $original->setTimezone(new DateTimezone($timezoneName));

答案 1 :(得分:10)

你说:

  

使用javascript我知道我的用户时区是UTC +3。

你可能会跑这样的事情:

var offset = new Date().getTimezoneOffset();

这将返回UTC的当前偏移量,以分钟为单位,正值落在UTC以西。它返回时区!

时区不是偏移量。时区具有偏移量。它可以有多个不同的偏移量。通常有两个偏移,一个用于标准时间,一个用于夏令时。单个数值不能单独代表这一点。

  • 时区示例:"America/New_York"
    • 对应的标准偏移量:UTC-5
    • 相应的日光偏移:UTC-4

除了两个偏移之外,还包括在该时区内的两个偏移之间转换的日期和时间,以便您知道它们何时应用。还有一个关于偏移和过渡如何随时间变化的历史记录。

另见"时区!=偏移"在the timezone tag wiki

在您的示例中,您可能从javascript收到-180的值,表示当前的UTC + 3偏移量。但那只是特定时间点的偏移!如果您按照minaz's answer,您将得到一个时区,假设UTC + 3 总是正确的偏移量。如果实时区域类似于"Africa/Nairobi",除了UTC + 3之外从未使用过任何东西,那将会有效。但是就你所知,你的用户可能在"Europe/Istanbul",它在夏天使用UTC + 3,在冬天使用UTC + 2.

答案 2 :(得分:5)

自PHP 5.5.10起,DateTimeZone接受类似“+3”的偏移量:

https://3v4l.org/NUGSv

答案 3 :(得分:4)

现代回答:

$usersNow = new DateTime('now', new DateTimeZone('+0300'));

文档:

  

http://php.net/manual/en/datetimezone.construct.php

答案 4 :(得分:1)

据我在DateTimeZone上的文档中可以看出,您需要传递一个有效的时区,这里是valid个。检查others,这可能会对您有所帮助。

答案 5 :(得分:1)

你试过这个吗?

http://php.net/manual/en/function.strtotime.php

 <?php
    echo strtotime("now"), "\n";
    echo strtotime("10 September 2000"), "\n";
     echo strtotime("+5 hours");
    echo strtotime("+1 day"), "\n";
    echo strtotime("+1 week"), "\n";
    echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n";
    echo strtotime("next Thursday"), "\n";
    echo strtotime("last Monday"), "\n";
    ?>

答案 6 :(得分:1)

对于遇到此问题的任何人,我遇到了同样的问题,所以最后我扩展了DateTime类并覆盖__construct()方法以接受偏移量(以分钟为单位)而不是时区。

从那里,我的自定义__construct()计算出小时和分钟的偏移量(例如-660 = +11:00)然后使用parent::__construct()来交出我的日期,自定义格式化为包括我的偏移量,回到原来的DateTime。

因为我总是在我的应用程序中处理UTC时间,所以我的类也通过减去偏移来修改UTC时间,所以通过午夜UTC和-660的偏移将显示我上午11点

我的解决方案详见:https://stackoverflow.com/a/35916440/2301484

答案 7 :(得分:0)

DateTimeZone需要一个时区而不是一个时区

答案 8 :(得分:0)

这一点让Matthew的答案更进一步,将日期的时区更改为任何整数偏移量。

public static function applyHourOffset(DateTime $dateTime, int $hourOffset):DateTime
{
    $dateWithTimezone = clone $dateTime;

    $sign = $hourOffset < 0 ? '-' : '+';
    $timezone = new DateTimeZone($sign . abs($hourOffset));
    $dateWithTimezone->setTimezone($timezone);

    return $dateWithTimezone;
}

注意:由于接受了答案,我的生产中断了。

答案 9 :(得分:0)

感谢Joey Rivera的链接,我被引导到一个解决方案。与其他人在此处所说的一样,时区不是您需要有效时区的偏移。

这就是我自己使用的

$singapore_time = new DateTime("now", new DateTimeZone('Asia/Singapore'));


var_dump( $singapore_time );

我自己发现使用YYYY-MM-DD HH:MM格式会更方便。示例

$original = new DateTime("2017-05-29 13:14", new DateTimeZone('Asia/Singapore'));