2013-10-30 2 views
11

Gibt es ein Programm oder eine Tabelle, die die Standardzeitzone für jedes Land bereitstellt?Erhalten Sie die Standardzeitzone für ein Land (über CultureInfo)

Ja, die USA, Kanada, & Russland haben mehrere Zeitzonen. (Ich denke, jedes andere Land hat nur eins.) Aber es ist besser, am wahrscheinlichsten zu beginnen, wenn ein Land bekannt ist, anstatt nur eine Liste bei GMT zu erstellen.

Vorzugsweise in C#, aber ich werde es in alles übernehmen und in C# konvertieren.

+2

China. Indien. Ich rannte. Brasilien .... –

+0

Was ist eine "Standardzeitzone" ??? Die Zone in der Hauptstadt eines Landes? – elgonzo

+1

Und Australien mit mindestens drei Zeitzonen, und einige Staaten, aber nicht alle, haben Sommerzeit und Indiana in den USA, die mindestens zwei Zeitzonen verwendet. –

Antwort

17

Wie in den Kommentaren der Frage angegeben, können Sie nicht für jedes Land eine einzige Zeitzone festlegen. Es gibt einfach zu viele Fälle von Ländern, die mehrere Zeitzonen haben.

Was Sie können tun ist, um die Liste der Standard IANA/Olson time zones filtern nach unten für diejenigen innerhalb eines bestimmten Landes.

Eine Möglichkeit, dies in C# zu tun ist, mit Noda Time:

IEnumerable<string> zoneIds = TzdbDateTimeZoneSource.Default.ZoneLocations 
    .Where(x => x.CountryCode == countryCode) 
    .Select(x => x.ZoneId); 

Pass einen zweistelligen ISO-3166-Ländercode, wie "AU" für Australien. Die Ergebnisse sind:

"Australia/Lord_Howe", 
"Australia/Hobart", 
"Australia/Currie", 
"Australia/Melbourne", 
"Australia/Sydney", 
"Australia/Broken_Hill", 
"Australia/Brisbane", 
"Australia/Lindeman", 
"Australia/Adelaide", 
"Australia/Darwin", 
"Australia/Perth", 
"Australia/Eucla" 

Und wenn Sie aus irgendeinem Grund Windows-Zeitzone Identifikatoren möchten, dass Sie mit dem TimeZoneInfo Objekt verwenden können, Noda Zeit diejenigen zuordnen können:

var source = TzdbDateTimeZoneSource.Default; 
IEnumerable<string> windowsZoneIds = source.ZoneLocations 
    .Where(x => x.CountryCode == countryCode) 
    .Select(tz => source.WindowsMapping.MapZones 
     .FirstOrDefault(x => x.TzdbIds.Contains(
          source.CanonicalIdMap.First(y => y.Value == tz.ZoneId).Key))) 
    .Where(x => x != null) 
    .Select(x => x.WindowsId) 
    .Distinct() 

Auch hier genannt mit "AU" für Australien zurück:

"Tasmania Standard Time", 
"AUS Eastern Standard Time", 
"Cen. Australia Standard Time", 
"E. Australia Standard Time", 
"AUS Central Standard Time", 
"W. Australia Standard Time" 

Wenn Sie sich fragen, wie zuverlässig diese Daten vorhanden sind, ist das Land Mapping TZID Datenteil der IANA-Zeitzone Basis selbst, in der zone.tab Datei. Die IANA-Windows-Mapping-Daten stammen von Unicode CLDR supplemental data. Es kommt dem "Offiziellen" nicht näher.

+0

Können Sie das gleiche für 'FO' Ländercode versuchen? ('Faroi Islands') Ich kann den Code in der Datei (' zone.tab') finden, aber in 'C#' bekomme ich keine Ergebnisse für diesen Code. – Alex

+0

Probiere den Schnitt, den ich gerade gemacht habe. Ich habe nicht berücksichtigt, dass die IDs im Windows-Mapping nicht immer die kanonischen TZDB-IDs sind. –

2

Kann nicht genau das, was Sie suchen, aber versuchen Sie dies: http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx

Um eine bestimmte Zeitzone zu erhalten:

TimeZoneInfo tZone = TimeZoneInfo.FindSystemTimeZoneById("E. Australia Standard Time"); 

Um die verfügbaren Zonen zu sehen:

ReadOnlyCollection<TimeZoneInfo> zones = TimeZoneInfo.GetSystemTimeZones(); 

foreach (TimeZoneInfo zone in zones) 
{ 
    Console.WriteLine(zone.Id); 
} 
1

Um CountryCode -> TimeZoneInfo Mapping zu bekommen, habe ich Antwort von Matt (2. Codeausschnitt) verwendet, aber es hat in vielen Fällen nicht funktioniert. Finden Sie eine einfachere und zuverlässigere Lösung (mit der gleichen Noda Time): TzdbDateTimeZoneSource.Default.WindowsMapping.MapZones hat grundsätzlich alle Daten.

Codebeispiel:

Dictionary<string, TimeZoneInfo> GetIsoToTimeZoneMapping() 
{ 
    var source = TzdbDateTimeZoneSource.Default; 

    return source.WindowsMapping.MapZones 
     .GroupBy(z => z.Territory) 
     .ToDictionary(grp => grp.Key, grp => GetTimeZone(source, grp)); 
} 

TimeZoneInfo GetTimeZone(TzdbDateTimeZoneSource source, IEnumerable<MapZone> territoryLocations) 
{ 
    var result = territoryLocations 
     .Select(l => l.WindowsId) 
     .Select(TimeZoneInfo.FindSystemTimeZoneById) 
     //pick timezone with the minimum offset 
     .Aggregate((tz1, tz2) => tz1.BaseUtcOffset < tz2.BaseUtcOffset ? tz1 : tz2); 

    return result; 
} 
Verwandte Themen