string tzid = theTimeZoneInfo.Id; // example: "Eastern Standard time" string lang = CultureInfo.CurrentCulture.Name; // example: "en-US" var abbreviations = TZNames.GetAbbreviationsForTimeZone(tzid, lang);
The resulting object will have the properties similar to:
abbreviations.Generic == "ET" abbreviations.Standard == "EST" abbreviations.Daylight == "EDT"
You can also use this same library to get the fully localized names of the time zones. The library uses an embedded self-contained copy of the CLDR data.
As others mentioned, Time zones abbreviations are ambiguous. But if you really want one for display, you need an IANA/Olson time zone database.
You can go from a Windows time zone to an IANA/Olson time zone and the other direction as well. But be aware that there could be multiple IANA/Olson zones for any given Windows zone. These mappings are maintained in the CLDR here.
NodaTime has both the database and the mappings. You can go from a .Net
DateTimeOffset with a
TimeZoneInfo, to a NodaTime
DateTimeZone. From there, you can get the abbreviation name.
// 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);