首页 文章

如何使用缩写的时区显示DateTime?

提问于
浏览
36

我知道System.TimeZone类以及DateTime.ToString()方法的许多用法 . 我没有't been able to find is a way to convert a DateTime to a string that, in addition to the time and date info, contains the three-letter Time Zone abbreviation (in fact, much the same way StackOverflow'用于相对时间显示的工具提示工作) .

为了让每个人都能轻松地关注和消费,让我们继续使用StackOverflow示例 . 如果查看相对时间显示的工具提示,它将显示完整日期,时间包括12小时格式的秒数,AM / PM指定,然后是三字母时区缩写(在他们的情况下为Coordinated)世界时间) . 我意识到我可以通过使用内置方法轻松获得GMT或UTC,但我真正想要的是它本地的时间 - 在这种情况下,在Web服务器上 .

如果我们的Web服务器正在运行Windows Server 2k3并且它的时区设置为CST(或者,直到daylight saving切换回来,CDT就是它?),我真的更喜欢基于运行代码的OS环境设置的服务器的解决方案 .

现在,除了时区缩写,我使用以下代码:

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并使用它来正确显示“Central Daylight Time”但是......为了简洁起见,这有点太长了 . 我是不是写了一个字符串操作例程来去掉白色空格和任何非大写字母?虽然这可能有用,但这对我来说似乎非常糟糕......

Googling并且在这里四处看看并没有产生任何适用于我的具体问题 .

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;
    }
    
  • 0

    有一个免费提供的库TZ4NET,它有这些缩写 . 在.NET 3.5之前,这是在时区之间进行转换的唯一替代方案之一 .

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

  • 2

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

    time zone abbreviations .

  • 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的数组可能最适合跨国公司 . 如果你想在紧迫的期限内刮几分钟,并且你在美国公司工作,那就行了 .

  • 2

    使用nodatime .

    以下函数在UTC时间内采用 DateTime 并使用缩写的本地系统时区对其进行格式化 . 在缩写时区的格式字符串中使用 x . 寻找自定义格式here .

    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);
        }
    
  • 6

    这取决于您需要的健壮程度 .

    无论哪种方式,你可能都需要某种黑客攻击 . 一种简单的方法是用空格分割字符串,然后连接每个单词的第一个字母 . 即

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

    这对地球上的每个时区都不起作用,但对大多数时区都适用 . 如果您需要它更强大,那么您可能需要创建一个将时区名称映射到其缩写的 Map .

  • 0

    好的,已经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]);
    }
    
  • 2

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

相关问题