0
背景:我有一些PHP代码可以根据各种规则计算下次发送循环消息的时间。我也有一个理智的网页,仔细检查下一次重复是否正确。由于时区问题,我不知道如何解决,理智页面显示了一些问题,我不确定它们是否确实存在问题。MySQL与PHP的时区问题
我相信这些显示是因为(未来)日期是BST(英国夏令时)期间,但欧洲/伦敦时区目前是格林威治标准时间。
我创建了一个非常简化的测试页来调试和测试一个例子。代码如下:
// 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日期为一小时不同,即使PHP和MySQL的时区是一样。如上所述,我相信这是因为日期是BST,而欧洲/伦敦目前是GMT。
如果我把1495620000到http://www.epochconverter.com/,它告诉我,这是星期三,2017年5月24日10:00:00 GMT
有两件事情,我目前不能确定的
- 是的当前数据库条目正确吗2017年5月24日,这封邮件会在10:00或11:00发送吗?用于发送消息的PHP代码在连接到匹配欧洲/伦敦当前时区后立即为MySQL设置会话时区。
- 如果数据库条目正确,我该如何获得PHP日期函数以便为将来的日期提供正确的输出?如果PHP日期函数是正确的,我如何(一般地)用正确的日期更新MySQL记录?我只知道它应该在2017年5月24日10:00发送。当前查询更新为
UPDATE SET NextRecurrence='2017-05-24 10:00:00' ...