.net 仅使用日期时间格式以小写形式获取日期时间的 AM/PM

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/499393/
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 11:08:15  来源:igfitidea点击:

Get AM/PM for a date time in lowercase using only a datetime format

.netdatetimestring-formatting

提问by Daniel Schaffer

I'm to get a custom DateTime format including the AM/PM designator, but I want the "AM" or "PM" to be lowercase withoutmaking the rest of of the characters lowercase.

我要获得一个包含 AM/PM 指示符的自定义 DateTime 格式,但我希望“AM”或“PM”是小写的,而不是将其余字符设为小写。

Is this possible using a single format and without using a regex?

这是否可以使用单一格式而不使用正则表达式?

Here's what I've got right now:

这是我现在所拥有的:

item.PostedOn.ToString("dddd, MMMM d, yyyy a\t h:mmtt")

An example of the output right now would be Saturday, January 31, 2009 at 1:34PM

现在的输出示例是2009 年 1 月 31 日星期六下午 1:34

回答by Jon Skeet

I would personally format it in two parts: the non-am/pm part, and the am/pm part with ToLower:

我个人会将其格式化为两部分:非上午/下午部分,以及使用 ToLower 的上午/下午部分:

string formatted = item.PostedOn.ToString("dddd, MMMM d, yyyy a\t h:mm") +
                   item.PostedOn.ToString("tt").ToLower();

