.net 如何使用缩写的时区显示日期时间?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/180370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 10:16:04  来源:igfitidea点击:

How to display DateTime with an abbreviated Time Zone?

.netdatetimeformattingtimezonetostring

提问by Sean Hanley

I am aware of the System.TimeZoneclass as well as the many uses of the DateTime.ToString()method. What I haven'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's tooltips for relative time display works).

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

To make an example easy for everyone to follow as well as consume, let's continue with the StackOverflow example. If you look at the tooltip that displays on relative times, it displays with the full date, the time including seconds in twelve-hour format, an AM/PM designation, and then the three-letter Time Zone abbreviation (in their case, Coordinated Universal Time). I realize I could easily get GMT or UTC by using the built-in methods, but what I really want is the time as it is locally — in this case, on a web server.

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

If our web server is running Windows Server 2k3 and has it's time zone set to CST (or, until daylight savingswitches back, CDT is it?), I'd like our ASP.NET web app to display DateTimes relative to that time zone as well as formatted to display a "CST" on the end. I realize I could easily hard-code this, but in the interest of robustness, I'd really prefer a solution based on the server running the code's OS environment settings.

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

Right now, I have everything but the time zone abbreviation using the following code:

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

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

Which displays:

其中显示:

10/07/2008 03:40:31 PM

10/07/2008 下午 03:40:31

All I want (and it's not much, promise!) is for it to say:

我想要的(而且不多,保证!)就是让它说:

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

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

I can use System.TimeZone.CurrentTimeZone and use it to correctly display "Central Daylight Time" but... that's a bit too long for brevity's sake. Am I then stuck writing a string manipulation routine to strip out white-space and any non-uppercase letters? While that might work, that seems incredibly hack to me...

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

Googlingand looking around on here did not produce anything applicable to my specific question.

谷歌搜索并在这里环顾四周并没有产生任何适用于我的具体问题的信息。

回答by craigmoliver

Here's my quick hack method I just made to work around this.

这是我刚刚用来解决这个问题的快速黑客方法。

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

回答by Dave Moore

There is a freely available library, TZ4NET, which has these abbreviations available. Prior to .NET 3.5, this was one of the only alternatives for converting between timezones as well.

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

If you don't want a seperate library, you could certainly generate a map of reasonable abbreviations using the TimeZoneInfo classes, and then just supply those to your user.

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

回答by kaptan

Use nodatime.

使用nodatime

The following function takes a DateTimein UTC time and formats it with abbreviated local system timezone. Use xin format string for abbreviated timezone. Look for custom formatting here.

以下函数采用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);
    }

回答by Pavel Chuchuva

I would create a lookup table that converts time zone name to its abbreviation. If the match is not found you could return full zone name.

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

See time zone abbreviations.

请参阅时区缩写

回答by Bob Houghton

If pulling the abbreviation from the DaylightName/StandardName, you're going to be better off building the string using a StringBuilder, for strings are immutable.

如果从 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();
    }

Of course, an array containing KeyValuePair's is probably best for a multinational company. If you want to shave a few minutes off of a tight deadline, and you are at a US company, this works.

当然,包含 KeyValuePair 的数组可能最适合跨国公司。如果您想在紧迫的期限内缩短几分钟时间,并且您在一家美国公司工作,那么这很有效。

回答by Gerald

It depends on the level of robustness that you need.

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

You'll probably need some kind of hack either way. An easy way would be to split the string by spaces and then concatenate the first letter of each word. i.e.

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

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

That won't work for every time zone on the planet, but it will work for most of them. If you need it more robust then you'll probably need to create a map that maps time zone names to their abbreviations.

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

回答by James Curran

Ok, It's been 4 years (and almost a week), it's time we brought LINQ into the discussion...

好的,已经 4 年了(差不多一个星期了),是时候让我们将 LINQ 带入讨论中了……

Putting together Criag's and Bob's ideas...

将 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]);
}

Unless you can trust TimeZone to never return a string with two consecutive spaces:

除非您可以相信 TimeZone 永远不会返回带有两个连续空格的字符串:

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

回答by ComeIn

If you are using <= .Net 3.0 then download TZ4Net and use OlsonTimeZone.CurrentTimeZone.StandardAbbreviation for > .Net 3.0 use NodaTime or other. The timezones names do not conform to any convention where you can rely on simple string manipulation to construct the abbreviation from an acronym. Wrong 5% of the time is still wrong.

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