Existe-t-il un programme ou une table fournissant le fuseau horaire par défaut pour chaque pays?
Oui, les États-Unis, le Canada et la Russie ont plusieurs fuseaux horaires. (Je pense que tous les pays n'en ont qu'un.) Mais il est préférable de commencer par le plus probable si un pays est connu plutôt que de simplement fournir une liste commençant par GMT.
De préférence en C # mais je vais le prendre dans n'importe quoi et convertir en C #.
Comme indiqué dans les commentaires de la question, vous ne pourrez pas obtenir un seul fuseau horaire pour chaque pays. Il y a juste trop de cas de pays qui ont plusieurs fuseaux horaires.
Ce que vous pouvez faites filtrer la liste des _ { fuseaux horaires IANA/Olson } standard jusqu’à ceux disponibles dans un pays spécifique.
Une façon de faire cela en C # est avec Noda Time :
IEnumerable<string> zoneIds = TzdbDateTimeZoneSource.Default.ZoneLocations
.Where(x => x.CountryCode == countryCode)
.Select(x => x.ZoneId);
Transmettez un code de pays ISO-3166 à deux chiffres, tel que "AU"
pour l'Australie. Les résultats sont:
"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"
Et si, pour une raison quelconque, vous souhaitez utiliser les identifiants de fuseau horaire Windows que vous pouvez utiliser avec l'objet TimeZoneInfo
, Noda Time peut également les mapper:
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()
De nouveau, appelé avec "AU"
pour les déclarations australiennes:
"Tasmania Standard Time",
"AUS Eastern Standard Time",
"Cen. Australia Standard Time",
"E. Australia Standard Time",
"AUS Central Standard Time",
"W. Australia Standard Time"
Si vous vous demandez quelle est la fiabilité de ces données, le mappage de pays à tzid fait partie de la base de données de fuseaux horaires IANA, dans le fichier zone.tab . Les données de mappage IANA vers Windows proviennent des données supplémentaires Unicode CLDR . Ça ne s'apparente pas plus à "officiel" que ça.
Ce n'est peut-être pas exactement ce que vous recherchez, mais essayez ceci: http://msdn.Microsoft.com/en-us/library/system.timezoneinfo.aspx
Pour obtenir un fuseau horaire spécifique:
TimeZoneInfo tZone = TimeZoneInfo.FindSystemTimeZoneById("E. Australia Standard Time");
Pour voir les zones disponibles:
ReadOnlyCollection<TimeZoneInfo> zones = TimeZoneInfo.GetSystemTimeZones();
foreach (TimeZoneInfo zone in zones)
{
Console.WriteLine(zone.Id);
}
Pour obtenir le mappage CountryCode -> TimeZoneInfo, j’ai utilisé la réponse de Matt (deuxième extrait de code), mais cela n’a pas fonctionné dans de nombreux cas. Une solution plus simple et plus fiable (utilisant la même heure Noda) a été trouvée: TzdbDateTimeZoneSource.Default.WindowsMapping.MapZones dispose de toutes les données.
Exemple de code:
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;
}
Les dernières versions de Windows contiennent le fichier %WINDIR%\Globalization\Time Zone\timezoneMapping.xml
qui mappe Olson sur le fuseau horaire Windows. Vous pouvez l'interroger comme suit: XML
. Je ne sais pas, mais peut-être que C#
a déjà une classe qui fonctionne avec elle.