SQL Server 2016 添加了AT TIME ZONE
运算符。从文档中:
AT TIME ZONE 实现依赖于 Windows 机制来跨时区转换日期时间值。
AT TIME ZONE
mscorlib.ni!TimeZoneInfo.ConvertTime
根据针对简单查询的 ETW 跟踪调用该方法。Jonathan Kehayias 有一篇博文,他从System.TimeZoneInfo
课堂上提取了所有时区规则。我只能在输出中找到 2004 年 1 月 1 日或以后生效的规则:
Rob Farley 在一篇博文中提到,2000 年的时区规则更改似乎没有得到遵守AT TIME ZONE
:
它通过使用包含所有信息的 Windows 注册表工作,但遗憾的是,当回顾过去时,它并不完美。澳大利亚在 2008 年更改了日期,美国在 2005 年更改了日期——这两个国家在一年中的大部分时间都在节约日光。AT TIME ZONE 明白这一点。但似乎并没有意识到,在 2000 年的澳大利亚,由于悉尼奥运会,澳大利亚在大约两个月前开始实行夏令时。
我觉得有大量间接证据表明,AT TIME ZONE
操作员可能会为早于 2004 年的日期返回不准确的结果。但是,我找不到任何AT TIME ZONE
使用System.TimeZoneInfo
该类的文档,AT TIME ZONE
对于较早的日期可能不准确,或者System.TimeZoneInfo
该类对于较早的日期可能不准确。
AT TIME ZONE
是否存在导致 2004 年之前返回不准确结果的 SQL Server 产品限制?
我不知道这是否是确定的,但我在 Stack Overflow 上找到了这个问答,其中包括一位前微软员工的回答(强调我的):
.NET 是否有时区更改的历史记录?
所以基本上,SQL Server 正在调用 .NET,.NET 正在查看 Windows 注册表,并且不能保证 Windows 注册表具有完整的时区更改历史记录。正如您所注意到的,在现代版本的 Windows 10 上,我看到的最古老的调整规则是从 2003 年开始的。
如果您需要比这更早的历史,您将不得不离开 SQL Server / 内置的 .NET Framework 库代码。我听说过关于NodaTime的好消息(它从 IANA 官方时区数据库中获取信息),因此您可以使用这个构建在该项目的一些基础设施之上的开源解决方案:
SQL Server 时区支持 - GitHub
如果您是一个坏人并且讨厌开源(或者您只是想要或其他什么),您也可以推出自己的解决方案。