Сокращения временной зоны

TimeZoneInfo не предоставляет сокращения или краткое имя для данного часового пояса. Единственный хороший способ сделать это – иметь словарь, который будет отображать сокращения для свойств Timezone.id , StandardName или DaylightName . Тем не менее, все источники, которые я искал в списке сокращений, имеют разные имена часовых поясов, то есть не то же самое, что и в Windows.

Как вы показываете пользователю не полное имя, id или любое другое имя в .NET? Я не хочу, чтобы UtcOffset, но сокращение от Timezone – PST для Pacific, UTC – для Universal, EST – для Восточного стандарта и т. Д. Есть ли список совместимых с C # или firebase database со всеми возможными часовыми поясами и их сокращениями, которые совместимы с тем, что TimeZoneInfo.GetSystemTimeZones() дает вам?

Это сложное требование, лучшее, что вы можете сделать, это получить список по вашему выбору и создать метод расширения / помощника, чтобы получить аббревиатуру для данного TimeZoneInfo.

Когда-то место для начала – http://www.timeanddate.com/library/abbreviations/timezones/, у которого есть версия списка, которая охватывает зоны, о которых я знаю.

Проблема заключалась бы в выборе соответствующей аббревиатуры, где для определенного часового пояса существует более одного. Например, UTC может быть представлен как UTC или WET (Западноевропейское время) или WEZ (Westeuropäische Zeit) или WT (стандартное время Западной Сахары) .

Вы можете согласиться с вашими заинтересованными сторонами в соглашении об именовании, которое вы собираетесь придерживаться с выбранными вариантами.

ОБНОВЛЕННЫЙ ОТВЕТ

Мой первоначальный ответ ниже, и он по-прежнему действителен. Однако теперь есть более простой способ, используя библиотеку TimeZoneNames . После установки из Nuget вы можете сделать следующее:

 string tzid = theTimeZoneInfo.Id; // example: "Eastern Standard time" string lang = CultureInfo.CurrentCulture.Name; // example: "en-US" var abbreviations = TZNames.GetAbbreviationsForTimeZone(tzid, lang); 

Получаемый объект будет иметь свойства, похожие на:

 abbreviations.Generic == "ET" abbreviations.Standard == "EST" abbreviations.Daylight == "EDT" 

Вы также можете использовать эту же библиотеку, чтобы получить полностью локализованные имена часовых поясов. Библиотека использует встроенную автономную копию данных CLDR.

ОРИГИНАЛЬНЫЙ ОТВЕТ

Как отмечали другие, сокращения временных зон являются двусмысленными. Но если вы действительно хотите его отображать, вам нужна firebase database часовых поясов IANA / Olson.

Вы можете перейти из часового пояса Windows в часовой пояс IANA / Olson и в другое направление. Но имейте в виду, что для любой зоны Windows может быть несколько зон IANA / Olson. Эти отображения сохраняются в CLDR.

NodaTime имеет как базу данных, так и сопоставления. Вы можете перейти от .Net DateTime или DateTimeOffset с помощью TimeZoneInfo к NodaTime Instant и DateTimeZone . Оттуда вы можете получить название аббревиатуры.

 // starting with a .Net TimeZoneInfo var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"); // You need to resolve to a specific instant in time - a noda Instant // For illustrative purposes, I'll start from a regular .Net UTC DateTime var dateTime = DateTime.UtcNow; var instant = Instant.FromDateTimeUtc(dateTime); // note that if we really wanted to just get the current instant, // it's better and easier to use the following: // var instant = SystemClock.Instance.Now; // Now let's map the Windows time zone to an IANA/Olson time zone, // using the CLDR mappings embedded in NodaTime. This will use // the *primary* mapping from the CLDR - that is, the ones marked // as "territory 001". // we need the NodaTime tzdb source. In NodaTime 1.1.0+: var tzdbSource = TzdbDateTimeZoneSource.Default; // in previous NodaTime releases: // var tzdbSource = new TzdbDateTimeZoneSource("NodaTime.TimeZones.Tzdb"); // map to the appropriate IANA/Olson tzid var tzid = tzdbSource.MapTimeZoneId(timeZoneInfo); // get a DateTimeZone from that id var dateTimeZone = DateTimeZoneProviders.Tzdb[tzid]; // Finally, let's figure out what the abbreviation is // for the instant and zone we have. // now get a ZoneInterval for the zone and the instant var zoneInterval = dateTimeZone.GetZoneInterval(instant); // finally, you can get the correct time zone abbreviation var abbreviation = zoneInterval.Name; // abbreviation will be either PST or PDT depending // on what instant was provided Debug.WriteLine(abbreviation); 

