php - MySQL 与 PHP 的时区问题

标签 php mysql timezone

背景:我有一些 PHP 代码,用于计算下一次应根据各种规则发送重复消息的时间。我还有一个健全页面,可以仔细检查下一次重复是否正确。由于时区问题,我不确定如何解决,理智页面显示了一些问题,我不确定它们是否确实是问题。

我相信这些之所以出现,是因为( future )日期是在 BST(英国夏令时)期间,但欧洲/伦敦时区目前是 GMT。

我创建了一个非常简化的测试页面来调试和测试一个示例。代码如下:

// Not included: DB connection setup, which includes a query to set the MySQL session timezone to the current timezone for Europe/London as calculated by PHP

// Copied from a comment at http://php.net/manual/en/function.date-default-timezone-get.php
function timezone_offset_string( $offset )
{
    return sprintf( "%s%02d:%02d", ( $offset >= 0 ) ? '+' : '-', abs( $offset / 3600 ), abs( $offset % 3600 ) );
}

$offset = timezone_offset_get( new DateTimeZone( date_default_timezone_get() ), new DateTime() );

// query_multiple() is a function to get a single result from the database and return it as the specified PDO type
$db = query_multiple("SELECT NextRecurrence, UNIX_TIMESTAMP(NextRecurrence) AS NextTS, IF(@@session.time_zone = 'SYSTEM', @@system_time_zone, @@session.time_zone) AS DBTZ FROM RecurringMessages WHERE RecurID=96 LIMIT 1", "", "", PDO::FETCH_ASSOC);

print "DB Date of NextRecurrence  : ".$db['NextRecurrence']."<br>";
print "DB timestamp of NextRecurrence  : ".$db['NextTS']."<br>";
print "DB timezone  : ".$db['DBTZ']."<br>";

print "PHP timezone and offset: " .date_default_timezone_get().", ".timezone_offset_string( $offset ) . "<br>";
print "PHP date of NextTS : ".date('Y-m-d H:i:s', $db['NextTS'])."<br>";

该页面的输出如下:

DB Date of NextRecurrence : 2017-05-24 10:00:00
DB timestamp of NextRecurrence : 1495620000
DB timezone : +00:00
PHP timezone and offset: Europe/London, +00:00
PHP date of NextTS : 2017-05-24 11:00:00

如您所见,尽管 PHP 和 MySQL 时区相同,但 PHP 日期相差一小时。如上所述,我认为这是因为给出的日期是 BST 期间,而欧洲/伦敦目前是 GMT。

如果我将 1495620000 放入 http://www.epochconverter.com/ ,它告诉我现在是 Wed, 24 May 2017 10:00:00 GMT

目前有两件事我不确定

  1. 当前数据库条目是否正确?到了2017年5月24日,这条消息会在10:00还是11:00发送?用于发送消息的 PHP 代码在连接后立即设置 MySQL 的 session 时区,以匹配欧洲/伦敦的当前时区。
  2. 如果数据库条目正确,如何让 PHP 日期函数为我提供任何 future 日期的正确输出?如果 PHP 日期函数正确,我如何(一般)用正确的日期更新 MySQL 记录?我只知道应该在2017年5月24日10:00发送。目前,查询更新为 UPDATE SET NextRecurrence='2017-05-24 10:00:00' ...

最佳答案

我想通了(我想)。

因为 MySQL 目前处于 GMT,所以我需要以 GMT 向 MySQL 提供 Y-m-d H:i:s 格式的日期和时间,即使该日期是在 BST 期间。

// $ts contains the correct unix timestamp

$offsetnow=date('Z');
$tsoffset=date('Z', $ts);
$diff=$offsetnow-$tsoffset;

// Add the difference to the timestamp so that the PHP date returns the appropriately presented Y-m-d H:i:s to MySQL, which as of writing this is GMT.
$ts+=$diff;

$query="UPDATE Recurrences SET NextRecurrence='".date('Y-m-d H:i:s', $ts)."' ...

如果有人发现我所做的事情有错误,请告诉我!

关于php - MySQL 与 PHP 的时区问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40895834/

相关文章:

php - 为用户注册插入数据 PHP/PDO

javascript - 获取div后面的数据

php - 安全的 PHP 查询?

mysql - 仅当每个元素都满足条件时才选择组

Javascript:如何根据设备获取用户的时区?

php - 将列拆分为单独的变量

php - 如何以与子句中给定的顺序相同的顺序获取查询结果

mysql - 按任意顺序对多行进行分组

iphone - 获取特定地理位置的时间

go - 获取完整的 UTC 偏移量格式