- 开发工具
【免费下载链接】Humanizer
Humanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities
OnDate.September是 Humanizer FluentDate 体系中的一个静态访问器类,用于以"自然语言"风格直接获取当前年份九月中任意一天的System.DateOnly值,例如OnDate.September.The1st表示"今年的 9 月 1 日"。通过本文,你将掌握该类的全部 30 个静态属性与动态方法The(int dayNumber)的用法、其背后的 T4 模板生成原理,以及基于源码与测试用例的最佳实践与边界约束。
类定位:FluentDate 中的 DateOnly 访问器
OnDate.September定义于 Humanizer 的 FluentDate 目录 之下,命名空间为Humanizer,其 API 参考文档位于 Humanizer.OnDate.September.md。该类的完整声明为:
public class OnDate.September- 继承关系:
System.Object→September,是一个普通静态成员类(本身非静态类,但所有成员均为静态)。 - 返回类型:所有成员统一返回
System.DateOnly,即 .NET 6 引入的"仅日期"结构体,不含时间分量。 - 平台前提:对应实现被
#if NET6_0_OR_GREATER条件编译保护(见 OnDate.Days.cs),因此该类仅在 .NET 6 及更高目标框架下可用。
从源码结构看,OnDate是面向DateOnly的整套 12 个月份访问器容器,同目录下还存在返回DateTime的On系列(On.Days.cs)以及面向相对时间的In/InDate系列,共同构成 Humanizer 的 FluentDate 日期表达式 DSL。
完整属性清单:The1st 到 The30th
与原 API 文档一致,OnDate.September提供 30 个静态只读属性,分别对应九月(30 天月份)的每一天。九月没有The31st,这是与 31 天月份类(如OnDate.January包含The31st,见 Humanizer.OnDate.January.md)的显著差异。
每个属性的声明形式均为:
public static System.DateOnly The10th { get; }完整成员清单如下:
| 属性 | 含义 | 属性 | 含义 |
|---|---|---|---|
The1st | 今年 9 月 1 日 | The16th | 今年 9 月 16 日 |
The2nd | 今年 9 月 2 日 | The17th | 今年 9 月 17 日 |
The3rd | 今年 9 月 3 日 | The18th | 今年 9 月 18 日 |
The4th | 今年 9 月 4 日 | The19th | 今年 9 月 19 日 |
The5th | 今年 9 月 5 日 | The20th | 今年 9 月 20 日 |
The6th | 今年 9 月 6 日 | The21st | 今年 9 月 21 日 |
The7th | 今年 9 月 7 日 | The22nd | 今年 9 月 22 日 |
The8th | 今年 9 月 8 日 | The23rd | 今年 9 月 23 日 |
The9th | 今年 9 月 9 日 | The24th | 今年 9 月 24 日 |
The10th | 今年 9 月 10 日 | The25th | 今年 9 月 25 日 |
The11th | 今年 9 月 11 日 | The26th | 今年 9 月 26 日 |
The12th | 今年 9 月 12 日 | The27th | 今年 9 月 27 日 |
The13th | 今年 9 月 13 日 | The28th | 今年 9 月 28 日 |
The14th | 今年 9 月 14 日 | The29th | 今年 9 月 29 日 |
The15th | 今年 9 月 15 日 | The30th | 今年 9 月 30 日 |
所有属性均为基于当前年份的计算属性:无论何时访问,返回的日期年份始终取DateTime.Now.Year,月份固定为 9,日期为属性名对应的序号。
动态方法:The(int dayNumber)
除了 30 个固定属性,OnDate.September还提供一个参数化入口,用于以变量方式指定九月中的任意一天:
public static System.DateOnly The(int dayNumber);- 参数:
dayNumber(System.Int32),表示九月的第 N 天。 - 返回值:
System.DateOnly,即当前年份九月的第dayNumber天。
典型用法是配合循环或动态业务值构造日期,例如"距开学第 N 天"这类场景:
for (int day = 1; day <= 30; day++) { DateOnly date = OnDate.September.The(day); Console.WriteLine(date); // 输出今年 9 月 1 日 … 今年 9 月 30 日 }从源码实现看,The(int dayNumber)直接执行new(DateTime.Now.Year, 9, dayNumber)。由于System.DateOnly构造函数会校验日期合法性,当dayNumber不在 1–30 的合法区间内时(例如 0、31 或负数),会抛出ArgumentOutOfRangeException,这一点在实际调用时需要自行保证参数范围。
实战示例:在项目中直接使用
以下代码可在 .NET 6+ 项目中直接运行(需引用 Humanizer 程序集并using Humanizer;):
using Humanizer; // 固定属性:开学纪念日(今年 9 月 1 日) DateOnly schoolOpening = OnDate.September.The1st; // 属性与 DateTime 互转 DateTime asDateTime = OnDate.September.The10th.ToDateTime(TimeOnly.MinValue); // 动态方法:报到日由变量决定 int checkInDay = 15; DateOnly checkIn = OnDate.September.The(checkInDay); // 与字符串化、序数化能力组合,输出如 "September 15" string label = checkIn.ToString("MMMM d"); Console.WriteLine($"开学日:{schoolOpening}"); Console.WriteLine($"报到日:{label}({checkIn})");结合 Humanizer 的其他扩展,你可以进一步把该日期输出为自然语言,例如使用 DateToOrdinalWordsExtensions 或 DateHumanizeExtensions 生成"9 月 15 日"或"3 天前"等人类可读文案,使 FluentDate 的取值能力与 Humanizer 的格式化能力形成完整闭环。
源码实现与 T4 生成机制
OnDate.September的实现位于 OnDate.Days.cs,其核心逻辑极其精简——每个成员都只是一行表达式:
public class September { public static DateOnly The(int dayNumber) => new(DateTime.Now.Year, 9, dayNumber); public static DateOnly The1st => new(DateTime.Now.Year, 9, 1); // ... The30th 同理 }值得注意的是,这 30 个属性并非手写,而是由 T4 文本模板 OnDate.Days.tt 自动生成的,模板机制可以总结为以下几点:
- 闰年锚点:模板以
leapYear = 2012为基准遍历 12 个月,确保 2 月 29 日这类"仅闰年存在"的日期也能被覆盖到。 - 月份名推导:通过
new DateTime(leapYear, month, 1).ToString("MMMM")获得本地化月份名(如September),并据此生成对应类名。 - 天数推导:用
DateTime.DaysInMonth(leapYear, month)计算当月天数,因此 9 月只会生成The1st–The30th,不会有 31 号。 - 序数词生成:调用 Humanizer 的
day.Ordinalize()把数字转成1st、2nd、3rd、21st、22nd、23rd、30th等属性名后缀,这正是属性命名中 11/12/13 与 21/22/23 后缀差异的来源。 - 条件编译:模板整体输出被
#if NET6_0_OR_GREATER包裹,与DateOnly的可用性保持一致。
理解了这套生成机制,就可以从源码层面解释该 API 文档中的每一个成员:它们不是手写常量,而是由"固定年份 + 月份 + 序号"模板批量推导的、随DateTime.Now.Year动态变化的计算属性。
测试验证与使用注意事项
Humanizer 仓库在 OnDateTests.cs 中为该系列提供了验证用例,例如:
[Fact] public void OnJanuaryThe23rd() => Assert.Equal(new(DateTime.Now.Year, 1, 23), OnDate.January.The23rd); [Fact] public void OnFebruaryThe() => Assert.Equal(new(DateTime.Now.Year, 2, 11), OnDate.February.The(11));同样的模式适用于OnDate.September(将月份换为 9)。基于源码与测试,使用时有以下几点值得注意:
- 年份动态性:所有成员返回"当前年份"的九月日期,跨年调用会产生不同的
DateOnly;若需要指定年份,应改用new DateOnly(year, 9, day)自行构造。 - 合法范围:固定属性天然限定在 1–30;
The(int dayNumber)接受任意int,但非 1–30 的值会触发DateOnly构造时的参数校验异常,业务代码应先做边界判断。 - 框架版本:类仅在
NET6_0_OR_GREATER下编译,面向 .NET Framework 或 .NET 5 的项目无法使用该 API,可退回On.September(返回DateTime)系列。 - 静态调用:所有成员均为静态,无需实例化
OnDate或September,直接以OnDate.September.The15th形式调用即可。
相关资源
- API 参考:Humanizer.OnDate.September.md
- 源码实现:OnDate.Days.cs
- 生成模板:OnDate.Days.tt
- 测试用例:OnDateTests.cs
- 同类 API:Humanizer.OnDate.January.md(含 31 天对照)
- 开发工具
【免费下载链接】Humanizer
Humanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities
相关推荐
Humanizer OnDate.September 流式日期 API 完全指南:用 DateOnly 表达"九月第 N 天"
Humanizer OnDate.September 流式日期 API 完全指南:用 DateOnly 表达"九月第 N 天" 本文是 Humanizer 流式
开发工具Humanizer OnDate.September 详解:用流式 API 构建 9 月日期(DateOnly)
Humanizer OnDate.September 详解:用流式 API 构建 9 月日期(DateOnly) 本篇指南聚焦 Humanizer 的 OnDa
开发工具Humanizer OnDate.December 流畅日期 API 完全指南:用 C 优雅构造当年 12 月的每一天
Humanizer OnDate.December 流畅日期 API 完全指南:用 C 优雅构造当年 12 月的每一天 导读 OnDate.December 是
开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考