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

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

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

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

Ответ 1

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

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

Один из способов сделать это на С# - Noda Time:

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

Пропустите двухзначный код страны 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, Noda Time также может отображать их:

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, в zone.tab. Данные сопоставления IANA для Windows поступают из дополнительных данных Unicode CLDR. Он не приближается к "официальному", чем это.

Ответ 2

Возможно, это не то, что вы ищете, но попробуйте следующее: 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);
}

Ответ 3

Чтобы получить сопоставление CountryCode → TimeZoneInfo, я использовал ответ от Matt (2-й фрагмент кода), но он не работал для многих случаев. Найденное более простое и надежное решение (с использованием того же Noda Time): TzdbDateTimeZoneSource.Default.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;
}

Ответ 4

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

Ответ 5

Я использовал часовые пояса по умолчанию для каждой страны, которые Microsoft использует для Windows, когда пользователь впервые входит в систему. Они перечислены по адресу https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-. часовые пояса.

Я также создал скрипт, который разбирает эту таблицу в файл JSON по адресу https://github.com/rahulgi/default-timezones.