【问题标题】:subtract offset from DateTime (date time to UTC)从 DateTime 中减去偏移量(日期时间到 UTC)
【发布时间】:2016-08-29 12:38:23
【问题描述】:

亲爱的 DB 大师,我再次需要帮助。

我有下表,我需要使用偏移列中的信息将不同的本地时间转换为格林威治标准时间

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

【问题讨论】:

  • 为什么您的偏移量存储为 +0200 而不是 +02:00?
  • 它来自以这种方式加载到数据库中的文件
  • 列的数据类型是什么? (我猜是 datetime 和 varchar)
  • 好猜测 :) 列是订单时间 - 日期时间和偏移量 - varchar

标签: sql sql-server timezone-offset datetimeoffset


【解决方案1】:

试试这个:

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

【讨论】:

  • 抱歉,我的解释可能不清楚我实际上需要按 UTC 计算时间。例如 2016-05-03 11:25:26 与 +0300 偏移量需要变为 2016- 05-03 08:25:26 UTC
【解决方案2】:

我使用LEFT 获取符号和小时数,使用LEFT + RIGHT 获取符号和分钟数,然后使用CASTvarchar 值更改为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

【讨论】:

    【解决方案3】:

    另一种方式:

    ;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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 2021-07-07
      • 1970-01-01
      • 2015-02-14
      • 2011-03-22
      • 2014-02-04
      相关资源
      最近更新 更多