Humanizer FluentDate 之 On 类:用自然语言优雅构造日期的流畅 API 完全指南
发布时间:2026/9/28 3:30:26来源:尧图网络
开发工具【免费下载链接】HumanizerHumanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities项目地址https://gitcode.com/gh_mirrors/hu/Humanizer点击查看免费下载Humanizer 的On类是 FluentDate流畅日期体系的核心入口之一它把「某年某月某日」这种日期构造需求封装成接近自然语言的调用形式On.January.The23rd、On.February.The(11)。本文以 Humanizer.On API 文档 为骨架结合 On.Days.cs 源码、T4 生成模板与单元测试完整讲解On类的 12 个月份嵌套类、The(int)方法与The1st~The31st属性集合的使用方法、实现原理和边界约束并顺带梳理它和In、OnDate系列的定位差异。读完你可以在自己的 .NET 项目中直接使用这套 API 写出可读性极强的日期代码。On 类是什么在 Humanizer 的文档体系中On是一个公开类public class On继承自System.Objectpublic class On它位于Humanizer命名空间下源码中的实际声明见 On.Days.cs职责是为每个月份提供流畅的日期访问器fluent date accessors。所谓流畅是指代码读起来像一句英文自然语言On.January.The21st读作 on January the 21st直接表达「在 1 月 21 日」无需再像new DateTime(year, 1, 21)那样先准备年份变量。On类本身不直接提供日期成员它的全部能力由 12 个嵌套类承载每个嵌套类对应一个月份。在 version-3.0.1 API 文档 中On只给出类声明成员明细被拆分到按月份命名的独立页面例如 Humanizer.On.January.md这正是 Humanizer 自动生成 API 参考的一贯组织方式。12 个月份嵌套类API 全貌On类内部定义了 12 个嵌套类名称即月份英文名全部为public class且均可直接以On.Month形式访问嵌套类对应月份提供的最多日属性On.January1 月The1st~The31stOn.February2 月The1st~The29thOn.March3 月The1st~The31stOn.April4 月The1st~The30thOn.May5 月The1st~The31stOn.June6 月The1st~The30thOn.July7 月The1st~The31stOn.August8 月The1st~The31stOn.September9 月The1st~The30thOn.October10 月The1st~The31stOn.November11 月The1st~The30thOn.December12 月The1st~The31st每个嵌套类内包含两组静态成员一个The(int dayNumber)方法返回当前年份下该月第dayNumber天的DateTime一组The1st~The31st或到该月最大天数的静态属性每个属性固定返回当前年份下该月对应日期的DateTime。以 On.January 文档 中的成员为例On.January的完整签名形态是// The nth day of January of the current year public static DateTime The(int dayNumber); // The 1st day of January of the current year public static DateTime The1st { get; } // ... 依此类推直至 The31st public static DateTime The31st { get; }所有成员返回值类型均为System.DateTime且全部是静态成员无需实例化On或月份嵌套类。核心成员详解The 方法与序号属性The(int dayNumber)按天数动态取值The(int dayNumber)是每个月份类都有的通用入口接受一个int参数表示当月第几天public static DateTime The(int dayNumber) new(DateTime.Now.Year, 1, dayNumber); // 以 January 为例从 On.Days.cs 源码 可以看到它直接以「当前年份 固定月份 传入天数」构造DateTime。使用示例var date On.February.The(11); // 当年 2 月 11 日 var date2 On.October.The(31); // 当年 10 月 31 日dayNumber需要落在该月的合法天数范围内例如On.February.The(30)会因 2 月无 30 日而抛出ArgumentOutOfRangeException这一点与直接new DateTime(year, month, day)的约束完全一致。The1st~The31st固定序数日属性除了动态方法每个月份类还预生成了一组按序数词命名的只读属性。以January为例On.Days.cspublic static DateTime The1st new(DateTime.Now.Year, 1, 1);属性名使用英文序数词后缀1st、2nd、3rd、4th……直到该月最大天数。这样写业务代码时几乎零心智负担var newYear On.January.The1st; // 当年 1 月 1 日 var valentine On.February.The14th; // 当年 2 月 14 日 var halloween On.October.The31st; // 当年 10 月 31 日统一的「当前年份」语义注意无论是The(int)还是TheNth属性年份一律取自DateTime.Now.Year本地当前时间即所有On成员返回的都是「今年」的日期。如果需要指定具体年份Humanizer 的In类提供了对应的XxxOf(int year)方法详见下文「与 In 类的关系」小节。源码原理T4 模板批量生成On类巨大的成员量12 个嵌套类 × 每个类 20~32 个成员并非手写维护而是由 T4 文本模板生成的。On.Days.tt 中清晰地体现了生成逻辑核心循环如下节选for (var month 1; month 12; month) { var firstDayOfMonth new DateTime(leapYear, month, 1); var monthName firstDayOfMonth.ToString(MMMM); public class # monthName # // 生成 12 个月份嵌套类 { public static DateTime The(int dayNumber) new(DateTime.Now.Year, # month #, dayNumber); for (var day 1; day DateTime.DaysInMonth(leapYear, month); day) { var ordinalDay day.Ordinalize(); public static DateTime The# ordinalDay # new(DateTime.Now.Year, # month #, # day #); } } }这里有几个值得注意的实现细节闰年基准leapYear 2012模板用 2012 年闰年的DateTime.DaysInMonth决定每个月份生成多少个日属性因此 2 月会生成到The29th而普通年份 2 月只有 28 天此时On.February.The29th会抛出异常这一点在「边界与注意事项」中还会强调。Ordinalize()的复用序数属性名The1st、The22nd、The23rd直接调用 Humanizer 自身的 OrdinalizeExtensions.cs 扩展方法生成体现了库内部「自举」的设计——用 Humanizer 生成 Humanizer 的 API。月份名取自ToString(MMMM)模板用文化相关的完整月份名January、February……作为嵌套类名保证了类名与月份语义一一对应。最终生成的 On.Days.cs 约 2300 行全部由模板产出人工只维护模板本身。日期类型扩展OnDate 与 DateOnly 变体On类返回的是System.DateTime。如果项目面向 .NET 6 且希望使用DateOnly仅日期、无时间的轻量类型Humanizer 提供了对偶类OnDate源码位于 OnDate.Days.cs该文件用#if NET6_0_OR_GREATER条件编译保护public class OnDate { public class January { // The nth day of January of the current year public static DateOnly The(int dayNumber) new(DateTime.Now.Year, 1, dayNumber); // The 1st day of January of the current year public static DateOnly The1st new(DateTime.Now.Year, 1, 1); } }OnDate的嵌套结构与On完全一致同样有 12 个月份类、The(int)与TheNth属性唯一差异是返回值类型为DateOnly。可以据此推断这套流畅 API 在设计上刻意保持了「按日期类型分族」的策略——DateTime用On/InDateOnly用OnDate/InDate方便不同类型项目各取所需。对应的InDate系列位于 InDate.cs 与 InDate.Months.cs。与 In 类的关系On 管「某日」In 管「某月首日」On并非孤立存在它与In类共同构成 FluentDate 的「定点日期」能力二者常配合使用需求推荐 API示例今年某月的某一天On.Month.TheNthOn.December.The25th指定年份某月的某一天On.Month.The(n)配合DateTime构造见下方进阶示例今年某月 1 日In.MonthIn.April指定年份某月 1 日In.MonthOf(year)In.AprilOf(2030)某年 1 月 1 日元旦In.TheYear(year)In.TheYear(2030)In类的月份属性与Of(year)方法定义在 In.Months.cs例如// Returns 1st of April of the current year public static DateTime April new(DateTime.UtcNow.Year, 4, 1); // Returns 1st of April of the year passed in public static DateTime AprilOf(int year) new(year, 4, 1);In的「当前年份」取的是DateTime.UtcNow.Year而On取的是DateTime.Now.Year二者时钟基准不同UTC vs 本地时间在跨时区场景需要留意。In.cs 还提供了TheYear(int year)方法返回指定年份的 1 月 1 日public static DateTime TheYear(int year) new(year, 1, 1);另外In类还支持「从当前时刻/指定时刻起算 N 个时间单位之后」的语义In.SomeTimeFrom.cs例如In.One.Week一周后、In.Two.Hours两小时后与On的「绝对日期」定位形成互补。实战示例完整可运行代码结合上述 API下面是一段完整的实战示例演示On类在日常业务中的典型用法假定当前运行年份为 2026 年using Humanizer; // 1) 用序数属性取「今年」的固定日期 DateTime christmas On.December.The25th; // 2026-12-25 DateTime piDay On.March.The14th; // 2026-03-14 DateTime newYear On.January.The1st; // 2026-01-01 // 2) 用 The(int) 动态取「今年」任意一天 DateTime payday On.MonthlyPayday(15); // 假设某月 15 日见下方辅助方法 DateTime feb11 On.February.The(11); // 2026-02-11 // 3) 与 In 类配合构造「指定年份的特定日期」 DateTime independenceDay2030 new( In.TheYear(2030).Year, // 2030 年 1 月 1 日取其年份 On.July.The4th.Month, // 7 月 On.July.The4th.Day); // 4 日 // 结果2030-07-04 // 4) 直接比较日期 bool isTodayPayday On.December.The25th DateTime.Today; // 5) 打印更人性化的描述 Console.WriteLine(christmas.Humanize()); // 例如 December 25说明上述第 2 步中的On.MonthlyPayday(15)是示意性辅助方法实际库中不存在On类只提供按月/日定位的成员。若要表达「每月某日」通常按具体月份调用如On.January.The(15)。代码中出现的.Humanize()、.Ordinalize()等扩展均来自 Humanizer 库本体可见 FluentDate 与字符串人性化能力是同一套 API 生态。测试验证仓库中的真实用例On类的行为有单元测试直接背书见 tests/Humanizer.Tests/FluentDate/OnTests.cspublic class OnTests { [Fact] public void OnJanuaryThe23rd() Assert.Equal(new(DateTime.Now.Year, 1, 23), On.January.The23rd); [Fact] public void OnDecemberThe4th() Assert.Equal(new(DateTime.Now.Year, 12, 4), On.December.The4th); [Fact] public void OnFebruaryThe() Assert.Equal(new(DateTime.Now.Year, 2, 11), On.February.The(11)); }这三个测试用例恰好覆盖了三种访问形态The23rd序数属性、The4th序数属性、以及The(11)动态方法并确认了「年份取DateTime.Now.Year」的行为。此外 InTests.cs 中也有On.January.The21st作为基准日期参与In类相对时间的断言InTests.cs说明两个类在真实测试中经常组合使用。FluentDate 的其余测试覆盖见 tests/Humanizer.Tests/FluentDate/ 目录。边界与注意事项年份恒为今年On所有成员都绑定DateTime.Now.Year跨年时如 12 月 31 日 23:59 与 1 月 1 日 00:00 之间两次调用可能得到不同年份的结果需要固定年份时请改用In.XxxOf(year)或自行new DateTime(...)。2 月 29 日仅在闰年合法On.February.The29th在平年会抛ArgumentOutOfRangeException因为模板以 2012 闰年为基准生成到 29 日而构造时使用的是实际当前年份。业务上应避免无条件调用该属性。不存在的日期同样抛异常On.April.The31st、On.September.The31st等属性根本不存在不会通过编译而The(31)传参会在运行时抛异常——静态属性在编译期就替你拦截了这类错误这也是序数属性的一大价值。返回值是DateTime而非DateOnlyOn返回带时间的DateTime时间为 00:00若只关心日期可改用 .NET 6 下的OnDate系列。时区基准差异On/OnDate用DateTime.Now.Year本地时间In的月份属性用DateTime.UtcNow.YearUTC分布式系统中需显式统一时钟来源。相关资源API 参考Humanizer.On.md、Humanizer.On.January.md源码实现src/Humanizer/FluentDate/On.Days.cs、T4 模板 src/Humanizer/FluentDate/On.Days.tt关联类型OnDate.Days.cs、In.cs、In.Months.cs、In.SomeTimeFrom.cs单元测试tests/Humanizer.Tests/FluentDate/OnTests.cs可运行的官方示例工程website/docs/_examples/scenarios-fluent-dates/如果你正在写日历、排期、账单日等强日期业务把new DateTime(year, month, day)换成On.Month.TheNth代码的可读性会立刻上一个台阶——这就是 Humanizer FluentDate 设计的初衷。赞分享开发工具【免费下载链接】HumanizerHumanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities项目地址https://gitcode.com/gh_mirrors/hu/Humanizer点击查看免费下载相关推荐Humanizer FluentDate 之 On 类以自然语言流畅构造当月日期的 DateTime 完整指南Humanizer FluentDate 之 On 类以自然语言流畅构造当月日期的 DateTime 完整指南 本文是 Humanizer 2.10.1开发工具Humanizer On 类 API 详解用 FluentDate 流畅构造当年日期的完整指南Humanizer On 类 API 详解用 FluentDate 流畅构造当年日期的完整指南 本篇技术指南以 Humanizer 2.11.10 版本 AP开发工具Humanizer 的 On.February 流畅日期 API用自然语言构造二月日期的完整指南Humanizer 的 On.February 流畅日期 API用自然语言构造二月日期的完整指南 导读 On.February 是 .NET 字符串与日期处理开发工具上一篇LinkSwift九大网盘直链下载助手告别下载限速的智能解决方案下一篇8大网盘极速下载LinkSwift浏览器脚本终极解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网