2017-05-04 55 views
6

MySQL有兩種數據類型,專門用於存儲日期&時間值 - DATETIMETIMESTAMP。這兩種類型都不存儲時區信息,並且都有不同的規則。在MySQL中使用NOW()時,我可以確定正確的UTC值將被存儲在TIMESTAMP列中嗎?

A DATETIME列將存儲插入查詢中提供的確切日期&時間值。 (沒有converstions和時區沒有啓示)

TIMESTAMP列將轉換從在插入時間爲UTC的連接的時區設置在插入的日期&時間值。檢索時,它會將日期爲&的時間值從UTC存儲到檢索連接的時區。 兩個連接的時區可根據這些rules顯式或隱式設置。

現在,在我開始討論我的問題之前,我們來看看處理日期&時涉及夏令時的一些細微差別。總結在另一個Stack Overflow question以及什麼我從MySQL documentation瞭解關於日期/時間的答案:

  1. 當使用DATETIME列,並明確指定的值(即/ 2009-11-01 01:30:00),該值可以是不明確的。 DATETIME不進行對話,只是存儲這個確切的日期/時間。假設我在紐約(遵循夏令時)。在插入和檢索時,我無法指示/知道這個值是指在夏令時(UTC-4)的1:30 AM還是無日光節約時刻的1:30 AM(UTC-5 )。
  2. 當使用帶NOW()沿着DATETIME柱,NOW()計算結果爲日期&時間值在查詢執行的開始(即/ 2009-11-01 01:30:00),並且該值被插入,沒有converstions,進DATETIME場引起完全相同的歧義正如剛纔提到的。
  3. 當使用TIMESTAMP列並明確指定一個值(即/ 2009-11-01 01:30:00)時,我再次遇到了與上述相同的問題。沒有辦法指定,也無法知道我指的是哪一天。

現在,這裏是我的問題:

鑑於被設置爲包括夏令時區(比如America/New York)MySQL數據庫連接,我可以肯定的是將NOW()TIMESTAMP列將導致正確的UTC日期&要存儲的時間值? UTC當然不遵守夏令時,所以UTC時間爲1:30 am紐約時區夏時制時間與UTC時間不同上午1:30紐約時區無日光節約時刻

更具體地說:是對UTC偏移量查詢執行的開始連接時區的用途是什麼,當我從一個TIMESTAMP柱插入/選擇進行到UTC /從-UTC轉換?回到我的例子,在凌晨1:30,夏令時(America\New York時區),我在UTC-4和上午1:30沒有夏令時(America\New York時區)我在UTC- 5 - 所以在這兩個時刻,當我明確插入2009-11-01 01:30:00或通過使用NOW()隱式插入相同的值時,是否會在TIMESTAMP字段中存儲不同的值?最後,如果我處於跨越這兩個時刻的單個MySQL連接中,並且我執行兩個查詢(一個在第一個時刻,另一個在第二個時刻),兩個查詢都會導致正確的(不同的)UTC值要存儲?

+0

你讀過[this](http://stackoverflow.com/questions/1646171/mysql-datetime-fields-and-daylight-savings-time-how-do-i-reference-the-extra)和[那](http://www.webdevelopersdiary.com/blog/good-to-know-how-to-properly-store-date-and-time-values-in-mysql)? –

+0

數據庫UTC。表示層用戶首選項和時區。 – danny117

回答

2

你可能想這對於服務器:

mysql> SHOW VARIABLES LIKE '%zone%'; 
+------------------+--------+ 
| Variable_name | Value | 
+------------------+--------+ 
| system_time_zone | UTC | -- Comes from OS 
| time_zone  | SYSTEM | -- Probably the 'right' setting 
+------------------+--------+ 

使用這些設置,SELECT NOW()將提供UTC時間,不是本地時間。

對於您的個人電腦,最好有system_time_zone等於Pacific Daylight Time(或其他),以反映您當前的位置。

沒有轉換髮生在INSERTingSELECTing一個DATEDATETIME。把它看作是時鐘的照片。

對於TIMESTAMP,無論您給它它將被轉換爲/從UTC。也就是說,表中存儲的位是UTC,但你看不到;您只能根據上述兩個設置查看轉換日期&時間。

我建議得到答案的最好方法是創建一個表,一個DATETIMETIMESTAMP,設置兩個設置,然後看看存儲時會發生什麼。然後更改設置並執行SELECT

+0

感謝您的回答,但我特別關注如何根據地點時區(如美國\紐約)將時區(如美國\紐約)存儲在TIMESTAMP字段中,以瞭解夏時制地點和夏時制時區的情況。 – VKK

+0

TIMESTAMP字段中的位是UTC。也就是說,在宇宙中的任何給定的秒鐘內,任何到ts字段的存儲都將根據時間和「INSERTer」的有效區域設置進行轉換。當選擇時,它將被選擇器重新轉換。如果它是具有相同設置的同一臺計算機,則會得到您存儲的內容。同時,不同區域/ DST/etc中的某人會看到不同的值。 –

+0

也許您需要製作一個顯示一些時間和區域的示例,並執行插入以及所需的選擇結果。 –

0

您可以通過使用SET time_zone功能測試TIME_ZONE變化:

mysql> create table demo (test timestamp); 
mysql> SET time_zone='-06:00'; 
mysql> insert into demo VALUES(NOW()); 
mysql> SELECT * FROM demo; 
+---------------------+ 
| test    | 
+---------------------+ 
| 2017-05-23 08:55:16 | 
+---------------------+ 

mysql> SET time_zone='+02:00'; 
mysql> insert into demo VALUES(NOW()); 
mysql> SELECT * FROM demo; 
+---------------------+ 
| test    | 
+---------------------+ 
| 2017-05-23 16:55:16 | 
| 2017-05-23 16:55:32 | 
+---------------------+ 

根據這些結果改變時區給出了一致的結果,其證明時間存儲UTC(使用timestamp時)。

+0

不錯的技術。現在用'(test DATETIME)'也可以試試。 –

+0

@RickJames使用'DATETIME'時,您在最後一次選擇時會有8小時的差異,這證明使用'DATETIME'時不會存儲UTC時間。 – Adam

+0

更改time_zone更改「8」嗎? –

0

據我所知,你最好用你的代碼做這件事。如果你真的需要通過數據庫來完成,你可以使用UTC_TIMESTAMP(),它總是會根據UTC給你當前的時間。然而依靠你的服務器時區在我看來並不是一個好主意,因爲隨着你的成長/規模,服務器必然會發生變化。

另一方面,從代碼中指定時間對於你來說更傾向於更重要/更準確,而不是讓它碰到數據庫。 (想想延遲,延遲插入和什麼不是)。

相關問題