简体   繁体   中英

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.

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

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):

{
 "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"". 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. 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. 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. Jon Skeet's answer gives an early look at the library's development back in 2011.

The library's Key Concepts page contains a Date/Time Zone block explaining the conversion functionality.


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%? 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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