Joe*_*ish 10 sql-server timezone
SQL Server 2016添加了AT TIME ZONE运算符。从文档中:
\n\nAT TIME ZONE 实现依赖于 Windows 机制来跨时区转换日期时间值。
\n
AT TIME ZONEmscorlib.ni!TimeZoneInfo.ConvertTime根据针对简单查询的 ETW 跟踪调用该方法。乔纳森·凯哈亚斯 (Jonathan Kehayias) 发表了一篇博文,其中他从课堂上提取了所有时区规则System.TimeZoneInfo。我只能在输出中找到于 01/01/2004 或更高版本生效的规则:
Rob Farley 在一篇博客文章中提到,2000 年时区规则的更改似乎并未得到遵守AT TIME ZONE:
\n\n它通过使用 Windows 注册表来工作,其中包含所有这些信息,但遗憾的是,当回顾过去时,它\xe2\x80\x99 并不完美。澳大利亚于 2008 年更改了日期,美国于 2005 年更改了日期 \xe2\x80\x93 两国都在一年中的大部分时间实行夏令时。AT TIME ZONE 明白这一点。但它似乎并没有意识到,2000年的澳大利亚,由于悉尼奥运会,澳大利亚提前了大约两个月开始实行夏令时。
\n
我觉得有大量间接证据表明,AT TIME ZONE对于早于 2004 年的日期,操作员可能会返回不准确的结果。但是,我找不到任何AT TIME ZONE使用该类的文档System.TimeZoneInfo,这些文档AT TIME ZONE对于较旧的日期可能不准确,或者System.TimeZoneInfo该类对于较旧的日期可能不准确。
SQL Server 产品是否存在导致AT TIME ZONE2004 年之前返回不准确结果的限制?
Jos*_*ell 14
我不知道这是否是确定的,但我在 Stack Overflow 上发现了这个问答,其中包括一位前微软员工的回答(重点是我的):
.NET 跟踪一些历史记录,但并不总是准确的。您偶然发现了其中一项不准确之处。
.NET 通过注册表从 Windows 导入所有时区信息,如此处和此处所述。如果您查看注册表中的 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\Russian Standard Time\Dynamic DST,您会发现它仅跟踪 2010 年以来该时区的信息。2000 年的测试日期不会很好地发挥作用,因为它将回退到最早的可用规则(2010 年)。
所以基本上,SQL Server 正在调用 .NET,.NET 正在查找 Windows 注册表,并且 Windows 注册表不能保证具有完整的时区更改历史记录。正如您所注意到的,在现代版本的 Windows 10 上,我看到的最旧的调整规则来自 2003 年。
如果您需要比这更早的历史记录,则必须超出 SQL Server/内置 .NET Framework 库代码。我听说过有关NodaTime的好消息(它从 IANA 官方时区数据库获取信息),因此您可以使用这个构建在该项目的某些基础设施之上的开源解决方案:
如果您是一个坏人并且讨厌开源(或者您只是想这样做或其他什么),您也可以推出自己的解决方案。