2014-06-24 14 views
5

Ho un sito Web globale che sta passando l'id del fuso orario IANA al server e utilizzo di Noda Time per mappare il fuso orario di Windows nell'app Web C# 5.tempo noda iana mapping di Etc/UTC a fuso orario di Windows

"Etc/UTC" viene passato al server ma Noda Time non può associarlo a un fuso orario di Windows. Come posso mappare un id del fuso orario 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

Guardando https://code.google.com/p/noda-time/source/browse/data/cldr/windowsZones-25.xml, sembra che non ci sia un mapping definito da CLDR di UTC. Potresti aver bisogno di codificare semplicemente questo :( –

+0

Giusto, grazie Sì, è una questione di non essere presente nella mappa :( –

risposta

7

Come Jon ha sottolineato, la mappatura CLDR non è lì per "Etc/UTC". Invece, il CLDR mappa il fuso orario Windows "UTC" a "Etc/GMT". IMHO: questo è un errore.

CLDR richiede "identificatori stabili", quindi non ha aggiornato tradizionalmente i suoi mapping quando cambiano i nomi dei fusi orari. Invece, si seguirebbe normalmente i "link" nel database dei fusi orari per mappare la zona canonica.

Tuttavia, il TZDB non considera "Etc/GMT" un collegamento per "Etc/UTC". Sono due zone distinte. C'è anche "Etc/UCT". In questo modo le applicazioni che si basano sul TZDB per le abbreviazioni dei fusi orari possono utilizzare la loro scelta di abbreviazione (GMT, UTC o UCT). (See discussion here.)

In ogni caso, grazie per averci ricordato di questo problema. Ho aggiornato lo mapping functions per tenerne conto.

+0

Conosci altre mappature del fuso orario che non funzionano? – user3772576

+0

è l'unico di cui sono a conoscenza - almeno, se si usano le funzioni di mappatura a cui ho collegato nella mia altra risposta, tenta di seguire tutti i collegamenti tzdb. La discrepanza è perché CLDR ha un'idea diversa di ciò che è "canonico" di tzdb. Ho aggiunto [alcuni dettagli qui] (https://code.google.com/p/noda-time/issues/detail?id=274) con considerazione per la prossima versione principale di Noda Time. –

+0

Impressionante, Ho una base utenti globale e NodeTime ha risolto molti dei problemi che avevo con gli offset del fuso orario. È una soluzione eccellente grazie – user3772576