如何获取历史夏令时本地日期的时区偏移量?

问题描述 投票:0回答:2

有一个SQL Server使用

GETDATE()
UTC+1,所以容易出现不同的本地时间。在夏天,它产生
+02:00
(CEST),而在冬天,它是
+01:00
(CET)。

获取当前时间的时区偏移量很容易。 How to get the UTC offset for historic dates?

日期实际上不言而喻——如果它分别在 3 月和 10 月的最后一个星期日的 1 点 UTC 之间,则为 DST,否则不是。但这是应用于每个查询的繁琐启发式方法。

我似乎无法使用

SYSDATETIMEOFFSET()/TODATETIMEOFFSET/SWITCHOFFSET/DATENAME(TZOFFSET,…)
因为我需要已经 know 偏移量。在这个例子中,
AT TIME ZONE/sys.time_zone_info
退出,因为它是一个较旧的 2014 SQL 服务器。

那一定是个标准问题。除了使用 UTC 日期或存储每个日期的偏移量之外,是否有合理的方法来获取特定(地理)时区中任何日期的 DST 偏移量?

sql-server-2014 dst timezone-offset localtime
2个回答
0
投票

我改编了这个答案以找到相关的星期日,并使用 CET/CEST 的硬连线决定来解决这个问题:

DECLARE @Date DATETIME2(3) = '2008-09-15 13:38:42.951'
DECLARE @DST_Start DATETIME2(0) = (SELECT DATEADD(HOUR,1,DATEADD(DAY,DATEDIFF(DAY,'19000107',DATEADD(MONTH,DATEDIFF(MONTH,0,CONCAT(YEAR(@Date),'-03-01')),30))/7*7,'19000107')));
DECLARE @DST_End   DATETIME2(0) = (SELECT DATEADD(HOUR,1,DATEADD(DAY,DATEDIFF(DAY,'19000107',DATEADD(MONTH,DATEDIFF(MONTH,0,CONCAT(YEAR(@Date),'-10-01')),30))/7*7,'19000107')));
SELECT CONVERT(VARCHAR(29),TODATETIMEOFFSET(@Date,CASE WHEN @Date BETWEEN @DST_Start AND @DST_End THEN '+02:00' ELSE '+01:00' END),126);
-- ⇒ 2008-09-15T13:38:42.951+02:00

这种特定的有机方法没有考虑调整期间的模糊性,但无论如何这是一个症结。


0
投票

我创建了一个函数。

DECLARE @UTCDateTime DATETIME2(3) = '2023-03-08 12:00:00.0000000'
DECLARE @Localtime datetime2;
DECLARE @DST_Start DATETIME2(0) = CONVERT(datetime, CONCAT(YEAR(@UTCDateTime),'-03-12'));-- USA Begin of Daylight savings
DECLARE @DST_End   DATETIME2(0) = CONVERT(datetime, CONCAT(YEAR(@UTCDateTime),'-11-05'));-- USA End of Daylight savings
SELECT @Localtime = DATEADD(HOUR,CASE WHEN @UTCDateTime BETWEEN @DST_Start AND @DST_End THEN -4 ELSE -5 END,@UTCDateTime) 
SELECT @Localtime 
© www.soinside.com 2019 - 2024. All rights reserved.