我有一个旧表,其中有几行有一个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),但我宁愿保持简单。
答案 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就是这样做的工具。
答案 5 :(得分:1)
这是已经提供的答案的略微变化,并未考虑DST更改。但是,它可能足以用于许多目的:
dateadd(minute, -datepart(tz, sysdatetimeoffset()), @legacyDatetime)