2013-03-03 9 views
6

Mam następujący kod Konwertuj z lokalizacji na nazwę strefy czasowej.Dlaczego pojawia się ten błąd strefy czasowej i czy istnieje lepszy sposób mapowania między strefą czasową Map Google a strefami czasowymi w systemie Windows?

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; 

}

Więc kiedy przechodzą w "New York, Stany Zjednoczone", zwraca "Eastern Standard Time"

I wtedy ten drugi funkcje, które konwertuje czas z jednej strefy czasowej źródłowym do tej innej znalezionej strefy czasowej powyżej.

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

Działa dobrze, dopóki nie wpadłem na ten przykład. Kiedy mijam w: Melbourne, Australia w pierwszej funkcji wrócę: australijski Eastern Daylight Time

kiedy mijam australijskiego Eastern Daylight Time w moją drugą funkcję (jako ostatecznego argumentu), otrzymuję ten błąd tył:

strefa czasowa Identyfikator „Australijskie Eastern Daylight time” nie została znaleziona na komputerze lokalnym

Wszelkie sugestie na temat tego, co robię źle? Kiedy patrzę na odpowiedzi od sekundy Google Maps API nazywają to wszystko z pól że wrócę (używając LA jako przykład):

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

kiedy mijam w Melbourne, widzę pole TimeZoneId jest ustawiony do: "" Australia/Hobart "". Czy to odpowiednie pole do obliczenia strefy czasowej. A może powinienem patrzeć na inne pola "offsetowe"?

Wszelkie sugestie będą mile widziane.

+1

Musisz odznaczenia prawie jak Jon Skeet ... :) – gdoron

+0

To może być zrobić teraz z Noda Time 1.1.0. [Opublikowałem tutaj funkcje konwersji.] (Http://stackoverflow.com/q/17348807/634824) –

Odpowiedz

5

Ze względu na to, w jaki sposób .NET implementuje Strefy czasowe, nie ma wbudowanego sposobu na konwersję 1:1. Będziesz musiał uciec się do korzystania z bibliotek zewnętrznych (lub zaimplementować własną konwersję).


Ta prośba o bardzo podobne rozwiązanie do tego, czego szukasz.

Osoba pytająca znalazła rozwiązanie, korzystając z wewnętrznej bazy danych bazy danych strefy czasowej Olson Time Zone Database (tz/bazainfo/bazy danych strefy czasowej IANA).Pytający odwołuje się do page, który wyjaśnia nieco o konwersji.


Wreszcie, można użyć Noda Time, który realizuje tę samą funkcjonalność, którego szukasz. Jon Skeet's answer wcześnie rzuca okiem na rozwój biblioteki w 2011 roku.

Biblioteka Key Concepts page zawiera blok Date/Time Zone wyjaśniający funkcję konwersji.


UPDATE

Oto example, w jaki sposób stworzyć taką tablicę odnośnika:

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

Link, który podałem jest również dla Olsona. Twoja odpowiedź jest bardziej odpowiednia dla sytuacji PO. +1 –

-1

Wydaje mi się, że nie ma takiej strefy czasowej. Proszę sprawdzić z GetSystemTimeZones.

var timeInDestTimeZone = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(sourceDate.Date, TimeZoneInfo.Local.Id, destination.TimeZoneName//There is not maybe); 

foreach (TimeZoneInfo timeZone in timeZones) 
{ 
    Check here 
} 
+0

Rozumiem. Próbuję zrozumieć, czy szukam niewłaściwego pola do wykonania mapowania. Zaktualizowałem pytanie, aby było bardziej jednoznaczne. Z pewnością chcę amidu, który działa w 100% czasu. – leora

1

100%? a następnie za pomocą standardowych nazw strefę czasową, aby potwierdzić:

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

Jeśli strefa czasowa nie znajduje się na danym komputerze nie daje gwarancji obejścia. Powinieneś mieć swój kod, aby utworzyć komunikat o błędzie z informacją, dlaczego wystąpił problem.

Zdajesz sobie sprawę, że właściciel/administrator danego systemu może zmienić te ustawienia lub dodać nowe - co oznacza, że ​​niestandardowe nazwy tz nie znajdują się w bazie danych tz.

+0

Nie mam żadnej kontroli bitów danych wejściowych pochodzących z informacji kontaktowych osób, które nie mają kontroli nad – leora

Powiązane problemy