2010-01-05 111 views
20

我有一個具有幾行的日期時間列的舊錶。我想切換到datetimeoffset,但我想能夠傳輸已經存在的數據。所以我做這樣的事情:將SQL Server DateTime列遷移到DateTimeOffset

SET IDENTITY_INSERT Table_Temp ON 

INSERT INTO Table_Temp 
    (Col0, ... ColN,) 
SELECT 
    COl0,.... ColN, from 
Table_Original; 

SET IDENTITY_INSERT Table_Temp OFF 

這工作,但偏置設定爲0時,我做的dattime到DATETIMEOFFSET分配。幸運的是我想要設置的偏移量是當前系統的偏移量。我不是tsql guru,但我似乎無法找到一個簡單的方法來做到這一點。

我希望能夠在轉換中設置偏移量。我打算去做一個C#實用程序(或PowerShell),但我寧願保持簡單。

+0

--- 謝謝你們,我本來應該說清楚,我只是想添加偏移不改變時間本身。但你們讓我在那裏! ;) – hdz 2010-01-06 18:02:38

回答

4

如果您使用一個版本的DATETIMEOFFSET類型,它知道的SQL Server,這句法會爲得到你的本地TZ服務器的偏移工作:

select datepart(tz,sysdatetimeoffset())

結果在MINUTES。

+0

謝謝你,正是我需要的。他們現在使用這麼多重疊的術語,甚至難以搜索文檔... – 2011-10-21 09:11:31

2

您可以計算出當前SQL服務器的偏移量使用以下內容。

select datediff(MI,getdate(), getutcdate()) 

你需要獲得在幾分鐘內偏移,而不是小時,因爲有一些半小時甚至一刻鐘時區。

使用分鐘值,可以使用類似

select dateadd(mi,datediff(MI,getdate(), getutcdate()), yourDateField) 

爲了提高效率改變你的價值觀會在(假定他們在歷史上的所有記錄爲本地時間),我會計算一次到一個變量和使用那是因爲差異不會改變。

+2

如果您需要考慮夏令時,則這不適用於歷史日期。對?您正在根據getdate查找當前的UTC偏移量,然後將其添加到歷史日期字段中。但是,如果您想考慮DST,則偏移會發生變化。東部標準時間是UTC-5,但東部夏令時是UTC-4。如果您想轉換歷史日期,您必須瞭解夏令時轉換。 (我只是在想它而頭痛)。 – 2011-11-11 19:50:50

+0

糾正你的錯誤,然後分批移動歷史數據,然後考慮一個不同時間點的Eacy年,並將其轉移。 – Andrew 2011-11-11 20:10:05

+0

你會如何去尋找歷史日期的抵消? – Jeremy 2016-06-09 19:23:58

22

請參見下面的文檔,你可能想是這樣的:

-- up here set the @time_zone variable. 

INSERT INTO Table_Temp 
    (Col0, ... ColN,) 
SELECT 
    COl0, TODATETIMEOFFSET(COLDATE, @time_zone),.... ColN, from 
Table_Original; 

MSDN

的SWITCHOFFSET功能調整的 輸入DATETIMEOFFSET值的 指定時區,同時保留 的UTC值。語法是 SWITCHOFFSET(datetimeoffset_value, time_zone)。例如,下面的代碼 調整當前系統 DATETIMEOFFSET值時區GMT 05:00:

SELECT SWITCHOFFSET(SYSDATETIMEOFFSET(), '-05:00');

因此,如果當前系統 DATETIMEOFFSET值是2月12日,2009年 10:00:00.0000000 -08:00,這 代碼返回值2月12日,2009年 13:00:00.0000000 -05:00。

TODATETIMEOFFSET函數設置輸入日期的時區偏移量 和 時間值。它的語法是 TODATETIMEOFFSET(date_and_time_value, time_zone)。

該功能不同於 SWITCHOFFSET有幾種方式。首先, 它不限於 datetimeoffset值作爲輸入;而是 它接受任何日期和時間數據 類型。其次,它並不試圖 調整基於源值 和指定的時區,但 之間的時區 差的時間,而不是簡單地返回輸入日期 和時間值以指定的時間 區爲DATETIMEOFFSET值。

的 TODATETIMEOFFSET功能的主要目的是 轉換不在時區 由給定 時區偏移量感知到DATETIMEOFFSET類型。如果日期 和時間值是DATETIMEOFFSET, 的TODATETIMEOFFSET功能改變 基礎上 相同的原始本地日期和時間 值加抵消新定的時區 的DATETIMEOFFSET值。

例如,當前系統 DATETIMEOFFSET值是2月12日,2009年 10:00:00.0000000 -08:00,和你 運行下面的代碼:

SELECT TODATETIMEOFFSET(SYSDATETIMEOFFSET(), '-05:00');

值2009年2月12日, 10:00:00.0000000 -05:00返回。 記住SWITCHOFFSET 函數返回的,2009年2月12日 13:00:00.0000000 -05:00,因爲它 調整基於所述輸入之間的時間 區差異 (-08:00)的時間和在指定的時間區 (-05:00)。

如前所述,您可以使用 TODATETIMEOFFSET函數和任何 日期和時間數據類型作爲輸入。對於 例如,下面的代碼利用 當前系統日期和時間值和 返回它作爲一個DATETIMEOFFSET值 與時區-00:05:

SELECT TODATETIMEOFFSET(SYSDATETIME(), 「-05: 00' );

+1

對這個訴舊帖子的一個評論。日期時間的時區和偏移是不同的事情。時區考慮到了DST,而偏移量恰好抵消了。 – 2014-06-20 11:26:34

4

如果目標時區中的DST保存處於活動狀態,這些轉換功能將無法正常工作,因爲時區偏移在同一年內發生更改。

+2

您如何正確地做到這一點,以考慮DST? – Jeremy 2016-06-09 19:23:07

0

這已經是給出了一個答案的一個微小的變化,並沒有考慮DST的變化。但是,它可能是不夠好很多目的:

dateadd(minute, -datepart(tz, sysdatetimeoffset()), @legacyDatetime)