如何在日期中为日号添加“st”、“nd”、“rd”或“th”






3.92/5 (9投票s)
一个自定义类型格式化程序,用于在输出日期字符串时为日号添加适当的“st/nd/rd/th”文本
引言
我最近有一个需求,需要以包含添加到日号的两位字母后缀的格式输出日期字符串。例如,“January 1st 2008”而不是“January 1 2008”。
经过一些调查,似乎 .NET 本身不支持此功能(这并不奇怪)。我得出的结论是,在 .NET 中实现此行为有多种方法,并选择了一种“对 .NET Framework 友好”的方法,因此它提供了良好的重用价值,并且对于 .NET 开发人员来说直观易用。
方法
该解决方案利用了框架中的自定义格式功能,可以通过实现 IFormatProvider
和 ICustomFormatter
接口来提供自定义 string
格式,以便与支持格式化的方法(如 String.Format()
或 Console.WriteLine()
)一起使用。
我决定通过为 DateTime
类型添加新的格式选项来扩展框架中现有的 DateTime
格式提供。框架对日期格式的现有支持非常全面;以下是一些常用的格式说明符:
格式 | 输出 |
---|---|
d |
短日期模式 |
D |
长日期模式 |
F |
完整日期/时间模式 |
有关更多信息,请参阅 MSDN 文章 - 标准 DateTime 格式字符串。
我的想法是复制其中一些标准格式(在适当的情况下)并包含日号后缀。以下日期格式已被“扩展”:
标准版 | 示例 | 带后缀 | 示例 |
---|---|---|---|
dd |
31 | ddx |
31st |
D |
31 January 2008 | Dx |
31st January 2008 |
F |
31 January 2008 21:30:15 | Fx |
31st January 2008 21:30:15 |
f |
31 January 2008 21:30 | fx |
31st January 2008 21:30 |
m |
31 January | mx |
31st January |
R |
Thu, 31 Jan 2008 21:30:15 GMT | Rx |
Thu, 31st Jan 2008 21:30:15 GMT |
U |
31 January 2008 21:30:15 | Ux |
31st January 2008 21:30:15 |
- | - | x |
st |
请注意,以上示例显示的是英语(英式)格式的日期。
我还希望允许开发人员通过利用日号后缀来创建她或他自己的日期格式。这使得可以使用带后缀的日号来组合自己的格式。例如:
string.Format(new DayNumberFormatInfo(),
"It's the {0:ddx} day of the month", DateTime.Now);
代码结构
附件的解决方案中有两个项目:
MarkGwilliam.com.Framework.Formatting
- 格式类MarkGwilliam.com.Framework.Formatting.Tests
- 单元测试(需要 NUnit)
DayNumberFormatInfo
类包含实际的格式化逻辑。此类实现了所需的框架接口方法,这些方法又调用 GetDayNumberSuffix()
帮助方法来执行 string
格式化。
演示项目/单元测试
这是一个非常小的主题,所以没有真正的演示项目。相反,有许多单元测试,展示了如何使用支持的格式,并允许您修改代码而不意外引入缺陷。
示例用法
在以下示例中,使用了格式字符串“Dx
”,这与使用格式字符串“D
”的输出相同,但为日号添加了两位字母后缀。
string.Format(new GetDayNumberSuffix(), "{0:Dx}", DateTime.Now);
全球化(和一些限制)
该代码是为英国文化格式化日期而开发的。“扩展”日期格式均遵循英式日期格式。
通过一些额外的努力,可以修改它使其更具文化意识并模仿其他文化,但这超出了我的需求,所以我没有费心去做。如果您有兴趣这样做,那么您需要修改 DayNumberFormatInfo.Format()
方法,并可能使用另一种技术来替换标准格式化 string
中的日号。
但是,该代码在当前状态下仍然可以在所有文化中有效使用,如果您希望进一步扩展它,它是一个起点。
.NET Framework 限制
我最初希望在调用 DateTime.ToString()
时提供此格式化功能,但 .NET Framework 代码不支持以这种方式使用 ICustomFormatter
。这很不走运,因为 String.ToString()
函数支持。通过使用 Reflector 或类似工具查看 IL 代码,可以证明这一点。出于同样的原因,也不支持解析。
关注点
实际上没有,除了如果您考虑添加一些功能,值得检查一下您是否可以通过某种方式扩展框架。这使得开发人员更容易使用您的代码,并希望在此过程中扩展您对 .NET 的知识。
延伸阅读
关于自定义格式化程序的主题在 MSDN 文档以及 The Code Project 上的文章“Custom String Formatting in .NET”中有详细描述。
历史
- 版本 1.0 - 2007 年 11 月 16 日 - 初始版本