2011-12-08 114 views
7

我有一個關於mysql時區的奇怪問題。如何正確設置mysql時區

在我的網站上的配置文件,我有這行設置時區:

mysql_query("SET SESSION time_zone = '$offset';"); // Offset is properly calculated, no worries about that 

有趣的是,如果我添加其他行之後這種權利像這樣:

$q = mysql_query("SELECT NOW() as now"); 
$row = mysql_fetch_array($row); 
echo $row["now"]; 

執行後該代碼,時間顯示正確。

但是,在其他一些查詢中,我在具有名爲date的列的表中插入行,該列默認爲CURRENT_TIMESTAMP。

行插入這樣的:

INSERT INTO `sessions` (`user_id`) VALUES `1` 

(會話表具有date欄默認爲CURRENT_TIMESTAMP)

但插在DB值仍然指向回服務器的時區: ((

任何想法如何通過這個工作?

+0

當你說數據庫中插入的值指向服務器時區時,如何檢查?另外,雖然你做了'SET SESSION time_zone'技巧的連接? – Romain

+0

是否在運行'INSERT'之前關閉連接? – ManseUK

+0

我在phpMyAdmin上檢查它,並且在腳本執行結束之前,nope連接沒有關閉 –

回答

19

你必須明白,MySQL的維護多個TI我區設置:

  • 系統時區(基本上是OS設置時區)
  • 服務器時區(由MySQL使用的時區)
  • 客戶端時區(每個連接使用的會話時區)

有關詳細信息,請參閱http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html

日期/時間值存儲在兩種不同的方式:基於

  • 所有的Unix時間戳值總是存儲在UTC。當它們被存儲和讀取時,它們在內部直接從客戶機時區轉換到客戶機時區。 NOW()和CURTIME()函數也是如此,因爲它們是基於時間戳的。
  • DATE,TIME和DATETIME列(以年 - 月 - 日 - 小時 - 分鐘 - 秒的格式存儲它們的值)不受時區設置的影響,也不會被轉換。

從上面可以明顯看出,當您從基於unix時間戳的列中讀取時,您看到的值不一定是真正存儲在數據庫中的值。它們使用服務器時區和客戶端時區進行轉換。如果你不瞭解機制的細節,結果可能會令人困惑。

對於第一次測試嘗試通過執行

SELECT @@global.time_zone, @@session.time_zone; 

的全球時區將始終是相同的,找出每個客戶端程序的當前設置。但會話時區可能會因客戶端應用程序和客戶端應用程序而有所不同,並會改變讀取和寫入操作的結果。

+2

非常感謝,非常啓發!我意識到phpMyAdmin顯示轉換爲服務器時區的時間,但如果我在設置會話時區後從我的腳本中的數據庫中讀取它們,它們顯得正確,所以它只是phpMyAdmin令我困惑:) –

+0

@DanyKhalife感謝您對此評論,以爲我瘋了。 – Mark

+0

@Jpsy Greate答案..我有查詢如何設置客戶端時區在MySQL confiq文件? – goodyzain