Получить часовой пояс по умолчанию для страны (через CultureInfo)

есть ли программа или таблица, содержащая по умолчанию в каждой стране?

да, США, Канада и Россия имеют несколько часовых поясов. (Я думаю, что в любой другой стране есть только одна.) Но лучше начать с наиболее вероятного, если страна известна, а не просто предоставить список, начинающийся с GMT.

предпочтительно в C#, но я возьму его в чем угодно и конвертирую в C#.

4 ответов


как указано в комментариях к вопросу, вы не сможете получить один часовой пояс для каждой страны. Есть слишком много случаев стран, которые имеют несколько часовых поясов.

что ты can do-это фильтр списка стандартных часовые пояса IANA/Olson вплоть до тех, которые доступны в конкретной стране.

один из способов сделать это в C# с Нода Времени:

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

Pass a двухзначный код страны ISO-3166, например "AU" для Австралии. Результаты:

"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"

и если по какой-то причине вам нужны идентификаторы часовых поясов Windows, которые вы можете использовать с TimeZoneInfo объект, Нода время может сопоставить те тоже:

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()

снова позвонил с "AU" для Австралии возвращает:

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

Если вам интересно, насколько надежны эти данные, отображение страны в tzid является частью самой базы данных часового пояса IANA, в зоны.tab. Данные сопоставления IANA с Windows поступают из Unicode CLDR дополнительные данные. Ближе к "официальному" он не подходит.


может быть не совсем то, что вы ищете, но попробуйте следующее:http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx

чтобы получить определенный часовой пояс:

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

чтобы увидеть доступные зоны:

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

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

чтобы получить отображение CountryCode - > TimeZoneInfo, я использовал ответ от Matt (2-й фрагмент кода), но он не работал во многих случаях. Найдено более простое и надежное решение (с использованием того же времени Noda): TzdbDateTimeZoneSource.По умолчанию.WindowsMapping.MapZones в основном имеет все данные.

код:

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;
}

последние версии Windows содержат файл %WINDIR%\Globalization\Time Zone\timezoneMapping.xml который сопоставляет Olson с часовым поясом Windows, вы можете запросить его как обычный XML. Я не знаю, но может быть C# уже есть класс, который работает с ним.