如何使用缩短的时区显示date时间?

我知道System.TimeZone类以及DateTime.ToString()方法的许多用途。 我无法find的是一种将DateTime转换为除时间和date信息之外还包含三个字母的时区缩写的string的方法(事实上,StackOverflow的相对工具提示时间显示工作)。

为了使每个人都可以轻松地遵循和使用示例,让我们继续使用StackOverflow示例。 如果您查看在相对时间显示的工具提示,则会显示完整date,包括十二小时格式的秒数,上午/下午指定以及三个字母的时区缩写(在他们的情况下为“协调世界时)。 我意识到我可以很容易地使用内置的方法得到GMT或UTC,但我真正想要的是在本地的时间 – 在这种情况下,在Web服务器上。

如果我们的Web服务器运行的是Windows Server 2k3,并且它的时区设置为CST(或者,直到夏令时切换回来,CDT就是这样吗?),我希望我们的ASP.NET Web应用程序显示相对于该时区的date时间以及最后格式化为显示“CST”。 我意识到我可以很容易地硬编码这一点,但为了健壮的利益,我真的更喜欢基于服务器运行代码的操作系统环境设置的解决scheme。

现在,除了使用下面的代码的时区缩写,我什么都没有。

myDateTime.ToString("MM/dd/yyyy hh:mm:ss tt") 

其中显示:

10/07/2008 03:40:31 PM

我只想要(这不是很多,承诺!)是这样说的:

10/07/2008 03:40:31 PM CDT

我可以使用System.TimeZone.CurrentTimeZone并使用它来正确显示“中央夏令时”,但是…为了简洁起见,这太长了。 然后,我坚持写一个string操作程序去除空白和任何非大写字母? 虽然这可能工作,这似乎令人难以置信的黑客我…

在这里使用谷歌search并没有产生任何适用于我的具体问题的东西。

这是我刚刚为解决此问题而采取的快速入侵方法。

 public static String TimeZoneName(DateTime dt) { String sName = TimeZone.CurrentTimeZone.IsDaylightSavingTime(dt) ? TimeZone.CurrentTimeZone.DaylightName : TimeZone.CurrentTimeZone.StandardName; String sNewName = ""; String[] sSplit = sName.Split(new char[]{' '}); foreach (String s in sSplit) if (s.Length >= 1) sNewName += s.Substring(0, 1); return sNewName; } 

有一个免费的图书馆, TZ4NET ,有这些缩写可用。 在.NET 3.5之前,这是在时区之间转换的唯一select之一。

如果你不想要一个独立的库,你可以使用TimeZoneInfo类生成一个合理缩写的地图,然后提供给你的用户。

我会创build一个查询表,将时区名称转换为其缩写。 如果找不到匹配,则可以返回完整的区域名称。

请参阅时区缩写 。

使用nodatime 。

以下函数采用UTC时间的DateTime ,并使用缩短的本地系统时区进行格式化。 在格式string中使用x来缩短时区。 在这里寻找自定义的格式。

  public static string ConvertToFormattedLocalTimeWithTimezone(DateTime dateTimeUtc) { var tz = DateTimeZoneProviders.Tzdb.GetSystemDefault(); // Get the system's time zone var zdt = new ZonedDateTime(Instant.FromDateTimeUtc(dateTimeUtc), tz); return zdt.ToString("MM'/'dd'/'yyyy' 'hh':'mm':'ss' 'tt' 'x", CultureInfo.InvariantCulture); } 

这取决于你所需要的健壮程度。

你可能需要某种黑客方式。 一个简单的方法是将string拆分为空格,然后连接每个单词的第一个字母。 即

 string[] words = tzname.Split(" ".ToCharArray()); string tzabbr = ""; foreach (string word in words) tzabbr += word[0]; 

这对于地球上的每个时区都是行不通的,但是这对大多数时间都是有效的。 如果您需要更强大的function,那么您可能需要创build一个将时区名称映射到缩写的映射。

如果从DaylightName / StandardName拉出缩写,那么使用StringBuilder构buildstring会更好,因为string是不可变的。

  public static string ToCurrentTimeZoneString(this DateTime date) { string name = TimeZone.CurrentTimeZone.IsDaylightSavingTime(date) ? TimeZone.CurrentTimeZone.DaylightName : TimeZone.CurrentTimeZone.StandardName; return name; } public static string ToCurrentTimeZoneShortString(this DateTime date) { StringBuilder result = new StringBuilder(); foreach (string value in date.ToCurrentTimeZoneString().Split(' ')) { if (value.IsNotNullOrEmptyWithTrim()) { result.Append(char.ToUpper(value[0])); } } return result.ToString(); } 

当然,包含KeyValuePair的数组对于跨国公司来说可能是最好的。 如果你想在一个紧急的截止date前几分钟,而你在一家美国公司,这是有效的。

好的,这已经4年了(差不多一周了),是时候把LINQ带进讨论区了。

汇集Criag和Bob的想法…

 public static String TimeZoneName2(DateTime dt) { var return ToCurrentTimeZoneShortString(dt) .Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries); return sSplit.Aggregate("", (st,w)=> st +=w[0]); } 

除非你可以信任TimeZone永远不会返回一个连续两个空格的string:

 public static String TimeZoneName3(DateTime dt) { return ToCurrentTimeZoneShortString(dt).Split(' ') .Aggregate("", (st,w)=> st +=w[0]); } 

如果您使用的是<= .Net 3.0,那么请下载TZ4Net,并使用OlsonTimeZone.CurrentTimeZone.Standard作为> .Net 3.0的缩写,使用NodaTime或其他。 时区名称不符合任何约定,您可以依靠简单的string操作来从首字母缩略词构造缩写。 错误的5%的时间仍然是错误的。