新闻详情

新闻详情

首页 / 资讯中心 / 详情

Humanizer 流式日期 API 全解析:In.Five 类与“从现在起 5 个时间单位“的 DateTime 计算

发布时间:2026/9/25 6:57:37来源:尧图网络
Humanizer 流式日期 API 全解析:In.Five 类与“从现在起 5 个时间单位“的 DateTime 计算
开发工具【免费下载链接】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.10.1 版本文档中的 Humanizer.In.Five.md 为骨架结合仓库源码与测试系统讲解In.Five这一静态嵌套类的 14 个成员7 个属性 7 个方法的定义、底层实现基于DateTime.UtcNow的增量计算、T4 模板生成机制、DateOnly变体InDate.Five以及在实际业务代码中的典型用法。读完本文你将能够直接用In.Five.Days、In.Five.MonthsFrom(date)这类自然语言式的 API 表达相对时间并理解其语义边界UTC 基准、求值时机与适用场景。一、In.Five是什么一个说人话的相对时间计算器在 Humanizer 的 FluentDate 命名空间下In是一个静态门面类public partial class In通过一组嵌套的静态类让开发者用接近自然语言的方式计算相对时间。In.Five是其中最典型的一员它专门回答从现在起 5 秒/分钟/小时/天/周/月/年后是什么时刻以及从某个指定日期起 5 个时间单位后是什么时刻这两类问题。按文档定义In.Five的类型签名如下public static class In.Five它继承自System.Object本身没有任何实例状态全部成员均为public static因此可以在任意位置直接以In.Five.XXX的方式调用无需先实例化任何对象。整个In.Five家族共有 14 个公开成员严格分成两组7 个只读属性Seconds、Minutes、Hours、Days、Weeks、Months、Years语义均为从当前时刻起 5 个该单位后的时间7 个方法SecondsFrom(DateTime)、MinutesFrom(DateTime)、HoursFrom(DateTime)、DaysFrom(DateTime)、WeeksFrom(DateTime)、MonthsFrom(DateTime)、YearsFrom(DateTime)语义均为从传入的日期起 5 个该单位后的时间。这两组的区别正是相对 now与相对指定时刻属性以此刻为基准方法以调用者传入的DateTime为基准。二、属性成员从现在起 5 个时间单位2.1 成员清单与返回值In.Five的全部属性都返回System.DateTime语义按文档描述如下属性类型文档语义底层计算对应源码SecondsDateTime从现在起 5 秒DateTime.UtcNow.AddSeconds(5)MinutesDateTime从现在起 5 分钟DateTime.UtcNow.AddMinutes(5)HoursDateTime从现在起 5 小时DateTime.UtcNow.AddHours(5)DaysDateTime从现在起 5 天DateTime.UtcNow.AddDays(5)WeeksDateTime从现在起 5 周DateTime.UtcNow.AddDays(35)MonthsDateTime从现在起 5 个月DateTime.UtcNow.AddMonths(5)YearsDateTime从现在起 5 年DateTime.UtcNow.AddYears(5)源码位置src/Humanizer/FluentDate/In.SomeTimeFrom.cs#L365-L450 中嵌套类Five的实现与上表逐条对应。2.2 关键实现细节UTC 基准所有属性都基于DateTime.UtcNow而非DateTime.Now计算。以源码为例public static class Five { public static DateTime Seconds DateTime.UtcNow.AddSeconds(5); public static DateTime Days DateTime.UtcNow.AddDays(5); public static DateTime Weeks DateTime.UtcNow.AddDays(35); public static DateTime Years DateTime.UtcNow.AddYears(5); }由此可以得出三个对使用者很重要的结论返回值是 UTC 时间。如果你要展示给本地用户通常需要自行ToLocalTime()如果只是做服务端调度、缓存过期时间戳计算UTC 反而是更稳妥的选择不受服务器时区设置影响。求值发生在访问属性的那一刻。这些是只读计算属性每次访问都会重新取一次UtcNow并做加法不存在缓存。因此循环中反复读取In.Five.Seconds会得到逐步递增的5 秒后时间点而不是一个固定值——这是相对 now语义的自然结果。Weeks的底层是AddDays(35)即周被定义为7 天的整数倍这与AddDays/AddMonths在月末、闰年等边界上的不同行为见下文 2.3需要区分对待。2.3 各单位运算的语义差异从源码可以看到不同单位使用了不同的加法原语其行为存在细微差别Seconds/Minutes/Hours/Days直接调用AddSeconds(5)、AddMinutes(5)、AddHours(5)、AddDays(5)是纯日历刻度的线性加减无歧义WeeksAddDays(5 * 7)等价于 35 个日历天MonthsAddMonths(5).NET 规则是日期数字保持不变、月份进 5遇到目标月份天数不足时会取该月最后一天例如 1 月 31 日加 1 个月得到 2 月 28/29 日YearsAddYears(5)同样遵循 .NET 的闰日规则2 月 29 日加 1 年得到 2 月 28 日。如果你需要的是严格等长的时间跨度例如固定 30 天的会话有效期应当使用TimeSpan/AddDays体系而不是Months/Years反之如果你的语义是日历上向后推 5 个月/5 年如会员续费到 5 个月后的同一天In.Five.Months/In.Five.Years正是为这种场景设计的。三、方法成员从指定日期起 5 个时间单位3.1 成员清单与签名In.Five的 7 个方法统一接收一个System.DateTime参数date返回System.DateTime语义为从传入日期起 5 个该单位后的时间public static System.DateTime SecondsFrom(System.DateTime date); public static System.DateTime MinutesFrom(System.DateTime date); public static System.DateTime HoursFrom(System.DateTime date); public static System.DateTime DaysFrom(System.DateTime date); public static System.DateTime WeeksFrom(System.DateTime date); public static System.DateTime MonthsFrom(System.DateTime date); public static System.DateTime YearsFrom(System.DateTime date);对应的底层实现同样在 In.SomeTimeFrom.cs#L365-L450模式是传入日期 对应单位的加法原语例如public static DateTime DaysFrom(DateTime date) date.AddDays(5); public static DateTime MonthsFrom(DateTime date) date.AddMonths(5); public static DateTime YearsFrom(DateTime date) date.AddYears(5);与属性版本相比方法版本完全不受当前时刻影响是确定性的纯函数对同一个date传入任何时刻调用结果都一致。因此在需要以某个已确定的时间点为基准计算截止时间如订单支付时间 5 天退款窗口时应优先使用方法而非属性。3.2 测试中的验证方式仓库测试 tests/Humanizer.Tests/FluentDate/InTests.cs#L103-L109 给出了方法版本的经典用法与断言[Fact] public void InFiveDays() { var baseDate On.January.The21st; var date In.Five.DaysFrom(baseDate); Assert.Equal(baseDate.AddDays(5), date); }可见测试直接以baseDate.AddDays(5)作为期望值印证了DaysFrom就是对传入日期执行AddDays(5)。这也说明该类方法的可测试性很好——传入固定基准日期即可得到完全可预期的结果不依赖系统时钟。四、从源码看In.Five的生成机制4.1 一个 T4 模板生成 One~Ten 十个类In.Five并不是手写唯一的特例。查看 src/Humanizer/FluentDate/In.SomeTimeFrom.tt 可以发现In.One到In.Ten这十个数字类全部由同一个 T4 文本模板循环生成for (var i 1; i 10; i) { var plural i 1 ? s : ; // Second/Minute/Hour/Day/Week/Month/Year 的复数形式 public static class # i.ToWords().Dehumanize() # { public static DateTime # second # DateTime.UtcNow.AddSeconds(# i #); public static DateTime # second #From(DateTime date) date.AddSeconds(# i #); // ……分钟、小时、天、周、月、年同理 } }模板中的两个关键细节值得注意数字类名由 Humanizer 自身的能力生成i.ToWords().Dehumanize()会把整数 5 先转成单词 Five再用Dehumanize规范化为 PascalCase 的Five从而生成In.Five这样的类名——这正是 Humanizer 用自己的 API 生成自己的 API的典型例子单复数命名规则i 1时使用单数Second、Minute……即In.One.Secondi 1时使用复数Seconds、Minutes……即In.Five.Seconds。这解释了为什么In.One.Day而In.Five.Days的命名差异。因此本文讨论的In.Five只是这套1 到 10 的自然语言相对时间体系中数字 5 的一个实例In.Two.MonthsFrom(...)、In.Ten.Years等成员的结构与语义完全同构。4.2 同一门面类下的其他成员In类是partial的其成员分散在多个文件中src/Humanizer/FluentDate/In.cs提供In.TheYear(int year)返回指定年份的 1 月 1 日new(year, 1, 1)src/Humanizer/FluentDate/In.Months.cs提供In.January、In.February……In.December属性当月 1 日及In.JanuaryOf(int)……In.DecemberOf(int)方法src/Humanizer/FluentDate/In.SomeTimeFrom.cs即本文主角所在的文件承载One~Ten十个数字类。换句话说In家族同时覆盖绝对日期表达几月几号、某年与相对时间表达N 个时间单位之后两条路径In.Five属于后者。五、实战用法把In.Five用进业务代码5.1 结合 FluentDate 其它 API 的场景示例仓库文档示例 website/docs/_examples/scenarios-fluent-dates/Program.cs 展示了这套 FluentDate API 的典型组合用法var startingPoint new DateTime(2025, 1, 20, 9, 0, 0); var twoMonthsLater In.Two.MonthsFrom(startingPoint); var appointment In.AprilOf(2025).AddDays(2).At(14, 30);把其中的In.Two.MonthsFrom换成In.Five.MonthsFrom即得In.Five的实战姿势——以某个业务锚点时间为基准向后推算 5 个月再配合At(hour, minute)、AddDays(...)等扩展继续细化到具体时刻。5.2 常见落地场景截止时间计算订单创建时间 In.Five.DaysFrom(createdAt)作为退款/换货窗口截止点缓存与重试策略In.Five.MinutesUTC 基准直接作为缓存绝对过期时间或下次重试时刻天然规避时区问题日历语义的排期In.Five.MonthsFrom(hireDate)计算 5 个月后的评估节点享受AddMonths的同日进位、月末截断日历规则固定基准的确定性测试用In.Five.DaysFrom(fixedDate)写断言结果与系统时钟无关参见上文测试用例。5.3 使用注意点汇总注意点说明属性基于UtcNowIn.Five.Days等属性返回 UTC 时间展示给本地用户前需ToLocalTime()属性每次求值属性是计算属性多次访问结果不同不要在循环内当作常量使用方法与属性分工需要确定性结果请用XxxFrom(date)需要当下起 N 单位才用属性周 7 天Weeks实现为AddDays(35)无跨月/跨年的日历进位月/年的日历进位AddMonths/AddYears遵循 .NET 日期进位规则月末截断、闰年处理六、延伸DateOnly变体InDate.Five在 .NET 6 条件下源码以#if NET6_0_OR_GREATER保护Humanizer 还提供了面向DateOnly的InDate门面。从 src/Humanizer/FluentDate/InDate.SomeTimeFrom.cs#L318 可以看到同样存在InDate.Five嵌套类其成员模式与In.Five一致但返回值类型为DateOnly且由于DateOnly不含时间分量从源码结构看该类覆盖的是Days、Weeks、Months、Years这类日期级单位并提供DaysFrom(DateOnly)、DaysFrom(DateTime)等重载DateTime版本通过DateOnly.FromDateTime截取日期部分。如果你在纯日期场景如5 天后的日历日下工作InDate.Five比In.Five更贴切且两者 API 形态高度相似学习成本几乎为零。七、小结In.Five是 Humanizer FluentDate 体系中数字 5对应的静态门面用 7 个属性回答从现在起 5 个时间单位用 7 个方法回答从指定时刻起 5 个时间单位全部成员返回DateTime底层直接映射到DateTime.UtcNow/date的AddSeconds、AddMinutes、AddHours、AddDays、AddMonths、AddYears周换算为AddDays(35)。它由 In.SomeTimeFrom.tt T4 模板批量生成与In.One~In.Ten共用一套命名与实现模式并有 InTests.cs 等测试用例覆盖其行为。理解UTC 基准每次求值属性 vs 方法这三组语义差异你就能在调度、截止时间、排期等场景中准确、自信地使用这套自然语言式日期 API。赞分享开发工具【免费下载链接】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 深度解析In.Ten 类——从从现在起 10 个时间单位到确定性日期计算的完整用法Humanizer 流畅日期 API 深度解析In.Ten 类——从从现在起 10 个时间单位到确定性日期计算的完整用法 Humanizer 的流畅日期开发工具Humanizer FluentDate 指南使用 In.Seven 计算“从现在起 7 个时间单位”与“距指定日期 7 个时间单位”的日期Humanizer FluentDate 指南使用 In.Seven 计算“从现在起 7 个时间单位”与“距指定日期 7 个时间单位”的日期 导读 本篇技术指开发工具Humanizer 的 In.Nine 类用 Fluent API 表达从现在起 9 个时间单位之后的日期Humanizer 的 In.Nine 类用 Fluent API 表达从现在起 9 个时间单位之后的日期 In.Nine 是 Humanizer Flu开发工具上一篇【免费下载】 银河麒麟系统下WPS卸载安装手册一步到位的办公软件管理下一篇TestNG集成测试指南与Maven、Gradle、Spring框架的完美结合创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Atlas 300V 24G推理加速卡实战:从CANN部署到YOLOv5全流程解析 2026/9/25 7:36:22

