2010-10-25 26 views
1

我繼承了一個遺留應用程序,其中所有日期和時間都存儲在本地時區(英國)中。我無法改變這些存儲方式。檢測日期是否在MySql的夏令時中

但是,要求是在應用程序中顯示GMT中的所有日期。因此,當我從數據庫中檢索事件列表時,我需要它以全部時間格式顯示它們,同時觀察是否正在對每個特定事件日期進行夏令時操作。使用下面的邏輯,我可以決定是否實行夏令時的查詢中活躍:

IF(CAST(TIMEDIFF(NOW(), UTC_TIMESTAMP()) AS SIGNED) >0, 
DATE_FORMAT(CONVERT_TZ(ADDTIME(`event_date`, IFNULL(`event_time`, '00:00')), '+01:00', '+00:00'), '%H:%i'), `event_time`) AS event_time 

不過,這顯然只是檢查其在被執行的日期。因此,任何跨越夏令時邊界的事件都不起作用。

有沒有一種方法可以檢測給定日期是否在mysql查詢本身的DST中?

任何幫助,非常感謝。

+1

你能不能使用CONVERT_TZ功能在MySQL?或者它沒有給你正確的結果? http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_convert -tz – Dave 2010-10-25 10:43:16

+0

我在做。關鍵是我需要知道是否應用它。由於它存儲在本地時間,其中一些是格林威治標準時間+ 1其他格林威治標準時間+0。我不能不加選擇地將它應用於所有人。因此,我需要知道日期是否爲+1 – 2010-10-25 11:13:14

+1

我的印象是,CONVERT_TZ基於time_zone_blah表的內容自動奇蹟地考慮了夏令時,所以如果這些內容設置正確,您應該能夠簡單地做'CONVERT_TZ(event_time,「美國/東部」,「GMT」)'並讓它在格林威治標準時間給出正確的時間 – Dave 2010-10-25 12:01:58

回答

1

時區未存儲在DATETIME值中。有趣的是,它們是針對TIMESTAMP的。

給定一個存儲日期,根據當地規則,你可以追溯到當時DST是否「開啓」。由於您無法更改日期,因此我猜測您無法添加列來存儲時區...

製作包含規則並將給定日期轉換爲GMT的存儲過程。

請注意,只有居住在格林威治附近的人希望他們的時間以GMT顯示。 :)

祝你好運。

+0

**不正確。**'TIMESTAMP'類型不*存儲時區信息。恰恰相反:'TIMESTAMP'類型將輸入值調整爲UTC,然後丟棄原始時區信息。從[文檔](https://dev.mysql.com/doc/refman/5.7/en/datetime.html)引用:* MySQL將TIMESTAMP值從當前時區轉換爲UTC存儲,並從UTC返回到當前檢索的時區。* – 2018-03-05 23:28:53

+0

對於凡人,UTC在功能上是一個時區。 – 2018-03-06 23:41:49

0

你在英國。所以,你的TZ應該是CET或CEST(中歐夏令時)。您可以通過這種方式獲取信息:

mysql> SELECT @@system_time_zone; 
+--------------------+ 
| @@system_time_zone | 
+--------------------+ 
| CEST    | 
+--------------------+ 

我在許多存儲過程中都使用了這個功能。注意:我需要兩種形式的TZ信息,無論是否需要計算應用DST或不應用DST時的偏移量。

CASE @@system_time_zone 
    WHEN 'CET' THEN SET l_tz = 'Europe/Paris'; SET l_tzOff = '+1:00'; 
    WHEN 'CEST' THEN SET l_tz = 'Europe/Paris'; SET l_tzOff = '+1:00'; 
    WHEN 'SGT' THEN SET l_tz = 'Asia/Singapore'; SET l_tzOff = '+8:00'; 
    ELSE    SET l_tz = 'Europe/Paris'; SET l_tzOff = '+1:00'; 
END CASE; 

你可以從中得到一些啓發。

0

發現了一個醜陋的複雜的方式,@DT輸入日期&時間

Set @DT=20150329020304; # -> 0 

Set @DT=20150329030304; # -> 1(-0.0511) 

Set @DT=20150329040304; # -> 1(-1) 

Select 0!=(UNIX_TIMESTAMP(@DT)- UNIX_TIMESTAMP(Concat(Year(@DT),'0101',Time_Format(@DT,'%H%i%s')))-DateDiff(@DT,Concat(Year(@DT),'0101',Time_Format(@DT,'%H%i%s')))*86400)/3600 as DlsIsOn 
+0

我無法解釋這是如何工作的......但它確實如此 – ChiMo 2016-03-23 05:35:31