22

我有一个旧表,其中有几行有一个日期时间列。我想将其切换到,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

这可行,但是当我执行datetimetodatetimeoffset分配时,偏移量设置为 0。幸运的是,我想设置的偏移量是当前系统的偏移量。我似乎想不出一个简单的方法来做到这一点。

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

4

6 回答 6

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:

选择 SWITCHOFFSET(SYSDATETIMEOFFSET(), '-05:00');

因此,如果当前系统 datetimeoffset 值为 2009 年 2 月 12 日 10:00:00.0000000 -08:00,则此代码返回值 2009 年 2 月 12 日 13:00:00.0000000 -05:00。

TODATETIMEOFFSET 函数设置输入日期和时间值的时区偏移量。它的语法是 TODATETIMEOFFSET(date_and_time_value, time_zone)。

此函数在几个方面与 SWITCHOFFSET 不同。首先,它不限于作为输入的 datetimeoffset 值;相反,它接受任何日期和时间数据类型。其次,它不会尝试根据源值与指定时区之间的时区差异来调整时间,而是简单地将指定时区的输入日期和时间值作为 datetimeoffset 值返回。

TODATETIMEOFFSET 函数的主要目的是通过给定的时区偏移量将不知道时区的类型转换为 DATETIMEOFFSET。如果给定的日期和时间值是 DATETIMEOFFSET,则 TODATETIMEOFFSET 函数会根据相同的原始本地日期和时间值加上新的给定时区偏移量来更改 DATETIMEOFFSET 值。

例如,当前系统 datetimeoffset 值为 2009 年 2 月 12 日 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 函数与任何日期和时间数据类型一起用作输入。例如,以下代码采用当前系统日期和时间值并将其作为时区 -00:05 的 datetimeoffset 值返回:

选择 TODATETIMEOFFSET(SYSDATETIME(), '-05:00');

于 2010-01-05T19:41:18.123 回答
4

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

select datepart(tz,sysdatetimeoffset())

结果以分钟为单位。

于 2010-10-11T15:13:06.983 回答
3

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

于 2010-12-15T06:59:09.223 回答
2

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

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

您需要以分钟而不是小时为单位获得偏移量,因为有许多半小时甚至四分之一小时的时区。

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

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

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

于 2010-01-05T19:36:22.067 回答
1

这是已经提供的答案的轻微变化,不考虑 DST 的变化。但是,它对于许多目的可能已经足够了:

dateadd(minute, -datepart(tz, sysdatetimeoffset()), @legacyDatetime)
于 2016-09-09T15:00:00.263 回答
0

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

https://github.com/mj1856/SqlServerTimeZoneSupport

于 2016-06-17T21:51:06.487 回答