В вашем вопросе не указано, какие часовые пояса должны применяться в вашей заявке, но в моем конкретном случае мне нужно только учитывать часовые пояса Соединенных Штатов и UTC.

Аббревиатуры часовых поясов США всегда являются первыми символами каждого слова в названии часового пояса. Например, аббревиатура «Горное стандартное время» – это «MST», а аббревиатура «Eastern Daylight Time» – «EDT».

Если у вас есть аналогичные требования, вы можете легко получить сокращенное название часового пояса локального часового пояса из имени локального часового пояса прямо следующим образом (обратите внимание: здесь я определяю собственное имя на основе текущей даты и времени):

 string timeZoneName = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now) ? TimeZone.CurrentTimeZone.DaylightName : TimeZone.CurrentTimeZone.StandardName; string timeZoneAbbrev = GetTzAbbreviation(timeZoneName); 

Код функции GetTzInitials() довольно прост. Стоит упомянуть, что некоторые часовые пояса могут быть установлены в Мексике или Канаде, а названия часовых поясов для них будут иметь название страны в скобках, например «Стандартное тихоокеанское время (Мексика)». Чтобы справиться с этим, любые данные в скобках передаются обратно напрямую. Аббревиатура, возвращенная выше, будет «PST (Мексика)», которая работает для меня.

 string GetTzAbbreviation(string timeZoneName) { string output = string.Empty; string[] timeZoneWords = timeZoneName.Split(' '); foreach (string timeZoneWord in timeZoneWords) { if (timeZoneWord[0] != '(') { output += timeZoneWord[0]; } else { output += timeZoneWord; } } return output; } 

Вот еще один fragment с использованием NodaTime:

 NodaTime.ZonedDateTime hereAndNow = NodaTime.SystemClock.Instance.Now.InZone( NodaTime.DateTimeZoneProviders.Tzdb.GetSystemDefault()); System.TimeSpan zoneOffset = hereAndNow.ToDateTimeOffset().Offset; string sTimeDisplay = string.Format("{0:G} {1} (UTC{2}{3:hh\\:mm} {4})", hereAndNow.ToDateTimeOffset(), hereAndNow.Zone.GetZoneInterval(hereAndNow.ToInstant()).Name, zoneOffset < TimeSpan.Zero ? "-" : "+", zoneOffset, hereAndNow.Zone.Id); 

В моей системе это дает: «4/11/2013 5:03:23 PM CDT (UTC-05: 00 America / Chicago)»

(Спасибо Мэтту Джонсону за то, что аббревиатура живет в TimeZoneInterval)

Было бы проще, если бы у NodaTime.ZonedDateTime был метод GetZoneInterval, но, возможно, я что-то упустил.

У меня была аналогичная проблема, но я не хотел использовать стороннюю библиотеку (как подсказывает большинство из этих ответов). Если вы хотите только поддерживать имена часовых поясов .Net и решить использовать таблицу поиска, взгляните на мой ответ здесь , который опирается на PHP, чтобы помочь сгенерировать список сокращений. Вы можете адаптировать fragment и таблицу в соответствии с вашими потребностями.

Это полезно для тех, кто использует Xamarin для iOS или Android, потому что согласно документации «Отображаемое имя локализовано на основе культуры, установленной в операционной системе Windows». При использовании этого в Центральном часовом поясе для DateTime «2016-09-01 12:00:00 GMT» эта функция возвращает «CDT», что именно то, что мне нужно, когда я столкнулся с этим вопросом.

 public static string GetTimeZoneAbbreviation(DateTime time) { string timeZoneAbbr; if(time.IsDaylightSavingTime() == true) { timeZoneAbbr = TimeZoneInfo.Local.DaylightName; } else { timeZoneAbbr = TimeZoneInfo.Local.StandardName; } return timeZoneAbbr; } 
  • Разница между UTC и стандартным временем GMT в .NET.
  • Получение системных часовых поясов на разных языках
  • Как преобразовать время в часовой пояс устройства iPhone?
  • .NET TimeZoneInfo из часового пояса Олсона
  • Как изменить часовой пояс mysql в java-соединении
  • Как мне заполнить список часовых поясов IANA / Olson от Noda Time?
  • Как обрабатывать календарные часовые пояса с помощью Java?
  • Игнорирование часовых поясов в Rails и PostgreSQL
  • Названия часовых поясов с одинаковыми свойствами дают разные результаты при применении к метке времени
  • Получение даты с на несколько часов
  • Веб-сервис - текущий часовой пояс для города?
  • Давайте будем гением компьютера.