Atlas 300V 24G推理加速卡实战:从CANN部署到YOLOv5全流程解析

老早之前就有朋友问我,为啥现在边缘AI项目里越来越多人在聊Atlas 300V这张卡,它到底是不是一张正经的“运算加速卡”。热搜词里同时挂着“atlas部署yolo”和“atlas 300v 24g 是运算加速卡吗”,这两问题其实问到了同一个点上:这卡…

阅读更多 →
Atlas 300V实战:昇腾推理卡部署YOLOv8全流程与性能调优 2026/9/25 7:36:22

Atlas 300V实战:昇腾推理卡部署YOLOv8全流程与性能调优

前阵子同事丢给我一个链接,问“atlas这个卡到底怎么样,能不能用来跑YOLO”。我一看,这里说的不是那个数据库中间件Apache Atlas,而是昇腾的Atlas 300V推理卡,带24G显存的版本。那段时间我的检索记录里也高频出现“atla…

阅读更多 →
高云FPGA在线逻辑分析仪GLA实战指南 2026/9/25 7:36:22

高云FPGA在线逻辑分析仪GLA实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
2026我的AI开发工具链全公开:TaoToken统一Key接入Cursor与Claude的config.toml骨架 2026/9/25 7:36:15

2026我的AI开发工具链全公开:TaoToken统一Key接入Cursor与Claude的config.toml骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
谷歌浏览器Axure插件安装与白屏排查:从开发者模式到文件访问权限 2026/9/25 7:36:15

谷歌浏览器Axure插件安装与白屏排查:从开发者模式到文件访问权限

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
开源软件低成本实用推荐:选型方法论与避坑指南 2026/9/25 7:36:15

开源软件低成本实用推荐:选型方法论与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