TimeZoneInfo
does not provide abbreviation or a short name for a given Timezone. The only good way to do it is to have a dictionary that will map abbreviations
I store all my dates in UTC and often have to display them in local time, so I created an extension method ToAbbreviation()
public static string ToAbbreviation(this TimeZone theTimeZone)
{
string timeZoneString = theTimeZone.StandardName;
string result = string.Concat(System.Text.RegularExpressions.Regex
.Matches(timeZoneString, "[A-Z]")
.OfType<System.Text.RegularExpressions.Match>()
.Select(match => match.Value));
return result;
}
example usage:
string tz = TimeZone.CurrentTimeZone.ToAbbreviation();
string formattedDate = String.Format("{0:yyyy/MM/dd hh:mm:ss} {1}", myDate, tz);
Or, if you want to just get a formatted date string from a DateTime object:
public static string ToLocalTimeWithTimeZoneAbbreviation(this DateTime dt)
{
DateTime localtime = dt.ToLocalTime();
string tz = TimeZone.CurrentTimeZone.ToAbbreviation();
string formattedDate = String.Format("{0:yyyy/MM/dd hh:mm:ss} {1}", localtime, tz);
return formattedDate;
}
and use as follows:
string formattedDate = myDateTimeObject.ToLocalTimeWithTimeZoneAbbreviation()
output: 2019-06-24 02:26:31 EST
This is a tricky requirement, the best you can do is get the list of your choice and create a extension / helper method to get the abbreviation for the given TimeZoneInfo.
Once place to start is at http://www.timeanddate.com/library/abbreviations/timezones/ which has a version of list which covers the zones I am aware of.
The issue would be in selecting an appropriate abbreviation where more than one exists for a given timezone. For example UTC can be represented as UTC or WET (Western European Time) or WEZ (Westeuropäische Zeit) or WT (Western Sahara Standard Time).
You may want to agree with your stakeholders on the naming convention you are going to follow with the given choices.
I had a similar issue, but didn't want to use a 3rd party library (as most of these answers suggest). If you only want to support .Net's timezone names, and decide to use a lookup table, take a look at my answer over here, which leans on PHP to help generate a list of abbreviations. You can adapt the snippet there and the table to suit your needs.
This is is helpful for anyone using Xamarin for iOS or Android because according to the documentation "The display name is localized based on the culture installed with the Windows operating system." When using this in the Central Time Zone, for the DateTime "2016-09-01 12:00:00 GMT", this function returns "CDT" which is exactly what I needed when I came upon this question.
public static string GetTimeZoneAbbreviation(DateTime time)
{
string timeZoneAbbr;
if(time.IsDaylightSavingTime() == true)
{
timeZoneAbbr = TimeZoneInfo.Local.DaylightName;
}
else
{
timeZoneAbbr = TimeZoneInfo.Local.StandardName;
}
return timeZoneAbbr;
}
Here's another snippet using 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);
On my system this yields: "4/11/2013 5:03:23 PM CDT (UTC-05:00 America/Chicago)"
(Thanks to Matt Johnson's answer for the clue that the abbreviation lives in TimeZoneInterval)
It would be easier if NodaTime.ZonedDateTime had a GetZoneInterval method, but perhaps I'm missing something.
Your question does not indicate what time zones your application must operate within, but in my particular instance, I only have a need to be concerned with United States time zones and UTC.
The abbreviations of U.S. time zones are always the first characters of each word in the time zone name. For instance, the abbreviation of "Mountain Standard Time" is "MST" and the abbreviation of "Eastern Daylight Time" is "EDT".
If you have similar requirements, you can easily derive the time zone abbreviation of the local time zone from the local time zone's name directly, as follows (note: here I'm determining the proper name based on the current date and time):
string timeZoneName = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now)
? TimeZone.CurrentTimeZone.DaylightName
: TimeZone.CurrentTimeZone.StandardName;
string timeZoneAbbrev = GetTzAbbreviation(timeZoneName);
The code for the GetTzInitials()
function is pretty straightforward. One thing worth mentioning is that some time zones may be set to Mexico or Canada, and the time zone names for these will come over with the country name in parenthesis, such as "Pacific Standard Time (Mexico)". To deal with this, any parenthesized data is passed back directly. The abbreviation returned for the above will be "PST(Mexico)", which works for me.
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;
}