Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 674
leora Avatar asked Mar 03 '13 18:03

leora


People also ask

What is time zone API?

The Time Zone API provides time offset data for locations on the surface of the earth. Request the time zone information for a specific latitude/longitude pair and date. The API returns the name of that time zone, the time offset from UTC, and the daylight savings offset.


2 Answers

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;
}
like image 59
Jesse Avatar answered Oct 20 '22 00:10

Jesse


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.

like image 32
jim mcnamara Avatar answered Oct 19 '22 23:10

jim mcnamara