2010-01-05 55 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)