How can I convert a Sql Server 2008 DateTimeOffset to a DateTime

119.8k views Asked by At

I'm hoping to convert a table which has a DATETIMEOFFSET field, down to a DATETIME field BUT recalculates the time by taking notice of the offset. This, in effect, converts the value to UTC.

eg.

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

that will get converted to

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

or

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

Cheers :)

7

There are 7 answers

6
RichardTheKiwi On BEST ANSWER

Converting using almost any style will cause the datetime2 value to be converted to UTC.
Also, conversion from datetime2 to datetimeoffset simply sets the offset at +00:00, per the below, so it is a quick way to convert from Datetimeoffset(offset!=0) to 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
4
AudioBubble On

Note: The timezone information is discarded in conversion if no style ("126" here) is specified. It might also be discarded in some of the other styles, I don't know -- in any case the following correctly adjusts for the TZ information. See CAST and CONVERT.

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

Happy SQL'ing.

Edit

Not sure if it matters but ... datetime Can't actually store that level of precision/accuracy. If the above is run the fractional seconds will be truncated to 3 digits (and accuracy is less than that). The same-same with datetime2 (and datetimeoffset(7)) produces a non-truncated value:

select convert(datetime2, cast('2008-12-19 17:30:09.1234567 +11:00' as datetimeoffset(7)), 126) as utc;
2
Vipeout On

I'd use the built in SQL option:

select SWITCHOFFSET(cast('2008-12-19 17:30:09.0000000 +11:00' as datetimeoffset),'+00:00')
4
Jeremy On

I know this is an old question but, if you want to convert DateTimeOffset to a DateTime, I think you need to take into account the timezone of the server you are converting on. If you just do a CONVERT(datetime, @MyDate, 1) you will simply lose the time zone, which likely results in an incorrect conversion.

I think you first need to switch the offset of the DateTimeOffset value, then do the conversion.

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

The result of converting '2013-11-21 00:00:00.0000000 -00:00' to a DateTime on a server who's offset is -7:00 will be 2013-11-20 17:00:00.000. With the above logic it doesn't mater what the time zone of the server or the offset of the DateTime value, it will be converted to DateTime in the servers time zone.

I believe you need to do this because a DateTime value includes an assumption that the value is in the time zone of the server.

0
bouvierr On

Several ways of converting from DateTimeOffset to DateTime2 (UTC or local).

On SQL Server 2019:

DECLARE @dto datetimeoffset = SYSDATETIMEOFFSET();

SELECT @dto as MyDateTimeOffset_EST                                -- 2023-05-24 15:04:59.1321648 -04:00
    ,@dto AT TIME ZONE 'UTC'     as DateTimeOffset_UTC             -- 2023-05-24 19:04:59.1321648 +00:00
    ,SWITCHOFFSET(@dto, 0)       as DateTimeOffset_UTC_also        -- 2023-05-24 19:04:59.1321648 +00:00
    ,CONVERT(datetime2, @dto AT TIME ZONE 'UTC') as DateTime2_Utc  -- 2023-05-24 19:04:59.1321648
    ,CONVERT(datetime2, @dto, 1) as DateTime2_Utc_also             -- 2023-05-24 19:04:59.1321648
    ,CONVERT(datetime2, @dto)    as DateTime2_Local                -- 2023-05-24 15:04:59.1321648
    -- If you want to change to a different time zone:
    ,@dto AT TIME ZONE 'UTC'
       AT TIME ZONE 'Pacific Standard Time' as DateTimeOffset_PST  -- 2023-05-24 12:04:59.1321648 -07:00
4
Sukesh Chand On

DateTimeoffset (Timezone) conversion in SQL Server.

SQL Server 2016 (13.x) and later

Exmample

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

Result will be

2020-08-18 08:22:21.640
2020-08-18 10:22:21.640
2020-08-18 13:52:21.640
1
Duane Pfeiffer On

In order to account for daylight savings time, I used the following:

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

Note: time_stamp_end_of_interval is a varchar