如何显示带有缩写时区的日期时间?

发布于 2024-07-07 01:58:45 字数 1404 浏览 6 评论 0原文

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

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

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

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

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 并用它来正确显示“中部夏令时间”,但是......为了简洁起见,这有点太长了。 那么我是否需要编写一个字符串操作例程来去除空格和任何非大写字母? 虽然这可能有效,但对我来说这似乎令人难以置信......

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

I am aware of the System.TimeZone class 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).

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.

If our web server is running Windows Server 2k3 and has it's time zone set to CST (or, until daylight saving switches 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.

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

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

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...

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

笙痞 2024-07-14 01:58:45

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

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

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;
}
独木成林 2024-07-14 01:58:45

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

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

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.

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.

奢欲 2024-07-14 01:58:45

使用nodatime

以下函数采用 UTC 时间的 DateTime 并使用缩写的本地系统时区对其进行格式化。 在格式字符串中使用 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);
    }

Use nodatime.

The following function takes a DateTime in UTC time and formats it with abbreviated local system timezone. Use x in format string for abbreviated timezone. Look for custom formatting 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);
    }
沒落の蓅哖 2024-07-14 01:58:45

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

请参阅时区缩写

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.

焚却相思 2024-07-14 01:58:45

如果从 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 的数组可能最适合跨国公司。 如果您想在紧迫的期限内节省几分钟,并且您在一家美国公司,那么这种方法很有效。

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.

    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.

骑趴 2024-07-14 01:58:45

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

不管怎样,你可能都需要某种黑客手段。 一种简单的方法是用空格分割字符串,然后连接每个单词的第一个字母。 即

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

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

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.

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.

满意归宿 2024-07-14 01:58:45

好吧,已经过去 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]);
}

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

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

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:

public static String TimeZoneName3(DateTime dt)
{
    return ToCurrentTimeZoneShortString(dt).Split(' ')
                 .Aggregate("", (st,w)=> st +=w[0]);
}
秋心╮凉 2024-07-14 01:58:45

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文