66

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

例如。

CreatedOn: 2008-12-19 17:30:09.0000000 +11:00

这将被转换为

CreatedOn: 2008-12-19 06:30:09.0000000

或者

CreatedOn: 2008-12-19 06:30:09.0000000 + 00:00 -- that's a `DATETIMEOFFSET`, but `UTC`.

干杯:)

4

6 回答 6

85

使用几乎任何样式进行转换都会导致 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
于 2011-02-10T07:01:26.620 回答
38

I'd use the built in SQL option:

select SWITCHOFFSET(cast('2008-12-19 17:30:09.0000000 +11:00' as datetimeoffset),'+00:00')
于 2014-08-21T03:02:52.113 回答
31

我知道这是一个老问题,但是,如果您想将 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())));

在偏移量为 -7:00 的服务器上将“2013-11-21 00:00:00.0000000 -00:00”转换为 DateTime 的结果将是 2013-11-20 17:00:00.000。使用上面的逻辑,不管服务器的时区是什么,或者DateTime值的偏移量,它都会转换为服务器时区的DateTime。

我相信您需要这样做,因为 DateTime 值包含该值位于服务器时区的假设。

于 2016-06-17T19:32:49.227 回答
13

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')

结果将是

2020-08-18 08:22:21.640
2020-08-18 10:22:21.640
2020-08-18 13:52:21.640
于 2020-08-18T08:26:25.253 回答
8

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

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

快乐的 SQL'ing。

编辑

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

select convert(datetime2, cast('2008-12-19 17:30:09.1234567 +11:00' as datetimeoffset(7)), 126) as utc;
于 2011-02-10T06:28:28.530 回答
0

为了考虑夏令时,我使用了以下内容:

CONVERT(
  DateTime, 
  SWITCHOFFSET(
    CONVERT(
      DateTimeOffset, 
      CONVERT(
        DateTime, 
        [time_stamp_end_of_interval], 
        120
      )
    ),
    DATENAME(
      TzOffset, 
      CONVERT(
        DateTime, 
        [time_stamp_end_of_interval], 
        120
      ) AT TIME ZONE 'Pacific Standard Time'
    )
  )
)
AS GOOD_PST

注意:time_stamp_end_of_interval是一个varchar

于 2019-07-26T15:51:48.657 回答