转换为我的时区 - SQL Server
Posted
技术标签:
【中文标题】转换为我的时区 - SQL Server【英文标题】:Convert to my time zone - SQL Server 【发布时间】:2018-01-23 12:13:57 【问题描述】:有人可以帮我吗?
我有一个源数据,它位于另一个国家/地区的另一台服务器中,当我将其发送到我的 B.I 暂存区时,我想将其转换为我的时区,但我的 SQL Server 版本是 2014 年。
我无法使用 AT TIME ZONE SQL Server 功能。 有没有其他方法可以在不修复如下硬编码值的情况下做到这一点?
下面的结果并没有解决我的问题,因为它的硬编码值:
SELECT SWITCHOFFSET (DATETIMEFIELD, '-03:00')
SELECT TODATETIMEOFFSET(DATETIMEFIELD,'-03:00')
Ps:不要忘记 DAYLIGHT SAVING
【问题讨论】:
原始数据是什么数据类型?datetime
/datetime2
还是你在使用datetimeoffset
?
@Larnu 源数据是一个日期时间列
我假设,由于您提到夏令时,您或来源不使用夏令时,或者他们在不同的日子?
@EvertonGomes BTW both 函数工作并返回 datetimeoffset 值。第一个将datetime
输入视为UTC,并返回新时区中的等效时间。第二个将偏移量附加到输入。 doesn't solve my problem
是什么意思?输入值是什么,预期结果是什么?
@Tanner 没有理由这样做,如果您使用 datetimeoffset
。在这种情况下,无需担心“我的时区”是什么意思
【参考方案1】:
没有任何样本数据,这在很大程度上是在黑暗中刺伤,至少试图解释它。请注意,这不是万无一失的。例如,当时钟返回时,时间 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 +/- 值存储为值的一部分;让这样的事情变得微不足道。
【讨论】:
以上是关于转换为我的时区 - SQL Server的主要内容,如果未能解决你的问题,请参考以下文章
将 UTC 中的 SQL Server 日期时间转换为特定时区