在使用Azure Maps提供的时区尝试使用AT TIME ZONE
来获取SQL Server(Azure SQL)中的本地时间的数据时,我遇到一个问题。
当我将Azure纬度/经度数据提供给夏威夷位置时,返回消息为“夏威夷-阿留申标准时间”:
"Names":{
"ISO6391LanguageCode":"en",
"Generic":"Hawaii-Aleutian Time",
"Standard":"Hawaii-Aleutian Standard Time",
"Daylight":"Hawaii-Aleutian Daylight Time"
},
在系统的另一部分中,我需要能够确定SQL Server中该位置的本地时间,因此我正在使用AT TIME ZONE
并注入标准时区。这对于我正在处理的美国时区(例如“东部标准时间”或“中央标准时间”)非常有用。当到达夏威夷地点时,它会出错并说这不是有效的时区。
查看我可以在线找到的SQL Server时区列表,看来夏威夷在SQL中的时区是“夏威夷标准时间”。
还有其他人遇到这种断开连接吗?
我认为我需要纠正一些异常代码,才能用“夏威夷标准时间”替换此Azure提供的时区。有更好的解决方案吗?
作为参考,下面是一个示例URL(减号):https://atlas.microsoft.com/timezone/byCoordinates/json?subscription-key={key}&api-version=1.0&options=all&query=21.4500,-158.0054
这是返回的完整JSON:
{
"Version": "2018g",
"ReferenceUtcTimestamp": "2018-12-08T17:10:31.8007137Z",
"TimeZones": [
{
"Id": "Pacific/Honolulu",
"Aliases": [
"Pacific/Johnston",
"US/Hawaii"
],
"Countries": [
{
"Name": "United States",
"Code": "US"
},
{
"Name": "US minor outlying islands",
"Code": "UM"
}
],
"Names": {
"ISO6391LanguageCode": "en",
"Generic": "Hawaii-Aleutian Time",
"Standard": "Hawaii-Aleutian Standard Time",
"Daylight": "Hawaii-Aleutian Daylight Time"
},
"ReferenceTime": {
"Tag": "HST",
"StandardOffset": "-10:00:00",
"DaylightSavings": "00:00:00",
"WallTime": "2018-12-08T07:10:31.8007137-10:00",
"PosixTzValidYear": 2018,
"PosixTz": "HST+10"
},
"RepresentativePoint": {
"Latitude": 21.306944444444444,
"Longitude": -157.85833333333332
},
"TimeTransitions": [
{
"Tag": "HST",
"StandardOffset": "-10:00:00",
"DaylightSavings": "00:00:00",
"UtcStart": "1947-06-08T12:30:00Z",
"UtcEnd": "9999-12-31T23:59:59.9999999Z"
}
]
}
]
}
答案 0 :(得分:2)
在Names
部分中返回的字符串不是标识符。它们是源自Unicode CLDR的本地化字符串,旨在显示给最终用户。尽管其中一些可能会以英语显示时与标识符对齐,但并不能保证如此。
它们也不是任意选择的。根据15 USC 260(and described on Wikipedia here)的定义,“夏威夷-阿留申时间”确实是该时区的法定名称。
另一方面,SQL Server的时区功能严格依赖Windows时区标识符(可以在Windows注册表中找到),也可以通过各种API(例如.NET的TimeZoneInfo.Id
)和命令行实用程序(例如在TZUTIL /L
返回的每对结果的第一行上。
不幸的是,看来Azure Maps API当前仅返回IANA ID,而不返回相应的Windows ID。我已经要求Azure Maps API团队考虑在以后的版本中添加它。
同时,您可以将IANA ID转换为相应的Windows ID,然后再在SQL Server中使用它。假设您使用的是.NET应用程序,最简单的方法是使用我的TimeZoneConverter库:
string tz = TZConvert.IanaToWindows("Pacific/Honolulu"); //=> "Hawaiian Standard Time"
如果您不在.NET中,则可以在以下路径使用Windows内置文件:
C:\Windows\Globalization\Time Zone\timezoneMapping.xml
文件中的条目如下所示:
<MapTZ TZID="Pacific/Honolulu" WinID="Hawaiian Standard Time" Region="001" Default="true" StdPath="Hawaii_Aleutian/standard" DltPath="Hawaii_Aleutian/daylight" />
您只需使用TZID
和WinID
属性来朝该方向进行映射。
或者,您可以使用CLDR的/common/supplemental/windowsZones.xml
文件,因为这是权威来源。开发主干版本位于here。它的数据看起来相似,但是属性的名称不同:
<mapZone other="Hawaiian Standard Time" territory="001" type="Pacific/Honolulu"/>
答案 1 :(得分:1)
好的,“ Pacific / Honolulu”是IANA代码。根据一些SQL文档,它支持所有Windows时区,而其他文档则说它仅支持计算机注册表中的时区,这可能因计算机而异。从物理上检查我的机器,我可以看到SQL支持137个时区(从sys.time_zone_info中选择*)。但是,根据Windows文档,它具有250个默认时区(以及大量扩展时区)。某些地方肯定存在断开连接,但看起来更像Windows / SQL断开连接。
也就是说,“夏威夷标准时间”和“夏威夷-阿留申标准时间”似乎是相同的:https://www.timeanddate.com/time/zones/hast
但是,关于夏时制,它变得更加复杂:https://www.timeanddate.com/time/zones/hadt
我将把该线程传递给Azure Maps工程和数据团队进行更深入的研究。