53

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

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

这是我现在得到的:

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

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

4

5 回答 5

65

我个人会将其格式化为两部分:非 am/pm 部分和带有 ToLower 的 am/pm 部分:

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

另一个选项(我将在几秒钟内研究)是获取当前的 DateTimeFormatInfo,创建一个副本,并将 am/pm 指示符设置为小写版本。然后将该格式信息用于正常格式。您显然想要缓存 DateTimeFormatInfo...

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

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

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

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;
        }
    }
}
于 2009-01-31T19:39:40.403 回答
26

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

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

但是,我认为更优雅的解决方案是使用您构造的DateTimeFormatInfo实例AMDesignator并将andPMDesignator属性分别替换为“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);

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

于 2009-01-31T19:49:44.440 回答
1

编辑:乔恩的例子要好得多,虽然我认为扩展方法仍然是要走的路,所以你不必到处重复代码。我已经删除了替换并在扩展方法中替换了 Jon 的第一个示例。我的应用程序通常是 Intranet 应用程序,我不必担心非美国文化。

添加扩展方法来为您执行此操作。

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();

编辑:关于如何在 C# 中格式化日期时间(如“2008 年 10 月 10 日 10:43am CST”)中有关如何执行此操作的其他想法。

于 2009-01-31T19:33:35.407 回答
1

上述方法的问题在于,您使用格式字符串的主要原因是启用本地化,而到目前为止给出的方法对于不希望包含最终 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;
    }
于 2011-12-19T18:47:37.780 回答
0

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

    public static string AmPm(this DateTime dt, bool lower = true)
    {
        return dt.Hour < 12 
            ? (lower ? "am" : "AM")
            : (lower ? "pm" : "PM");
    }
于 2013-03-14T21:54:58.677 回答