如何将Sql Server 2008 DateTimeOffset转换为DateTime

Pur*_*ome 43 sql sql-server datetime datetimeoffset sql-server-2008

我希望将具有DATETIMEOFFSET字段的表转换为字段,DATETIME但通过注意偏移重新计算时间.实际上,这会将值转换为UTC.

例如.

CreatedOn: 2008-12-19 17:30:09.0000000 +11:00
Run Code Online (Sandbox Code Playgroud)

将被转换为

CreatedOn: 2008-12-19 06:30:09.0000000
Run Code Online (Sandbox Code Playgroud)

要么

CreatedOn: 2008-12-19 06:30:09.0000000 + 00:00 -- that's a `DATETIMEOFFSET`, but `UTC`.
Run Code Online (Sandbox Code Playgroud)

干杯:)

Ric*_*iwi 59

使用几乎任何样式进行转换都会导致datetime2值转换为UTC.
此外,从datetime2到datetimeoffset的转换只是将偏移量设置为+00:00,如下所示,因此它是一种快速转换Datetimeoffset(offset!=0)Datetimeoffset(+00:00)

declare @createdon datetimeoffset
set @createdon = '2008-12-19 17:30:09.1234567 +11:00'

select CONVERT(datetime2, @createdon, 1)
--Output: 2008-12-19 06:30:09.12

select convert(datetimeoffset,CONVERT(datetime2, @createdon, 1))
--Output: 2008-12-19 06:30:09.1234567 +00:00
Run Code Online (Sandbox Code Playgroud)

  • 可以解释一下CONVERT的最后一个参数"1"是什么意思吗?此参数的所有示例都使用字符类型作为输出或输入类型.这里我们将datetimeoffset转换为datetime. (3认同)
  • 请注意下面@ user166390的答案。_“如果未指定样式,则时区信息将在转换中被丢弃” _。如果您未指定第三个参数(无论是1还是其他参数),则会丢失正确的UTC转换 (2认同)

小智 26

我使用内置的SQL选项:

select SWITCHOFFSET(cast('2008-12-19 17:30:09.0000000 +11:00' as datetimeoffset),'+00:00')
Run Code Online (Sandbox Code Playgroud)


Jer*_*emy 21

我知道这是一个老问题但是,如果你想将DateTimeOffset转换为DateTime,我认为你需要考虑你要转换的服务器的时区.如果您只是执行CONVERT(datetime,@ MyDate,1),您将只会丢失时区,这可能会导致转换错误.

我认为您首先需要切换DateTimeOffset值的偏移量,然后进行转换.

DECLARE @MyDate DATETIMEOFFSET = '2013-11-21 00:00:00.0000000 -00:00';
SELECT CONVERT(DATETIME, SWITCHOFFSET(@MyDate, DATEPART(tz,SYSDATETIMEOFFSET())));
Run Code Online (Sandbox Code Playgroud)

将"2013-11-21 00:00:00.0000000 -00:00"转换为偏移量为-7:00的服务器上的DateTime的结果为2013-11-20 17:00:00.000.使用上述逻辑,它不会影响服务器的时区或DateTime值的偏移量,它将在服务器时区中转换为DateTime.

我相信您需要这样做,因为DateTime值包含一个假设,即该值在服务器的时区中.

  • p/s然而,您可以解释日期时间值.它根本没有时区假设,这就是datetimeoffset存在的原因. (2认同)

Suk*_*and 10

SQL Server 中的 DateTimeoffset(时区)转换。

SQL Server 2016 (13.x) 及更高版本

例子

Select GETUTCDATE()
Select Convert(DATETIME, GETUTCDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'Central European Standard Time')
Select Convert(DATETIME, GETUTCDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'India Standard Time')
Run Code Online (Sandbox Code Playgroud)

结果将是

2020-08-18 08:22:21.640
2020-08-18 10:22:21.640
2020-08-18 13:52:21.640
Run Code Online (Sandbox Code Playgroud)

  • 这就是我一直在寻找的。我需要将时区偏移量保留到最终的日期时间值中,而不是丢弃。在另一个答案中输入 126 返回错误。谢谢! (2认同)

小智 7

注意:如果未指定样式(此处为“ 126”),则时区信息在转换中被丢弃。我不知道,它也可能以其他一些样式被丢弃-在任何情况下,以下内容都会正确调整TZ信息。参见CAST和CONVERT

select convert(datetime, cast('2008-12-19 17:30:09.0000000 +11:00' as datetimeoffset), 126) as utc;
Run Code Online (Sandbox Code Playgroud)

快乐的SQLing。

编辑

不确定是否重要,但是... datetime无法实际存储该级别的精度/准确度。如果运行以上命令,小数秒将被截断为3位数字(并且精度低于该数字)。与datetime2(和datetimeoffset(7))相同,将产生一个非截断的值:

select convert(datetime2, cast('2008-12-19 17:30:09.1234567 +11:00' as datetimeoffset(7)), 126) as utc;
Run Code Online (Sandbox Code Playgroud)

  • 我发现尝试将样式126直接从“ DATETIMEOFFSET”转换为“ DATETIME2”时,尝试使用样式126会导致错误(在SQL Server 2012中),是不受支持的样式。除了0和1之外,我没有发现其他被接受的东西(但是我没有尝试所有的东西)。126是用于将“ DATETIMEOFFSET”转换为“ VARCHAR”的有效样式。 (6认同)
  • 在SQL Server 2008 R2中进行的快速测试表明,仅使用样式“ 0”或(等效地)省略样式代码会丢弃时区信息。MSDN文档中列出的任何其他代码都将保留它。 (2认同)