更新的答案
我的原始回复如下,并且仍然有效。但是,现在有一种更简单的方法,即使用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 数据的嵌入式独立副本。
原始答案
正如其他人所提到的,时区缩写是模棱两可的。但如果你真的想要一个用于显示,你需要一个 IANA/Olson 时区数据库。
您可以从 Windows 时区转到 IANA/Olson 时区以及其他方向。但请注意,任何给定的 Windows 区域都可能有多个 IANA/Olson 区域。这些映射在此处的 CLDR 中维护。
NodaTime同时拥有数据库和映射。您可以从 .NetDateTime
或DateTimeOffset
,TimeZoneInfo
转到 NodaTimeInstant
和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);