没有任何样本数据,这在很大程度上是在黑暗中刺伤,至少试图解释它。请注意,这不是万无一失的。例如,当时钟返回时,时间 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;
编辑:请注意,这两个区域之间的差异是硬编码的(我有一个 DATEADD,硬编码值为 5),因为这是一个示例。您需要为自己的系统进行推断,但由于我们不知道这是什么样的,您需要完成这项工作。
编辑 2:感觉就像添加时区差异。现在只有硬编码的值是本地时区的值('GMT' 在这种情况下是第二个CROSS APPLY)
正如一些人所说,datetime 没有时区的概念。如果这对您的数据至关重要,那么不要使用datetime,使用datetimeoffset。将 UTC +/- 值存储为值的一部分;让这样的事情变得微不足道。