将SQL Server DateTime列迁移到DateTimeOffset

时间:2010-01-05 19:27:44

标签: sql sql-server tsql sql-server-2008 datetimeoffset

我有一个旧表,其中有几行有一个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

这是有效的,但是当我执行dattime到datetimeoffset赋值时,偏移量设置为0。幸运的是,我想要设置的偏移量是当前系统的偏移量。我不是tsql大师,但我似乎无法找到一个简单的方法来做到这一点。

我希望能够在转换中设置偏移量。我打算使用c#实用程序(或PowerShell),但我宁愿保持简单。

6 个答案:

答案 0 :(得分:22)

请参阅下面的doc,您可能需要以下内容:

-- 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值为a   指定的时区,同时保留   UTC值。语法是   SWITCHOFFSET(datetimeoffset_value,   时区)。例如,以下内容   代码调整当前系统   datetimeoffset值到时区GMT   05:00:

     

选择   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值作为输入;宁   它接受任何日期和时间数据   类型。其次,它没有尝试   根据时区调整时间   源值之间的差异   和指定的时区但是   而只是返回输入日期   和指定时间的时间值   zone作为datetimeoffset值。

     

的主要目的   TODATETIMEOFFSET函数是   转换非时区的类型   通过给定的DATETIMEOFFSET意识到   时区偏移。如果给定日期   和时间值是DATETIMEOFFSET,   TODATETIMEOFFSET函数更改   DATETIMEOFFSET值基于   相同的原始当地日期和时间   值加上新的给定时区   偏移量。

     

例如,当前系统   datetimeoffset值是2月12日,   2009年10:00:00.0000000 -08:00,你   运行以下代码:

     

选择   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 :(得分:4)

如果您使用的是知道datetimeoffset类型的SQL Server版本,则此语法将用于获取服务器的本地tz偏移量:

select datepart(tz,sysdatetimeoffset())

结果是MINUTES。

答案 2 :(得分:4)

如果目标时区中的DST保存处于活动状态,则这些转换功能将无法正常工作,因为时区偏移会在同一年内发生变化。

答案 3 :(得分:2)

您可以使用以下内容确定当前SQL Server的偏移量。

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

你需要在几分钟而不是几小时内得到补偿,因为有半小时甚至四分之一小时的时区。

使用分钟值,您可以使用类似

之类的内容更改您的值(假设它们在历史记录中都记录为当地时间)
select dateadd(mi,datediff(MI,getdate(), getutcdate()), yourDateField)

为了提高效率,我会将其计算一次变量并使用它,因为差异不会改变。

答案 4 :(得分:1)

对于任何试图正确解决此问题的人来说,在这里考虑DST就是这样做的工具。

https://github.com/mj1856/SqlServerTimeZoneSupport

答案 5 :(得分:1)

这是已经提供的答案的略微变化,并未考虑DST更改。但是,它可能足以用于许多目的:

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