40

我知道System.TimeZone类以及DateTime.ToString()方法的许多用途。我找不到的是一种将 DateTime 转换为字符串的方法,该字符串除了时间和日期信息之外,还包含三个字母的时区缩写(实际上,与 StackOverflow 的相对工具提示大致相同)时间显示工作)。

为了让每个人都能轻松理解和使用示例,让我们继续 StackOverflow 示例。如果您查看显示相对时间的工具提示,它会显示完整日期、时间(包括 12 小时格式的秒数)、AM/PM 名称,然后是三个字母的时区缩写(在他们的情况下,协调世界时)。我意识到我可以通过使用内置方法轻松获取 GMT 或 UTC,但我真正想要的是本地时间——在本例中,是在 Web 服务器上。

如果我们的 Web 服务器正在运行 Windows Server 2k3 并且它的时区设置为 CST(或者,直到夏令时切换回来,CDT 是吗?),我希望我们的 ASP.NET Web 应用程序显示相对于该时区的 DateTimes以及格式化以在末尾显示“CST”。我意识到我可以很容易地对此进行硬编码,但出于稳健性的考虑,我真的更喜欢基于运行代码的操作系统环境设置的服务器的解决方案。

现在,除了时区缩写外,我使用以下代码拥有所有内容:

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

其中显示:

2008 年 10 月 7 日下午 3:40:31

我想要的(这并不多,承诺!)就是让它说:

2008 年 10 月 7 日下午 03:40:31 CDT

我可以使用 System.TimeZone.CurrentTimeZone 并使用它来正确显示“Central Daylight Time”但是......为了简洁起见,这有点太长了。然后我是否坚持编写字符串操作例程来去除空格和任何非大写字母?虽然这可能有效,但对我来说这似乎令人难以置信......

谷歌搜索和查看这里并没有产生任何适用于我的具体问题的东西。

4

8 回答 8

19

这是我刚刚解决此问题的快速破解方法。

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;
}
于 2009-04-27T19:32:56.317 回答
5

有一个免费可用的库TZ4NET,其中提供了这些缩写。在 .NET 3.5 之前,这也是在时区之间转换的唯一选择之一。

如果您不想要一个单独的库,您当然可以使用 TimeZoneInfo 类生成合理缩写的映射,然后将它们提供给您的用户。

于 2008-10-08T03:42:00.280 回答
4

使用节点时间

以下函数采用DateTimeUTC 时间并使用缩写的本地系统时区对其进行格式化。在格式字符串中使用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);
    }
于 2014-12-12T20:16:46.680 回答
1

我将创建一个将时区名称转换为其缩写的查找表。如果未找到匹配项,您可以返回完整的区域名称。

请参阅时区缩写

于 2008-10-08T02:20:07.433 回答
1

如果从 DaylightName/StandardName 中提取缩写,则最好使用 StringBuilder 构建字符串,因为字符串是不可变的。

    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 的数组可能最适合跨国公司。如果您想在紧迫的最后期限中缩短几分钟,并且您在一家美国公司,这很有效。

于 2011-09-29T17:14:15.383 回答
0

这取决于您需要的稳健性级别。

无论哪种方式,您都可能需要某种技巧。一个简单的方法是用空格分割字符串,然后连接每个单词的第一个字母。IE

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

这并不适用于地球上的每个时区,但它适用于大多数时区。如果您需要它更健壮,那么您可能需要创建一个将时区名称映射到其缩写的映射。

于 2008-10-07T21:40:34.940 回答
-1

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

于 2014-10-27T03:06:33.000 回答
-1

好的,已经 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 永远不会返回包含两个连续空格的字符串:

public static String TimeZoneName3(DateTime dt)
{
    return ToCurrentTimeZoneShortString(dt).Split(' ')
                 .Aggregate("", (st,w)=> st +=w[0]);
}
于 2012-10-12T14:03:22.247 回答