简体   繁体   English

为什么我会收到此时区错误,是否有更好的方法在Google地图时区和Windows时区之间进行映射?

[英]Why am i getting this timezone error and is there a better way to map between Google Maps Timezone and Windows Time Zones?

I have the following code to Convert from location to TimeZone name. 我有以下代码从位置转换为TimeZone名称。

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;

} }

So when I pass in "New York, United States", it returns "Eastern Standard Time" 因此,当我通过“纽约,美国”时,它返回“东部标准时间”

I then have this second functions that converts a time from one source timezone into this other retrieved timezone above. 然后我有第二个函数将一个源时区的时间转换为上面的另一个检索时区。

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

Its works well until i ran into this example. 它运作良好,直到我遇到这个例子。 When I pass in: Melbourne, Australia into the first function I get back: Australian Eastern Daylight Time 当我进入时: 澳大利亚墨尔本成为我回归的第一个功能: 澳大利亚东部夏令时

When I pass Australian Eastern Daylight Time into my second function (as the final argument), I get this error back: 当我将澳大利亚东部夏令时传递到我的第二个函数(作为最终参数)时,我得到了这个错误:

The time zone ID 'Australian Eastern Daylight Time' was not found on the local computer 在本地计算机上找不到时区ID“Australian Eastern Daylight Time”

Any suggestions on what i am doing wrong? 关于我做错了什么的任何建议? When i look at the response from second google maps API call these are all of the fields that i get back (using LA as an example): 当我查看来自第二个谷歌地图API调用的响应时,这些是我得到的所有字段(以LA为例):

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

When I pass in Melbourne,I see the TimeZoneId field is set to : ""Australia/Hobart"". 当我通过墨尔本时,我看到TimeZoneId字段设置为:“”Australia / Hobart“”。 Is that the right field to look at for the timezone calculation. 这是查看时区计算的正确字段吗? Or should I be looking at the other "offset" fields? 或者我应该看看其他“偏移”字段?

Any suggestions would be greatly appreciated. 任何建议将不胜感激。

Due to how .NET implements Time Zones, there's no built-in way to do a 1:1 conversion. 由于.NET实现了时区,因此没有内置的方法来进行1:1转换。 You will have to resort to using 3rd party libraries (or implement your own conversion). 您将不得不求助于使用第三方库(或实施您自己的转换)。


This question asks for a very similar solution to what you are looking for. 这个问题要求提供与您正在寻找的非常相似的解决方案。

The asker found a solution by using the Olson Time Zone Database ( tz database/zoneinfo database/IANA Time Zone Database ) internally. 提问者在内部使用Olson时区数据库tz数据库/ zoneinfo数据库/ IANA时区数据库 )找到了解决方案。 The asker references a page which explains a bit about the conversion. 提问者引用页面这就解释了一下有关转换。


Lastly, you can use Noda Time , which implements this very functionality you are looking for. 最后,您可以使用Noda Time ,它实现了您正在寻找的功能。 Jon Skeet's answer gives an early look at the library's development back in 2011. Jon Skeet的回答早在2011年就可以看到图书馆的发展。

The library's Key Concepts page contains a Date/Time Zone block explaining the conversion functionality. 库的Key Concepts页面包含一个日期/时区块,用于解释转换功能。


UPDATE UPDATE

Here's an example on how to create such a lookup table : 这是一个关于如何创建这样的查找表示例

// 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;
}

100%? 100%? then use standard timezone names to validate: 然后使用标准时区名称来验证:

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

If the timezone is not found on the given machine there is NO GUARANTEED WORKAROUND. 如果在给定的计算机上找不到时区,则无法保证可以使用。 You should have your code create an error message stating why there was a problem. 您应该让代码创建一条错误消息,说明出现问题的原因。

You do realize that it is possible for the owner/admin of a given system to change those settings, or add new ones - meaning non-standard tz names not in the tz database. 您确实意识到给定系统的所有者/管理员可以更改这些设置或添加新设置 - 这意味着非标准tz名称不在tz数据库中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM