2014-06-24 17 views
5

Mam globalną stronę internetową, która przekazuje identyfikator strefy czasowej IANA na serwer i używa Noda Time do mapowania do strefy czasowej Windows w aplikacji internetowej # 5.noda czas iana mapowanie Etc/UTC na strefę czasową Windows

Urządzenie "Etc/UTC" jest przekazywane do serwera, ale Noda Time nie może zmapować go do strefy czasowej systemu Windows. Jak mogę odwzorować identyfikator strefy czasowej IANA?

public TimeZoneInfo GetTimeZoneByIanaId(string ianaTimeZoneId) 
{ 
    TzdbDateTimeZoneSource timeZoneSource = TzdbDateTimeZoneSource.Default; 
    IList<MapZone> zoneMaps = timeZoneSource.WindowsMapping.MapZones; 

    // resolve any link, since the CLDR doesn't necessarily use canonical IDs 
    IList<string> mapZoneIds = timeZoneSource.CanonicalIdMap.Where(map => map.Value.Equals(ianaTimeZoneId, StringComparison.OrdinalIgnoreCase)).Select(x => x.Key).ToList(); 
    MapZone mapZone = zoneMaps.FirstOrDefault(zoneMap => zoneMap.TzdbIds.Any(mapZoneIds.Contains)); 

    if (mapZone == null) 
    { 
     throw new TimeZoneNotFoundException("Unable to determine the clients timezone using the jsTimezoneDetect plugin"); 
    } 

    TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById(mapZone.WindowsId); 

    if (timeZone == null) 
    { 
     throw new TimeZoneNotFoundException("Unable to determine the clients timezone from NodaTime"); 
    } 

    return timeZone; 
} 
+0

Patrząc na stronę https://code.google.com/p/noda-time/source/browse/data/cldr/windowsZones25.xml, wygląda na to, że nie ma mapowania UTC zdefiniowanego przez CLDR. Być może będziesz musiał po prostu zakodować ten kod :( –

+0

Dobrze, dziękuję, tak, to kwestia wpisu, który nie jest obecny na mapie :( –

Odpowiedz

7

Jak Jon zauważył, odwzorowanie CLDR nie jest tam dla "Etc/UTC". Zamiast tego CLDR odwzorowuje strefę czasową Windows "UTC" na "Etc/GMT". IMHO - jest to błąd.

Klawisz CLDR wymaga "stabilnych identyfikatorów", więc nie ma tradycyjnej aktualizacji mapowań po zmianie nazw stref czasowych. Zamiast tego zwykle podążają za "linki" w bazie danych strefy czasowej, aby mapować do strefy kanonicznej.

Jednak - TZDB nie uważa, że ​​"Etc/GMT" jest linkiem do "Etc/UTC". Są to dwie odrębne strefy. Jest też "Etc/UCT". Jest tak, że aplikacje, które korzystają ze skrótów strefy czasowej TZDB, mogą używać swojego skrótu (GMT, UTC lub UCT). (See discussion here.)

W każdym razie - dzięki za przypomnienie nam o tym problemie. Zaktualizowałem mapping functions, aby wziąć to pod uwagę.

+0

Czy znasz jakieś inne mapowania stref czasowych, które nie działają? – user3772576

+0

To jest jedyną, o której mi wiadomo - przynajmniej, jeśli użyjesz funkcji mapowania, z którymi łączyłem się w mojej drugiej odpowiedzi, spróbuje śledzić wszystkie linki tzdb. Rozbieżność jest taka, że ​​CLDR ma inną koncepcję tego, co jest "kanoniczne" niż tzdb. Dodałem tutaj [trochę szczegółów] (https://code.google.com/p/noda-time/issues/detail?id=274) z uwzględnieniem kolejnej ważnej wersji Noda Time. –

+0

Awesome, Mam globalną bazę użytkowników, a NodeTime rozwiązało wiele problemów, które miałem z przesunięciami czasowymi. Jest to doskonałe rozwiązanie dzięki – user3772576

Powiązane problemy