【问题标题】:PHP timezone function not workingPHP时区功能不起作用
【发布时间】:2011-11-03 13:15:10
【问题描述】:

我正在创建一个论坛,该论坛还存储帖子的发送时间,我需要将其转换为用户的时区。
现在,MySQL 数据库用UTC_TIMESTAMP() 存储时间(在DATETIME 类型的列中),我从http://www.ultramegatech.com/blog/2009/04/working-with-time-zones-in-php/ 上的代码创建了一个小函数来将时间转换为用户的时区。这是函数:

function convertTZ($timestamp, $tz='UTC', $format='d-m-Y H:i:s') {
    // timestamp to convert
    $timestamp = strtotime($timestamp);
    // the time formatting to use
    $format = $format;
    // the time zone provided
    $tz = $tz;

    // create the DateTimeZone object for later
    $dtzone = new DateTimeZone($tz);

    // first convert the timestamp into an RFC 2822 formatted date
    $time = date('r', $timestamp);

    // now create the DateTime object for this time
    $dtime = new DateTime($time);

    // convert this to the user's timezone using the DateTimeZone object
    $dtime->setTimeZone($dtzone);

    // print the time using your preferred format
    $time = $dtime->format($format);

    return $time;
}

我在http://assets.momo40k.ch/timezones.php做了一个测试页。

现在,当我在我的时区(即Europe/Rome)的11:50 处将帖子插入数据库时​​,它会在UTC 中插入09:50,这是正确的,根据一些在线时区转换器。
但是当我尝试使用convertTZ() 函数将其转换回Europe/Rome 时,它返回09:50,好像Europe/Rome 是UTC。如果我尝试将其转换为 GMT+2:00 时区,它会返回 10:50。谁能猜出这是为什么?


P.S:我没有使用CONVERT_TZ()SQL函数,因为我的服务器不支持命名时区,所以这个函数是我的解决方法。

【问题讨论】:

    标签: php mysql timezone


    【解决方案1】:

    确保您存储的时间戳是 UTC:

    $date = new DateTime($timestamp, new DateTimeZone("UTC"));
    $date->format(DATE_W3C); // does it gives the expected result ?
    

    顺便说一句,您的功能可以简化为:

    function convertTZ($timestamp, $tz='UTC', $format='d-m-Y H:i:s') {
        $dtime = new DateTime($timestamp, new DateTimeZone("UTC"))
        $dtime->setTimezone(new DateTimeZone("UTC"));
        return $dtime->format($format);
    }
    

    【讨论】:

    • 感谢您抽出宝贵时间回答。这似乎仍然返回 25-08-2011 09:50:51 而不是 2011-08-25 11:50:51,如果在演示的下拉列表中选择 Europe/Rome 应该是这样。
    【解决方案2】:

    MySQL 始终在内部以 UTC 存储 TIMESTAMP 字段(实际上,这是 unix 时间戳的定义)。所以当你 SELECT 或 UPDATE/INSERT/REPLACE 时,你获取或设置的时间总是在 MySQL 服务器的本地时区。

    所以一个常见的错误是存储 UTC_TIMESTAMP(),MySQL 将其解释为本地时间,因此当当前时间在内部作为 unix TIMESTAMP 存储在字段中时,它会双重转换为 UTC。

    【讨论】:

    • 感谢您抽出宝贵时间回答。如果使用CONVERT_TZ()SELECT,双重转换问题是否仍然适用?另外,我的列类型是DATETIME,而不是TIMESTAMP
    • 您获取或设置的任何字段都将位于这些操作的本地时区。因此,如果您使用 CONVERT_TZ 进行 SELECT,则 CONVERT_TZ 会将服务器本地时区的时间字段作为输入。
    • DATETIME 字段按原样存储,我相信,所以你只需要确保如果你在 UPDATE 上进行任何转换,你也在 SELECT 上做相反的事情。您还应该知道,某些时区映射函数不是一对一的,请参阅 UNIX_TIMESTAMP 文档末尾的注释:dev.mysql.com/doc/refman/5.5/en/…
    • 谢谢你。我会注意的。尽管如此,我还是不明白为什么它似乎将欧洲/罗马视为 UTC(因为任何时区都有与欧洲/罗马的偏移量)。它似乎正在跳过两个时区
    • Europe/Rome 不应该等于 UTC,你是对的。只需仔细检查您的代码并正确输入时区名称即可。
    猜你喜欢
    • 2018-03-20
    • 2013-04-18
    • 2018-07-17
    • 2014-05-19
    • 2011-04-07
    • 2012-07-12
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多