Humanizer 流畅日期 API 解析:OnDate.June 的用法、源码实现与测试验证
开发工具【免费下载链接】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 2.14.1 版本文档中OnDate.June类的完整 API 说明展开系统讲解该类 30 个静态日期属性、The(int)方法的签名与语义、DateOnly返回类型以及它们与源码实现、T4 模板生成机制和测试用例之间的对应关系。读完本文你将掌握如何用流畅语法构造“今年 6 月的某一天”并理解这些访问器在 .NET 6 目标框架下的生成原理与边界行为。类概览OnDate.June 是什么在 Humanizer 的 FluentDate 模块中OnDate是一个静态外观类内部按月份嵌套了 12 个同级子类January至December为“当前年份某月的某一天”提供可读的流畅访问器。OnDate.June就是其中专门面向 6 月的嵌套类。按 Humanizer.OnDate.June.md 文档的定义public class OnDate.June继承关系为System.Object→OnDate.June。类的文档描述是“Provides fluent date accessors for June”为 6 月提供流畅日期访问器其全部成员均声明为public static因此无需实例化即可直接调用。// 直接通过静态成员访问 var june1 OnDate.June.The1st;OnDate.June与 OnDate 类 的整体设计一致静态、无状态、每次调用都基于DateTime.Now计算当前年份。关于这一点fluent-dates-and-time-spans.mdx 场景指南给出了重要提示——不带From或Of(year)的属性会读取DateTime.Now在确定性代码如单元测试中应避免依赖它们而应注入起始日期。这一点在下面的源码分析中会进一步印证。全部 30 个属性成员签名与语义文档为OnDate.June列出了 30 个静态只读属性每个属性对应 6 月中的一个具体日期含义均为“The nth day of June of the current year”当前年份 6 月的第 n 天返回类型统一为System.DateOnly。属性返回日期当前年份属性返回日期当前年份The1st6 月 1 日The16th6 月 16 日The2nd6 月 2 日The17th6 月 17 日The3rd6 月 3 日The18th6 月 18 日The4th6 月 4 日The19th6 月 19 日The5th6 月 5 日The20th6 月 20 日The6th6 月 6 日The21st6 月 21 日The7th6 月 7 日The22nd6 月 22 日The8th6 月 8 日The23rd6 月 23 日The9th6 月 9 日The24th6 月 24 日The10th6 月 10 日The25th6 月 25 日The11th6 月 11 日The26th6 月 26 日The12th6 月 12 日The27th6 月 27 日The13th6 月 13 日The28th6 月 28 日The14th6 月 14 日The29th6 月 29 日The15th6 月 15 日The30th6 月 30 日典型声明形式以The10th为例如下public static System.DateOnly The10th { get; }注意6 月是小月只有 30 天因此该嵌套类不包含The31st对比同目录下 Humanizer.OnDate.May.md 中的May类就包含The31st。属性命名采用英文序数词后缀1st、2nd、3rd、4th…30th本身就是一种“可读性优先”的 API 设计。The(int) 方法按序号动态取值除固定属性外文档还收录了唯一的实例无关方法The(int)public static System.DateOnly The(int dayNumber);项目说明参数dayNumberSystem.Int32表示 6 月中的第几天返回值System.DateOnly当前年份 6 月dayNumber日的日期文档对该方法的描述为“The nth day of June of the current year”。它适合日期号在运行时才能确定的场景// 动态取值运行时才知道是哪一天 var target OnDate.June.The(15);源码实现从 DateTime.Now 到 DateOnlyOnDate.June的完整实现位于 OnDate.Days.cs6 月类的定义从第 973 行附近开始。核心实现模式为public static DateOnly The(int dayNumber) new(DateTime.Now.Year, 6, dayNumber); public static DateOnly The1st new(DateTime.Now.Year, 6, 1);由此可以确认三点实现事实年份来自DateTime.Now.Year所有成员都基于“当前系统时间的年份”因此属性值会随年份变化属于非确定性的即时计算月份固定为6这正是June类与May、December等其他嵌套类唯一的月份参数差异直接构造DateOnlynew DateOnly(year, month, day)是 .NET 6 引入的日期类型构造方式因此整个OnDate类都被#if NET6_0_OR_GREATER条件编译指令包裹——这意味着该 API 只在目标框架为 .NET 6 及以上时才可用.NET Framework 或 .NET Core 3.1 等旧框架无法引用此类型。T4 模板12 个嵌套类是如何生成的OnDate.Days.cs并不是手工编写的 2336 行代码而是由 OnDate.Days.tt 这个 T4 文本模板生成的。模板逻辑清晰展示了生成规律for (var month 1; month 12; month) { var firstDayOfMonth new DateTime(leapYear, month, 1); var monthName firstDayOfMonth.ToString(MMMM); // 生成 public class monthName { ... } }生成算法要点模板以2012 这个闰年为基准计算每个月的天数DateTime.DaysInMonth(leapYear, month)所以 2 月会生成The29th而 6 月只会生成到The30th属性名中的序数后缀1st、2nd、3rd…由 Humanizer 自身的day.Ordinalize()扩展方法生成模板与运行时 API 形成了“自举”式的呼应每个属性体都是new(DateTime.Now.Year, month, day)一行式实现。理解这一生成机制有助于你在阅读 OnDate.Days.cs 时快速定位任意月份的任意属性行号排列严格按“月份 × 天数”的固定节奏展开。测试验证OnDate.June 的行为约束仓库的测试文件 OnDateTests.cs 对OnDate系列访问器给出了直接的验证用例[Fact] public void OnJanuaryThe23rd() Assert.Equal(new(DateTime.Now.Year, 1, 23), OnDate.January.The23rd); [Fact] public void OnDecemberThe4th() Assert.Equal(new(DateTime.Now.Year, 12, 4), OnDate.December.The4th); [Fact] public void OnFebruaryThe() Assert.Equal(new(DateTime.Now.Year, 2, 11), OnDate.February.The(11));虽然测试没有逐月覆盖 June但验证模式是通用的断言访问器返回的DateOnly等于“用DateTime.Now.Year手工构造的同名日期”。由此可以推断对OnDate.June的任何属性其测试预期值也必然是new(DateTime.Now.Year, 6, n)。这套断言同时揭示了该 API 的两个使用约束测试本身也依赖DateTime.Now所以测试断言只在“运行测试的当天年份”内成立跨年运行需要重新评估预期值生产代码若要保证确定性应像 scenarios-fluent-dates 示例 那样显式注入起始日期而不是依赖Now。实战示例如何在实际代码中使用结合 Humanizer 的流畅日期场景OnDate.June的典型用法如下using Humanizer; // 1. 固定属性今年 6 月 1 日 DateOnly childrensDay OnDate.June.The1st; // 2. 动态方法运行时决定取 6 月的第几天 DateOnly midYear OnDate.June.The(15); // 3. 与 DateTime 构造器对照等价写法 DateOnly sameDay new(DateTime.Now.Year, 6, 15); // 4. 输出 Console.WriteLine(${childrensDay:yyyy-MM-dd} / {midYear:yyyy-MM-dd});输出示例假设当前年份为 20262026-06-01 / 2026-06-15OnDate.June返回的是DateOnly而非DateTime意味着它天然适合“仅关心日历日期、不关心时刻”的业务场景如排期、纪念日、任务截止日。若需要完整时刻可参考同模块的On.June在 On.Days.cs 中生成——后者提供对应的DateTime版本访问器。使用前提与限制小结维度说明目标框架仅.NET 6.0受#if NET6_0_OR_GREATER约束DateOnly类型依赖此框架年份基准DateTime.Now.Year结果随系统当前年份变化成员形态全部public static无实例状态直接通过类名调用月份天数6 月固定 30 天无The31st属性The(31)会抛出ArgumentOutOfRangeException确定性依赖DateTime.Now不适合需要可重复结果的逻辑测试中需按当前年份校准预期值深入阅读OnDate 类 API 文档OnDate外观类总览OnDate.June 完整 API 文档本文依据的原始文档OnDate.Days.cs 源码6 月类的实际实现OnDate.Days.tt 模板12 个月嵌套类的生成逻辑OnDateTests.cs 测试流畅日期访问器的断言模式流畅日期场景指南OnDate与InDate、In、On的组合使用与确定性建议FluentDate 目录In、On、InDate、OnDate四个日期外观类的全部源码与模板赞分享开发工具【免费下载链接】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 流式日期 API 详解On.August 类的用法、源码实现与测试验证Humanizer 流式日期 API 详解On.August 类的用法、源码实现与测试验证 Humanizer 为 .NET 开发者提供了名为 Fluent开发工具Humanizer 的 On.December 流畅日期访问器API 全解析与源码实现原理Humanizer 的 On.December 流畅日期访问器API 全解析与源码实现原理 本文聚焦 Humanizer 中 On.December 这一流畅开发工具PostgreSQL 架构实践指南从 JSONB 到事件存储、CDC 与 .NET 生态集成PostgreSQL 架构实践指南从 JSONB 到事件存储、CDC 与 .NET 生态集成 PostgreSQL 是软件架构设计中用途最广的关系型数据库之一开发工具上一篇Visual C运行库终极修复指南告别DLL文件丢失和软件兼容性问题下一篇HunterPie怪物猎人世界最强数据覆盖层终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考