Вычесть смещение из DateTime (дата и время по UTC)

Уважаемые гуру БД, мне еще раз нужна помощь.

У меня есть следующая таблица, и мне нужно использовать информацию в столбце "Смещение", чтобы переключить местное время на 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

результат, к которому я стремлюсь, примерно такой

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

На самом деле мне нужно рассчитать время по UTC.

Например 2016-05-03 11:25:26 с +0300 смещение должно стать 2016-05-03 08:25:26 УНИВЕРСАЛЬНОЕ ГЛОБАЛЬНОЕ ВРЕМЯ.

3 ответа

Я использовал LEFT чтобы получить знак и количество часов и LEFT + RIGHT чтобы получить знак и количество минут, а затем использовать CAST чтобы изменить varchar значения для int ценности, и оттуда это просто DATEADD на минуты и DATEADD часами:

Объявить образец таблицы

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

Заполнить таблицу образцов

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

Результаты

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

По-другому:

;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

Выход:

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

Попробуй это:

SELECT TODATETIMEOFFSET([Order Time], '-' +
            substring(t.Offset, 2, len(t.Offset) - 2) + ':' +
            substring(t.Offset, len(t.Offset) - 2, 2))
FROM yourtable t
Другие вопросы по тегам