0

我在使用 Azure Maps 为时区提供的数据尝试使用AT TIME ZONE.

当我向 Azure Maps 提供夏威夷位置的纬度/经度数据时,返回显示“夏威夷-阿留申标准时间”:

"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"
        }
      ]
    }
  ]
}
4

2 回答 2

2

Names部分中返回的字符串不是标识符。它们是源自Unicode CLDR的本地化字符串,旨在显示给最终用户。虽然其中一些在以英语呈现时可能与标识符对齐,但不能保证这一点。

他们也不是随意选择的。“夏威夷-阿留申时间”确实是该时区的法定名称,由 15 USC 260 定义(并在此处的 Wikipedia 上进行了描述)。

另一方面,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" />

您只需使用TZIDandWinID属性在该方向上进行映射。

或者,您可以使用 CLDR 的/common/supplemental/windowsZones.xml文件,因为这是权威来源。开发主干版本位于此处。它的数据看起来很相似,但属性名称不同:

<mapZone other="Hawaiian Standard Time" territory="001" type="Pacific/Honolulu"/>
于 2019-02-13T21:06:27.890 回答
1

好的,“太平洋/檀香山”是 IANA 代码。根据一些 SQL 文档,它支持所有 Windows 时区,而其他文档说它只支持机器注册表中的时区,这可能因机器而异。物理检查我的机器,我可以看到 SQL 支持 137 个时区(Select * from sys.time_zone_info)。但是,根据 Windows 文档,它有 250 个默认时区(加上一堆扩展时区)。某些地方肯定存在断开连接,但它看起来更像是 Windows/SQL 断开连接。

也就是说,“夏威夷标准时间”和“夏威夷-阿留申标准时间”似乎是相同的:https ://www.timeanddate.com/time/zones/hast

然而,当谈到夏令时,它变得更加复杂:https ://www.timeanddate.com/time/zones/hadt

我会将此线程传递给 Azure Maps 工程和数据团队以进行更深入的调查。

于 2018-12-10T18:09:37.583 回答