转换为我的时区 - SQL Server

时间:2018-01-23 12:13:57

标签: sql sql-server sql-server-2014

有人能帮我一个忙吗?

我有一个源数据,它位于另一个国家/地区的另一台服务器上,当我将它转到我的B.I Staging区域时,我想将其转换为我的时区,但我的SQL Server版本是2014年。

我无法使用AT TIME ZONE SQL Server功能。 如果不修复下面的硬编码值,还有其他方法吗?

以下结果并不能解决我的问题,因为它的硬编码值为:

SELECT SWITCHOFFSET (DATETIMEFIELD, '-03:00')
SELECT TODATETIMEOFFSET(DATETIMEFIELD,'-03:00')

Ps:不要忘记DAYLIGHT SAVING

1 个答案:

答案 0 :(得分:0)

没有任何样本数据,这在黑暗中非常刺激,至少试图解释它。请注意,这不是傻瓜式证明。例如,当时钟返回时,时间01:00:00 - 01:59:59将发生两次。这些时间始终被假定为之前 DST,无论它们是否真的如此。

无论如何,首先我创建了一个小表,其中包含DST在英国(GMT:UTC + 0)和东美(EST:UTC - 5)发生的日期。

然后,我使用该数据创建了如下查询。

USE Sandbox;
GO
--SAmple Daylight Savings Table
CREATE TABLE DaylightSaving (Timezone char(3),
                             ClocksChangeDate datetime,
                             Change smallint,
                             UTCDiff smallint);
--Dates for UK
INSERT INTO DaylightSaving
VALUES ('GMT','20170326 02:00:00',1,0),
       ('GMT','20171029 02:00:00',0,0),
       ('GMT','20180325 02:00:00',1,0),
       ('GMT','20181028 02:00:00',0,0),
       ('GMT','20190331 02:00:00',1,0),
       ('GMT','20191027 02:00:00',0,0);

--Dates for Eastern America
INSERT INTO DaylightSaving
VALUES ('EST','20170312',1,-5),
       ('EST','20171105',0,-5),
       ('EST','20180311',1,-5),
       ('EST','20181104',0,-5),
       ('EST','20190310',1,-5),
       ('EST','20191103',0,-5);
GO
--Made up sample data

CREATE TABLE SampleData (DateAndTime datetime, Timezone char(3));

INSERT INTO SampleData
VALUES ('20180123 12:28:00.000','EST'),
       ('20180523 19:58:00.000','EST'),
       ('20181101 07:19:00.000','EST'),
       ('20190330 20:50:00.000','EST'),
       ('20190330 21:05:00.000','EST');
GO

SELECT DateAndTime AS ESTTime,
       DATEADD(HOUR, 5 + DT.Change - ST.Change, DateAndTime) AS GMTTime,
       DATEDIFF(HOUR, DateAndTime, DATEADD(HOUR, DT.UTCDiff - ST.UTCDiff + DT.Change - ST.Change, DateAndTime)) AS TimeZoneDifference,
       ST.ClocksChangeDate, DT.ClocksChangeDate
FROM SampleData SD
     CROSS APPLY (SELECT TOP 1 *
                  FROM DaylightSaving sq
                  WHERE sq.ClocksChangeDate <= SD.DateAndTime
                    AND Timezone = SD.Timezone
                  ORDER BY sq.ClocksChangeDate DESC) ST
     CROSS APPLY (SELECT TOP 1 *
                  FROM DaylightSaving sq
                  WHERE sq.ClocksChangeDate <= DATEADD(HOUR, sq.UTCDiff - ST.UTCDiff,SD.DateAndTime)
                    AND sq.Timezone = 'GMT' --your destination Timezone
                  ORDER BY sq.ClocksChangeDate DESC) DT;


GO

DROP TABLE DaylightSaving;
DROP TABLE SampleData;

编辑:请注意,2个区域之间的区别是硬编码的(我有DATEADD,其硬编码值为5),因为这是一个示例。您需要为自己的系统推断这一点,但由于我们没有看起来像什么的概念,您需要做这项工作。

编辑2:感觉就像添加时区差异一样。现在只有硬编码值是本地时区的值(在这种情况下'GMT' CROSS APPLY中的datetime

正如有几个人所说,datetime没有时区概念。如果这对您的数据至关重要,请不要使用datetimeoffset,请使用index groupcol value 1 A 10 2 B 12 3 C 10 4 A 10 5 C 17 6 A 11 7 B 15 。将UTC +/-值存储为值的一部分;做这样的事情是微不足道的。