我要获得一个自定义的 DateTime 格式,包括 AM/PM 指示符,但我希望“AM”或“PM”为小写,而不使其余字符小写。
这是否可以使用单一格式而不使用正则表达式?
这是我现在得到的:
item.PostedOn.ToString("dddd, MMMM d, yyyy a\\t h:mmtt")
现在的输出示例是2009 年 1 月 31 日星期六下午 1:34
我要获得一个自定义的 DateTime 格式,包括 AM/PM 指示符,但我希望“AM”或“PM”为小写,而不使其余字符小写。
这是否可以使用单一格式而不使用正则表达式?
这是我现在得到的:
item.PostedOn.ToString("dddd, MMMM d, yyyy a\\t h:mmtt")
现在的输出示例是2009 年 1 月 31 日星期六下午 1:34
我个人会将其格式化为两部分:非 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;
}
}
}
您可以将格式字符串分成两部分,然后将 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
许多其他方面。DateTime
string
编辑:乔恩的例子要好得多,虽然我认为扩展方法仍然是要走的路,所以你不必到处重复代码。我已经删除了替换并在扩展方法中替换了 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”)中有关如何执行此操作的其他想法。
上述方法的问题在于,您使用格式字符串的主要原因是启用本地化,而到目前为止给出的方法对于不希望包含最终 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;
}
这应该是所有这些选项中性能最高的。但太糟糕了,他们不能在 DateTime 格式的小写选项中工作(tt 与 TT 相反?)。
public static string AmPm(this DateTime dt, bool lower = true)
{
return dt.Hour < 12
? (lower ? "am" : "AM")
: (lower ? "pm" : "PM");
}