Если у меня есть время UT C, как мне получить C# соответствующее местное время в Польше? Или во Франции? Или в Эквадоре?
Вкл. Windows:
var poland = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTimeOffset.UtcNow, "Central European Standard Time");
var france = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTimeOffset.UtcNow, "Romance Standard Time");
var ecuador1 = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTimeOffset.UtcNow, "SA Pacific Standard Time"); // (Mainland)
var ecuador2 = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTimeOffset.UtcNow, "Central America Standard Time"); // (Galapagos Is.)
Вкл. Linux, OSX и др. NET Основные платформы:
var poland = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTimeOffset.UtcNow, "Europe/Warsaw");
var france = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTimeOffset.UtcNow, "Europe/Paris");
var ecuador1 = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTimeOffset.UtcNow, "America/Guayaquil"); // (Mainland)
var ecuador2 = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTimeOffset.UtcNow, "Pacific/Galapagos"); // (Galapagos Is.)
(Обратите внимание, что Эквадор имеет два часовых пояса , один для материка, один для Галапагосских островов.)
Хорошим ориентиром для определения того, какой Windows ID использовать, является CLDR windowsZones.xml
file , который является источником истины для преобразования между Windows и идентификаторами часовых поясов IANA.
(я понимаю, что это не имеет смысла для большого такие страны, как Россия, где используется много раз)
Действительно, в России много различных идентификаторов часовых поясов. Нужно знать, в какой части России они были заинтересованы.
В большинстве существующих примеров люди используют объект TimeZoneInfo
:
var zone = TimeZoneInfo.FindSystemTimeZoneById("SE Asia Standard Time");
Проблема в том, что это недостаточно. Во многих странах есть что-то вроде «летнего времени» или « летнего времени », где они используют различное смещение времени по отношению к UT C в зависимости от дня года и даже точного часа (в день изменение времени).
Например, вместо того, чтобы знать, нужен ли мне параметр Central Daylight
Time
или Central Standard Time
, я хочу иметь возможность выбрать America/Chicago
и позволить ему справиться с этим для меня.
Нет, это не проблема. Вероятно, вы запутались в требовании, потому что слово «Стандарт» находится в имени идентификатора. Несмотря на это, объект TimeZoneInfo
представляет весь часовой пояс, включая как стандартное время, так и летнее / летнее время.
Для пояснения, метод TimeZoneInfo.FindSystemTimeZoneById
принимает идентификатор . Свойство Id
результирующего объекта будет затем содержать этот идентификатор.
"America/Chicago"
- это идентификатор часового пояса IANA. "Central Standard Time"
является и идентификатором часового пояса Windows, и локализованным Engli sh "стандартным именем" той же зоны (на Windows). "Central Daylight Time"
является Engli sh локализованным «именем дневного света» этой зоны (на Windows). Это недопустимый идентификатор часового пояса.
Существуют ли какие-либо встроенные функции C#, которые занимаются этим, или мне нужно обрабатывать все вычисления, где начинается летнее время, и заканчивается в соответствии с законом выбранной страны сам?
Все встроенные вычисления обрабатывают это. Только передайте действительные идентификаторы, и структура будет определять правильное смещение от UT C независимо от того, действует ли стандартное время или летнее / летнее время.
Вот рабочий пример , который демонстрирует эти концепции:
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"); // Use "America/Chicago" on non-Windows systems
Console.WriteLine("Id: " + tzi.Id);
Console.WriteLine("DisplayName: " + tzi.DisplayName);
Console.WriteLine("StandardName: " + tzi.StandardName);
Console.WriteLine("DaylightName: " + tzi.DaylightName);
Console.WriteLine();
DateTime winterDate = new DateTime(2020, 1, 1);
DateTime summerDate = new DateTime(2020, 7, 1);
TimeSpan winterOffset = tzi.GetUtcOffset(winterDate);
TimeSpan summerOffset = tzi.GetUtcOffset(summerDate);
bool winterIsDst = tzi.IsDaylightSavingTime(winterDate);
bool summerIsDst = tzi.IsDaylightSavingTime(summerDate);
Console.WriteLine("Winter Offset: " + winterOffset + " IsDST: " + winterIsDst);
Console.WriteLine("Summer Offset: " + summerOffset + " IsDST: " + summerIsDst);
Вывод:
Id: Central Standard Time
DisplayName: (UTC-06:00) Central Time (US & Canada)
StandardName: Central Standard Time
DaylightName: Central Daylight Time
Winter Offset: -06:00:00 IsDST: False
Summer Offset: -05:00:00 IsDST: True
Наконец, если вы хотите использовать любой набор идентификаторов в любой операционной системе, есть два различных способа, которыми вы можете обработать это:
Вы можете получить TimeZoneInfo
с моей библиотекой TimeZoneConverter . Например:
// Either of these will work on any platform:
TimeZoneInfo tzi = TZConvert.GetTimeZoneInfo("America/Chicago");
TimeZoneInfo tzi = TZConvert.GetTimeZoneInfo("Central Standard Time");
Вы можете использовать Время Noda вместо TimeZoneInfo
, которое имеет ZonedDateTimeProviders
для Bcl (Windows) и Tzdb (IANA) идентификаторы.
// This will work on any platform:
DateTimeZone dtz = DateTimeZoneProviders.Tzdb["America/Chicago"];
// This will work with Windows on .NET Framework only
DateTimeZone dtz = DateTimeZoneProviders.Bcl["Central Standard Time"];
Вы также можете прочитать тег часового пояса вики здесь, в Переполнение стека. Особенно в разделе «Базы данных часовых поясов».