5

我有以下代码从位置转换为时区名称。

public TimeZoneResponse ConvertCityToTimeZoneName(string location)
{
   TimeZoneResponse response = new TimeZoneResponse();
   var plusName = location.Replace(" ", "+");
   var address = "http://maps.google.com/maps/api/geocode/json?address=" + plusName + "&sensor=false";
   var result = new System.Net.WebClient().DownloadString(address);
   var latLongResult = JsonConvert.DeserializeObject<GoogleGeoCodeResponse>(result);

   if (latLongResult.status == "OK")
   {
       var timeZoneRespontimeZoneRequest = "https://maps.googleapis.com/maps/api/timezone/json?location=" + latLongResult.results[0].geometry.location.lat + "," + latLongResult.results[0].geometry.location.lng + "&timestamp=1362209227&sensor=false";
       var timeZoneResponseString = new System.Net.WebClient().DownloadString(timeZoneRespontimeZoneRequest);
       var timeZoneResult = JsonConvert.DeserializeObject<TimeZoneResult>(timeZoneResponseString);

       if (timeZoneResult.status == "OK")
       {

           response.TimeZoneName = timeZoneResult.timeZoneName;
           response.Success = true;
           return response;
       }
   }
   return response;

}

因此,当我通过“美国纽约”时,它会返回“东部标准时间”

然后我有第二个函数,它将时间从一个源时区转换为上面检索到的另一个时区。

var timeInDestTimeZone = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(sourceDate.Date, TimeZoneInfo.Local.Id, destination.TimeZoneName);

它运行良好,直到我遇到这个例子。当我通过:澳大利亚墨尔本进入我返回的第一个功能:澳大利亚东部夏令时间

当我将澳大利亚东部夏令时间传递给我的第二个函数(作为最后一个参数)时,我得到了这个错误:

在本地计算机上找不到时区 ID“澳大利亚东部夏令时间”

关于我做错了什么的任何建议?当我查看来自第二个谷歌地图 API 调用的响应时,这些是我返回的所有字段(以 LA 为例):

{
 "dstOffset" : 0.0,
 "rawOffset" : -28800.0,
 "status" : "OK",
 "timeZoneId" : "America/Los_Angeles",
 "timeZoneName" : "Pacific Standard Time"
}

当我经过墨尔本时,我看到 TimeZoneId 字段设置为:""Australia/Hobart""。这是要查看时区计算的正确字段吗?还是我应该查看其他“偏移”字段?

任何建议将不胜感激。

4

2 回答 2

7

由于 .NET 实现时区的方式,没有内置的方法来进行1:1转换。您将不得不求助于使用 3rd 方库(或实施您自己的转换)。


这个问题要求与您正在寻找的解决方案非常相似。

提问者通过在内部使用Olson 时区数据库tz 数据库/zoneinfo 数据库/IANA 时区数据库)找到了解决方案。提问者引用了一个页面,该页面解释了有关转换的一些信息。


最后,您可以使用Noda Time,它实现了您正在寻找的这个功能。Jon Skeet 的回答让我们对图书馆在 2011 年的发展有了早期的了解。

该库的关键概念页面包含一个解释转换功能的日期/时区块。


更新

这是有关如何创建此类查找表的示例

// Note: this version lets you work with any IDateTimeZoneSource, although as the only
// other built-in source is BclDateTimeZoneSource, that may be less useful :)
private static IDictionary<string, string> LoadTimeZoneMap(IDateTimeZoneSource source)
{
    var nodaToWindowsMap = new Dictionary<string, string>();
    foreach (var bclZone in TimeZoneInfo.GetSystemTimeZones())
    {
        var nodaId = source.MapTimeZoneId(bclZone);
        if (nodaId != null)
        {
            nodaToWindowsMap[nodaId] = bclZone.Id;
        }
    }
    return nodaToWindowsMap;
}
于 2013-03-03T19:15:38.573 回答
1

100%?然后使用标准时区名称来验证:

http://en.wikipedia.org/wiki/List_of_tz_database_time_zones

如果在给定的机器上找不到时区,则没有保证的解决方法。您应该让您的代码创建一条错误消息,说明出现问题的原因。

您确实意识到给定系统的所有者/管理员可以更改这些设置,或添加新设置 - 这意味着非标准 tz 名称不在 tz 数据库中。

于 2013-03-03T19:14:21.887 回答