2015-11-05 165 views
2

我們使用一個程序,節省了時間標記的UTC時間。我們是猶他州本地公司,所以我們受到夏令時的影響。夏令時間和UTC時間

例如,如果我們現在收到一個電話,它是12:52:00 MST,它將作爲19:52:00保存在數據庫中。

我首先考慮的是明年當DST於2016年3月13日重新開始,我在準確的同時運行這一點。請問UTC中的時間戳是18:52:00還是保留在19:52:00

我的第二個問題是,如果我轉換數據庫的日期到我的本地時間,所以我必須首先檢查它是否DST,然後如果是花時間-6,如果沒有這將是-7?

因此,使用上面的例子:

IsDST = 01:52:00 (-6) 
IsNotDST = 12:52:00 (-7) 

我想這是我需要擔心其轉換到/從UTC?

我的主要問題除了兩個以上的擔憂。是否有內置於SQL Server/T-SQL中的任何內容來處理此轉換,還是我需要自己編寫所有內容以滿足需要?

我就開始了,但現在需要在DST工作,如果有必要

DECLARE @declared_start_datetime DATETIME, 
     @declared_end_datetime DATETIME, 
     @converted_start_datetime DATETIME, 
     @converted_end_datetime DATETIME 

SET @declared_start_datetime = '11/04/2015 07:00:00' -- Hour we open phones 
SET @declared_end_datetime = '11/04/2015 18:00:00' -- Hour we close phones 
SET @converted_start_datetime = DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), @declared_start_datetime) 
SET @converted_end_datetime = DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), @declared_end_datetime) 

select @declared_start_datetime as 'Declared Start', 
     @declared_end_datetime as 'Declared End' 
select @converted_start_datetime as 'Converted Start', 
     @converted_end_datetime as 'Converted End' 
+0

你的問題根本不清楚。你似乎知道'GETUTCDATE()',你說你想使用UTC時間戳(很好的選擇),你爲什麼要處理本地時間戳? – Amit

+0

哪一次是完全相同的時間:'12:52:00' MST或MDT?有一個重要的差異,同時注意夏令時如何在不同的時間開始,而不是很久以前就有這種轉變。 –

+0

這些報告將由公司中的其他人選擇,他們將選擇報告的運行時間(當地時間)。而且,我預示着他們必須學習/轉換爲UTC的投訴/反彈數量。所以我需要把他們的當地時間和他們轉換爲UTC從數據庫中獲取正確的記錄。 @amit –

回答

3

例如,如果我們接到一個電話,現在它是12:52:00 MST,它將被保存在數據庫爲19:52:00

我首先考慮的是明年當DST於2016年3月13日重新開始,我在準確的同時運行這一點。請問UTC中的時間戳是18:52:00還是保留在19:52:00

山區標準時間爲UTC-7,美國山區夏令時爲UTC-6。如果您寫出轉換中涉及的完整日期,時間和偏移量,則推理起來會容易得多。這是標準的ISO8601擴展格式:

2015-11-06T12:52:00-07:00 = 2015-11-06T19:52:00Z 
2016-03-13T12:52:00-06:00 = 2016-03-13T18:52:00Z 

每個當地時間等式的左邊標有正確的本地時間,該時間本地偏差。然後到達UTC(由Z標識),您只需從當地時間減去偏移量即可。或者,把它看作是顛倒標誌並加入,如果這樣更容易合理化。

所以是的,它將存儲在18:52:00 UTC當你在白天的時間。這是正確的行爲。

我的第二個問題是,如果我將數據庫中的日期轉換爲當地時間,那麼我必須首先檢查它是否是DST,然後是否需要時間-6,如果不是-7,

是的,但請記住它是由您轉換的時間戳反映的日期和時間。這都沒有區別你是否目前在DST與否。

但是,請記住,時區轉換應該通常可以避免在數據庫層,如果你們都可以幫助它。在絕大多數用例中,這是一個應用層關心的問題。例如,如果您正在使用.NET構建的應用程序寫入SQL Server,則可以使用TimeZoneInfo類和"Mountain Standard Time" ID(適用於MST和MDT)。或者,您可以使用Noda Time庫和TZDB標識符"America/Denver"

通過使用庫,您不必關心所有DST何時啓動和停止的各種細節,也不必關心它在世界各地歷史上的變化。

在極少數情況下,您實際上需要在數據庫級別完成時區轉換,您當然可以編寫自己的存儲過程或UDF(例如鏈接的某些問題評論),但根據您的需要他們可能不夠。通常,他們傾向於僅對時區轉換的一組固定規則編碼,因此他們不會考慮其他時區或歷史更改。

SQL Server有幾個通用時區解決方案,,但與其他數據庫平臺不同,中沒有任何內建內置程序。我會推薦我的SQL Server Time Zone Support OSS項目,如果你搜索,還有其他人。但是真的,你應該希望不是需要這個,並且應該儘可能地在應用層中進行轉換。

更新:對於SQL Server 2016 CTP 3.1,現在通過AT TIME ZONE語句內置支持時區。見the CTP announcement for examples

+0

謝謝馬特。不幸的是,我沒有使用應用程序,因此需要以這種方式編寫DST轉換。我將他們提供的日期並檢查它是否在DST中,然後將日期更改爲6或7,然後使用它獲取數據庫中的值。這是一個要求的自定義報告。我會檢查你提到的時區支持項目。 –

+0

請記住過渡期的時間,以及在秋季,過渡期的值可能不明確。例如'2015-11-01T01:30'可能是'2015-11-01T01:30-06:00' *或*'2015-11-01T01:30-07:00'。你需要決定選擇哪一個。如果有疑問,大多數場景需要第一個(日光)發生。雖然有時候可以根據其他相關數據來消除歧義。 –