尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Humanizer FluentDate 指南:使用 InDate.Six 编写 6 天/周/月/年后日期计算

Humanizer FluentDate 指南:使用 InDate.Six 编写 6 天/周/月/年后日期计算 开发工具【免费下载链接】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 的InDate.Six静态类展开它隶属于 FluentDate 流式日期 API用于以接近自然语言的方式计算从现在起 6 天后/周/月/年以及从某个指定日期起 6 个时间单位之后的日期。读完本文你将掌握InDate.Six全部 4 个属性和 8 个方法的签名、返回类型、UTC 语义以及它们与InDate、In、OnDate等姊妹类型和 T4 代码生成管线的关系可直接在 .NET 6 项目中落地使用。InDate.Six是什么InDate.Six是 Humanizer FluentDate 模块 中面向System.DateOnly的静态嵌套类定义于 InDate.SomeTimeFrom.cspublic static class InDate.Six { public static DateOnly Days { get; } public static DateOnly Weeks { get; } public static DateOnly Months { get; } public static DateOnly Years { get; } public static DateOnly DaysFrom(DateOnly date); public static DateOnly DaysFrom(DateTime date); public static DateOnly WeeksFrom(DateOnly date); public static DateOnly WeeksFrom(DateTime date); public static DateOnly MonthsFrom(DateOnly date); public static DateOnly MonthsFrom(DateTime date); public static DateOnly YearsFrom(DateOnly date); public static DateOnly YearsFrom(DateTime date); }它继承自System.Object本身是InDate的公开静态嵌套类。命名空间为Humanizer因此引入using Humanizer;后即可直接以InDate.Six.Days的形式访问。与InDateTime 版的关系InDate.Six是In.Six的DateOnly版本。In系列返回System.DateTime见 In.SomeTimeFrom.csInDate系列返回System.DateOnly。两者均由同一个 T4 模板驱动生成详见下文代码生成一节。如果业务逻辑不关心时刻、只需要纯日期优先使用InDate如果需要保留时间分量如DateTime.UtcNow的时分秒则使用In。四个属性从现在起 6 个时间单位InDate.Six的四个静态属性全部基于DateTime.UtcNow计算并在返回前通过DateOnly.FromDateTime截断时间分量只保留日期部分属性含义源码实现InDate.SomeTimeFrom.csDays从现在起 6 天DateOnly.FromDateTime(DateTime.UtcNow.AddDays(6))Weeks从现在起 6 周DateOnly.FromDateTime(DateTime.UtcNow.AddDays(42))Months从现在起 6 个月DateOnly.FromDateTime(DateTime.UtcNow.AddMonths(6))Years从现在起 6 年DateOnly.FromDateTime(DateTime.UtcNow.AddYears(6))使用示例using Humanizer; DateOnly due InDate.Six.Days; // 例如 2026-09-30取决于调用时刻 DateOnly halfYear InDate.Six.Months; DateOnly promoEnd InDate.Six.Weeks; DateOnly licenseExpiry InDate.Six.Years;关键语义说明UTC 基准四个属性都以DateTime.UtcNow为基准不受调用方本地时区影响可以推断这是为了保证相对日期在不同时区的服务器上结果一致周换算为天Weeks内部实际是AddDays(42)6 × 7周不经过AddWeeks这与 GeneratedFluentDateTests.cs 中RelativeDateUnit.Week date.AddDays(amount * 7)的测试换算完全一致月份/年份语义AddMonths(6)、AddYears(6)遵循 .NET 的日历加法规则。以月末为基准时可能产生钳制效果如 8 月 31 日 6 个月得到次年 2 月 28/29 日但属性本身以当天 UTC 日期为起点日常使用无歧义DateOnly 输出返回类型为System.DateOnly.NET 6 引入的纯日期结构无时区、无时刻适合存储和比较到期日这类业务日期。测试如何验证属性仓库用反射式测试保证这些属性正确。GeneratedFluentDateTests.cs 中的AssertDateOnlyRelativeProperties遍历InDate的所有相对日期嵌套类型One 到 Ten对每个属性在调用前后分别取DateTime.UtcNow断言返回值落在[before amount, after amount]区间内以消除测试执行期间的时钟漂移var before DateTime.UtcNow; var actual Assert.IsTypeDateOnly(property.GetValue(null)); var after DateTime.UtcNow; Assert.InRange(actual, DateOnly.FromDateTime(Add(before, amount, unit)), DateOnly.FromDateTime(Add(after, amount, unit)));该文件同时用RelativeAmounts字典将Six → 6映射到对应偏移量GeneratedFluentDateTests.cs因此Six的所有属性都会被覆盖验证。八个方法从指定日期起 6 个时间单位与属性不同From系列方法允许传入一个基准日期计算该日期之后 6 个时间单位的结果。每个单位提供两个重载一个接收DateOnly另一个接收DateTime后者内部先做日期运算再转回DateOnly。方法DateOnly 重载实现DateTime 重载实现DaysFrom(date)date.AddDays(6)DateOnly.FromDateTime(date.AddDays(6))WeeksFrom(date)date.AddDays(42)DateOnly.FromDateTime(date.AddDays(42))MonthsFrom(date)date.AddMonths(6)DateOnly.FromDateTime(date.AddMonths(6))YearsFrom(date)date.AddYears(6)DateOnly.FromDateTime(date.AddYears(6))全部返回System.DateOnly。使用示例using Humanizer; DateOnly start new(2026, 3, 31); DateOnly d InDate.Six.DaysFrom(start); // 2026-04-06 DateOnly w InDate.Six.WeeksFrom(start); // 2026-05-12 DateOnly m InDate.Six.MonthsFrom(start); // 2026-09-30 DateOnly y InDate.Six.YearsFrom(start); // 2032-03-31典型业务场景从合同签订日start推算 6 个月质保期、从课程开课日推算 6 周结课日、从保单生效日推算 6 年续保提醒日。相比手写date.AddMonths(6)InDate.Six.MonthsFrom(date)的意图更接近自然语言代码即文档。月末钳制行为提醒MonthsFrom/YearsFrom委托给DateOnly.AddMonths/AddYears。如果基准日落在月末如 1 月 31 日加上 6 个月会得到 7 月 31 日这类正常结果但如果目标月份没有对应日期例如 8 月 31 日加 6 个月指向次年 2 月.NET 会钳制到该月最后一天次年 2 月 28/29 日。这是 .NET 标准日历语义不是 Humanizer 的特殊处理。测试如何验证方法GeneratedFluentDateTests.cs 的AssertDateOnlyRelativeMethods以2024-02-29闰日为基准分别对DateOnly和DateTime两个重载断言actual Add(base, 6, unit)var dateTime new DateTime(2024, 2, 29, 10, 20, 30, DateTimeKind.Utc); var dateOnly DateOnly.FromDateTime(dateTime); var argument parameterType typeof(DateOnly) ? dateOnly : (object)dateTime; // ... 遍历 Six 的 From 方法断言 Add(base, 6, unit)选用闰日做基准是有意为之用于同时验证闰年边界下AddYears/AddMonths的行为。此外 InDateTests.cs 中还有一条手写用例展示了InDate.Five.DaysFrom(baseDate)与baseDate.AddDays(5)等价的手动验证模式var baseDate OnDate.January.The21st; var date InDate.Five.DaysFrom(baseDate); Assert.Equal(baseDate.AddDays(5), date);从源码结构看Six是 T4 模板生成的第 6 个嵌套类InDate.Six并非手写代码而是由 InDate.SomeTimeFrom.tt 这个 T4 文本模板在编译期生成生成结果即 InDate.SomeTimeFrom.cs。模板用一个for循环遍历 1 到 10#for (var i 1; i 10; i){ var plural i 1 ? s : ; var day Day plural; var week Week plural; var month Month plural; var year Year plural; # public static class # i.ToWords().Dehumanize() # { public static DateOnly # day # DateOnly.FromDateTime(DateTime.UtcNow.AddDays(# i #)); // ...Weeks / Months / Years 同理 } #}#也就是说仓库里One、Two、Three……Ten十个嵌套类的 120 个成员10 类 × 12 成员全部来自同一份模板Six只是i 6的展开结果类名Six由6.ToWords().Dehumanize()生成ToWords将 6 转为 sixDehumanize转为 PascalCase 的SixDay(s)/Week(s)/Month(s)/Year(s)属性名由plural拼接规则生成i 1时统一使用复数形式因此Six的成员名为Days、Weeks、Months、Years注意One类中使用单数Day/Week/Month/YearInDate.SomeTimeFrom.cs周偏移在模板中直接写成i * 7所以Six.Weeks展开为AddDays(42)。整个文件被#if NET6_0_OR_GREATER包裹InDate.SomeTimeFrom.cs因为DateOnly类型从 .NET 6 才开始提供——这意味着InDate.Six只能在 .NET 6 及以上目标框架中使用这是硬性前提。在 FluentDate 家族中的定位InDate是一个public partial class由多个源文件共同拼装InDate.cs、InDate.SomeTimeFrom.cs、InDate.Months.cs 等可用的成员包括月份属性与方法InDate.January当年 1 月 1 日、InDate.JanuaryOf(2009)指定年份 1 月 1 日、InDate.TheYear(2009)指定年份 1 月 1 日见 InDate.cs由 InDate.Months.tt 模板生成相对日期嵌套类InDate.OneInDate.Ten即Six所在的位置姊妹类型OnDate每月某天如OnDate.January.The21st、InDateTime版相对日期、OnDateTime版每月某天对应源码 OnDate.Days.cs、In.SomeTimeFrom.cs、On.Days.cs。这些 API 的完整行为契约都由 GeneratedFluentDateTests.cs 中的反射测试统一守护任何成员缺失或偏移错误都会导致测试失败。实战建议与限制框架版本InDate.Six依赖DateOnly务必确认项目TargetFramework为net6.0或更高否则无法编译时区属性以 UTC 为基准若业务上需要本地日期的 6 天后建议先取DateOnly.FromDateTime(DateTime.Now)再调用DaysFrom(date)这类方法避免 UTC 与本地日期的跨日偏差不可变与线程安全属性和方法均为static纯函数除时间源外无共享状态可安全用于并发环境可读性收益在领域代码、测试固件或定时任务中InDate.Six.MonthsFrom(signDate)比裸的signDate.AddMonths(6)更具表达力且与 Humanizer 文档Humanizer.InDate.Six.md中记录的 API 契约一一对应方便团队检索和引用。参考文件索引API 文档Humanizer.InDate.Six.md生成源码Six类定义InDate.SomeTimeFrom.csT4 生成模板InDate.SomeTimeFrom.tt父类定义InDate.cs反射式行为测试GeneratedFluentDateTests.cs手写语义测试InDateTests.cs赞分享开发工具【免费下载链接】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 InDate.Six 详解用 DateOnly 流畅表达「六天后 / 六周后 / 六月后 / 六年后」的日期计算Humanizer InDate.Six 详解用 DateOnly 流畅表达「六天后 / 六周后 / 六月后 / 六年后」的日期计算 导读 InDate.Si开发工具Humanizer InDate.Ten 详解用 DateOnly 流式 API 计算 10 天/周/月/年后的日期Humanizer InDate.Ten 详解用 DateOnly 流式 API 计算 10 天/周/月/年后的日期 InDate.Ten 是 Humaniz开发工具CloudTunes架构揭秘Python后端与CoffeeScript前端的完美结合CloudTunes架构揭秘Python后端与CoffeeScript前端的完美结合 CloudTunes是一款基于Web的云音乐播放器它能够无缝整合You开发工具上一篇Medium-Editor Insert Plugin 使用教程下一篇Electron-sample-apps 打印功能详解从网页内容到系统打印的完整流程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表