Another option (which I'll investigate in a sec) is to grab the current DateTimeFormatInfo, create a copy, and set the am/pm designators to the lower case version. Then use that format info for the normal formatting. You'd want to cache the DateTimeFormatInfo, obviously...

另一种选择(我将在稍后研究)是获取当前的 DateTimeFormatInfo,创建一个副本,并将 am/pm 指示符设置为小写版本。然后使用该格式信息进行正常格式设置。你想要缓存 DateTimeFormatInfo,显然......

EDIT: Despite my comment, I've written the caching bit anyway. It probably won't be fasterthan the code above (as it involves a lock and a dictionary lookup) but it does make the calling code simpler:

编辑:尽管有我的评论,我还是写了缓存位。它可能不会比上面的代码(因为它涉及锁和字典查找),但它确实使调用代码更简单:

string formatted = item.PostedOn.ToString("dddd, MMMM d, yyyy a\t h:mmtt",
                                          GetLowerCaseInfo());

Here's a complete program to demonstrate:

这是一个完整的程序来演示:

using System;
using System.Collections.Generic;
using System.Globalization;

public class Test
{
    static void Main()
    {
        Console.WriteLine(DateTime.Now.ToString("dddd, MMMM d, yyyy a\t h:mmtt",
                                                GetLowerCaseInfo());
    }

    private static readonly Dictionary<DateTimeFormatInfo,DateTimeFormatInfo> cache =
        new Dictionary<DateTimeFormatInfo,DateTimeFormatInfo>();

    private static object cacheLock = new object();

    public static DateTimeFormatInfo GetLowerCaseInfo()
    {
        DateTimeFormatInfo current = CultureInfo.CurrentCulture.DateTimeFormat;
        lock (cacheLock)
        {
            DateTimeFormatInfo ret;
            if (!cache.TryGetValue(current, out ret))
            {
                ret = (DateTimeFormatInfo) current.Clone();
                ret.AMDesignator = ret.AMDesignator.ToLower();
                ret.PMDesignator = ret.PMDesignator.ToLower();
                cache[current] = ret;
            }
            return ret;
        }
    }
}

回答by casperOne

You could split the format string into two parts, and then lowercase the AM/PM part, like so:

您可以将格式字符串拆分为两部分,然后将 AM/PM 部分小写,如下所示:

DateTime now = DateTime.Now;
string nowString = now.ToString("dddd, MMMM d, yyyy a\t h:mm");
nowString = nowString + now.ToString("tt").ToLower();

However, I think the more elegant solution is to use a DateTimeFormatInfoinstancethat you construct and replace the AMDesignatorand PMDesignatorproperties with "am" and "pm" respectively:

但是,我认为更优雅的解决方案是使用您构造的DateTimeFormatInfo实例并将AMDesignatorPMDesignator属性分别替换为“am”和“pm”:

DateTimeFormatInfo fi = new DateTimeFormatInfo();

fi.AMDesignator = "am";
fi.PMDesignator = "pm";

string nowString = now.ToString("dddd, MMMM d, yyyy a\t h:mmtt", fi);

You can use the DateTimeFormatInfoinstance to customize many other aspects of transforming a DateTimeto a string.

您可以使用该DateTimeFormatInfo实例自定义将 a 转换DateTime为 a 的许多其他方面string

回答by Adam Wise

The problem with the above approaches is that the main reason you use a format string is to enable localization, and the approaches given so far would break for any country or culture that does not wish to include a final am or pm. So what I've done is written out an extension method that understands an additional format sequence 'TT' which signifies a lowercase am/pm. The below code is debugged for my cases, but may not yet be perfect:

上述方法的问题在于,您使用格式字符串的主要原因是为了启用本地化,并且到目前为止给出的方法对于不希望包含最终 am 或 pm 的任何国家或文化都会失效。所以我所做的是写出一个扩展方法,它理解一个附加的格式序列“TT”,它表示一个小写的 am/pm。以下代码针对我的情况进行了调试,但可能还不完美:

    /// <summary>
    /// Converts the value of the current System.DateTime object to its equivalent string representation using the specified format.  The format has extensions over C#s ordinary format string
    /// </summary>
    /// <param name="dt">this DateTime object</param>
    /// <param name="formatex">A DateTime format string, with special new abilities, such as TT being a lowercase version of 'tt'</param>
    /// <returns>A string representation of value of the current System.DateTime object as specified by format.</returns>
    public static string ToStringEx(this DateTime dt, string formatex)
    {
        string ret;
        if (!String.IsNullOrEmpty(formatex))
        {
            ret = "";
            string[] formatParts = formatex.Split(new[] { "TT" }, StringSplitOptions.None);
            for (int i = 0; i < formatParts.Length; i++)
            {
                if (i > 0)
                {
                    //since 'TT' is being used as the seperator sequence, insert lowercase AM or PM as appropriate
                    ret += dt.ToString("tt").ToLower();
                }
                string formatPart = formatParts[i];
                if (!String.IsNullOrEmpty(formatPart))
                {
                    ret += dt.ToString(formatPart);
                }
            }
        }
        else
        {
            ret = dt.ToString(formatex);
        }
        return ret;
    }

回答by tvanfosson

EDIT: Jon's example is much better, though I think the extension method is still the way to go so you don't have to repeat the code everywhere. I've removed the replace and substituted Jon's first example in place in the extension method. My apps are typically intranet apps and I don't have to worry about non-US cultures.

编辑:Jon 的示例要好得多,但我认为扩展方法仍然是可行的方法,因此您不必到处重复代码。我已经在扩展方法中删除了替换并替换了 Jon 的第一个示例。我的应用程序通常是 Intranet 应用程序,我不必担心非美国文化。

Add an extension method to do this for you.

添加一个扩展方法来为你做这件事。

public static class DateTimeExtensions
{
    public static string MyDateFormat( this DateTime dateTime )
    {
       return dateTime.ToString("dddd, MMMM d, yyyy a\t h:mm") +
              dateTime.ToString("tt").ToLower();
    }
}

...

item.PostedOn.MyDateFormat();

EDIT: Other ideas on how to do this at How to format a DateTime like "Oct. 10, 2008 10:43am CST" in C#.

编辑:有关如何在 C# 中格式化 DateTime 之类的“Oct. 10, 2008 10:43am CST”的其他想法。

回答by Nicholas Petersen

This should be the most performant of all these options. But too bad they couldn't work in a lowercase option into the DateTime format (tt opposite TT?).

这应该是所有这些选项中性能最高的。但太糟糕了,他们不能在 DateTime 格式的小写选项中工作(tt 与 TT 相对?)。

    public static string AmPm(this DateTime dt, bool lower = true)
    {
        return dt.Hour < 12 
            ? (lower ? "am" : "AM")
            : (lower ? "pm" : "PM");
    }