简体   繁体   中英

subtract offset from DateTime (date time to UTC)

Dear DB gurus once again I need help.

I have the following table and I need to use the information in the Offset column to turn the different local times to GMT

Order Time          Offset
2016-05-03 10:08:22 +0200
2016-05-03 10:08:22 +0300
2016-05-03 13:11:26 +0200
2016-05-03 11:07:27 +0200
2016-05-03 14:22:35 +0200
2016-05-03 16:31:36 +0300

the result that I aim at is something like this

Order Time          
2016-05-03 08:08:22
2016-05-03 07:08:22 
2016-05-03 11:11:26 
2016-05-03 09:07:27 
2016-05-03 12:22:35 
2016-05-03 13:31:36

Actually I need to calculate the time by UTC.

For example 2016-05-03 11:25:26 with +0300 offset needs to become 2016-05-03 08:25:26 UTC.

Try this:

SELECT TODATETIMEOFFSET([Order Time], '-' +
            substring(t.Offset, 2, len(t.Offset) - 2) + ':' +
            substring(t.Offset, len(t.Offset) - 2, 2))
FROM yourtable t

I've used LEFT to get the sign and the number of hours and LEFT + RIGHT to get the sign and the number of minutes, then used CAST to changed the varchar values to int values, and from there it's just a simple DATEADD for minutes and DATEADD for hours:

Declare sample table

DECLARE @YourTable As Table
(
    [Order Time] datetime,
    Offset varchar(6)
)

Populate sample table

INSERT INTO @YourTable VALUES 
('2016-05-03 10:08:22', '+0200'),
('2016-05-03 10:08:22', '+0300'),
('2016-05-03 13:11:26', '-0200'), -- Note: - 2 hours
('2016-05-03 11:07:27', '+0200'),
('2016-05-03 14:22:35', '+0200'),
('2016-05-03 16:31:36', '-0325') -- Note: - 3 hours 25 minutes

Select

SELECT  Offset, [Order Time],
        DATEADD(HOUR, 
                -CAST(LEFT(Offset, LEN(Offset)-2) as int), 
                DATEADD(MINUTE, 
                        -CAST(LEFT(Offset, 1) + RIGHT(Offset, 2) as int), 
                        [Order Time])
                ) As [Order Time UTC]
FROM @YourTable

Results

Offset  Order Time                  Order Time UTC
------  -----------------------     -----------------------
+0200   2016-05-03 10:08:22.000     2016-05-03 08:08:22.000
+0300   2016-05-03 10:08:22.000     2016-05-03 07:08:22.000
-0200   2016-05-03 13:11:26.000     2016-05-03 15:11:26.000 -- Note: - 2 hours
+0200   2016-05-03 11:07:27.000     2016-05-03 09:07:27.000
+0200   2016-05-03 14:22:35.000     2016-05-03 12:22:35.000
-0325   2016-05-03 16:31:36.000     2016-05-03 19:56:36.000 -- Note: - 3 hours and 25 minutes

Another way:

;WITH cte AS (
SELECT *
FROM (VALUES
('2016-05-03 10:08:22', '+0200'),
('2016-05-03 10:08:22', '+0300'),
('2016-05-03 13:11:26', '+0200'),
('2016-05-03 11:07:27', '+0200'),
('2016-05-03 14:22:35', '+0200'),
('2016-05-03 16:31:36', '+0300')
) AS t([Order Time], Offset)
)

SELECT CAST(SWITCHOFFSET(TODATETIMEOFFSET([Order Time], STUFF(Offset,4,0,':')),'-00:00')as datetime)
FROM cte

Output:

2016-05-03 08:08:22.000
2016-05-03 07:08:22.000
2016-05-03 11:11:26.000
2016-05-03 09:07:27.000
2016-05-03 12:22:35.000
2016-05-03 13:31:36.000

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM