2016-11-30 54 views
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

有兩件事情,我目前不能確定的

  1. 是的當前數據庫條目正確嗎2017年5月24日,這封郵件會在10:00或11:00發送嗎?用於發送消息的PHP代碼在連接到匹配歐洲/倫敦當前時區後立即爲MySQL設置會話時區。
  2. 如果數據庫條目正確,我該如何獲得PHP日期函數以便爲將來的日期提供正確的輸出?如果PHP日期函數是正確的,我如何(一般地)用正確的日期更新MySQL記錄?我只知道它應該在2017年5月24日10:00發送。當前查詢更新爲UPDATE SET NextRecurrence='2017-05-24 10:00:00' ...

回答

0

我想通了(我認爲)。

因爲MySQL目前在格林威治標準時間,所以我需要在格林威治標準時間格式化日期和時間到MySQL格式的日期和時間,即使日期是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)."' ... 

如果有人看到我在做什麼的錯誤,請告訴我!