ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Humanizer 中的 PrecisionDateTimeOffsetHumanizeStrategy:可控制精度阈值的 DateTimeOffset 人性化时间距离算法

Humanizer 中的 PrecisionDateTimeOffsetHumanizeStrategy:可控制精度阈值的 DateTimeOffset 人性化时间距离算法 开发工具【免费下载链接】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 的PrecisionDateTimeOffsetHumanizeStrategy类展开讲解它如何通过一个precision精度系数把两个DateTimeOffset之间的时间差近似为几分钟前/几天后/2 个月前这样的自然语言表述。读完本文你将掌握该策略类的完整 API 契约、精度系数在底层取整算法中的具体作用、如何通过Configurator将它接入DateTimeOffset.Humanize扩展方法以及官方单元测试对关键行为的验证方式。一、类定位精度型距离时间计算器PrecisionDateTimeOffsetHumanizeStrategy是 Humanizer 用于计算两个时间点之间距离distance of time in words的精度型策略类。它的官方 API 参考页位于 PrecisionDateTimeOffsetHumanizeStrategy API 文档文档对其的定性是Precision-based calculator for distance between two times该类的声明形态如下摘自 API 文档public class PrecisionDateTimeOffsetHumanizeStrategy : Humanizer.DateTimeHumanizeStrategy.IDateTimeOffsetHumanizeStrategy它继承自System.Object并实现 IDateTimeOffsetHumanizeStrategy 接口。该接口的唯一职责是为DateTimeOffset.Humanize计算两个日期之间的时间距离以自然语言表示public interface IDateTimeOffsetHumanizeStrategy { string Humanize(DateTimeOffset input, DateTimeOffset comparisonBase, CultureInfo? culture); }接口的实现可以在仓库源码中直接核对IDateTimeOffsetHumanizeStrategy.cs。从源码结构看IDateTimeOffsetHumanizeStrategy一共有两个内置实现构成一组可替换的算法策略策略类算法特征DefaultDateTimeOffsetHumanizeStrategy默认策略采用固定的经验阈值500 毫秒、60 秒、90 分钟、24 小时、28 天等不做可配置近似PrecisionDateTimeOffsetHumanizeStrategy本文主题所有取整阈值均由precision系数按比例缩放可统一调节进位的激进程度二、完整 API 面构造器与 Humanize 方法2.1 构造器PrecisionDateTimeOffsetHumanizeStrategy(double)构造器签名与 API 文档一致public PrecisionDateTimeOffsetHumanizeStrategy(double precision 0.75);precisiondouble默认值0.75近似精度系数precision of approximation。文档说明if not provided, 0.75 will be used as a default precision即不传参时按 0.75 使用。该值在实例内部被保存为一个只读字段后续每次Humanize调用都使用构造时确定的同一个精度系数实例本身不随调用改变行为。在仓库当前源码中该类使用 C# 主构造器参数声明实现非常薄全部逻辑委托给共享算法类见 PrecisionDateTimeOffsetHumanizeStrategy.cspublic class PrecisionDateTimeOffsetHumanizeStrategy(double precision .75) : IDateTimeOffsetHumanizeStrategy { readonly double precision precision; /// summary /// Returns localized amp; humanized distance of time between two dates; given a specific precision. /// /summary public string Humanize(DateTimeOffset input, DateTimeOffset comparisonBase, CultureInfo? culture) DateTimeHumanizeAlgorithms.PrecisionHumanize(input.UtcDateTime, comparisonBase.UtcDateTime, precision, culture); }这里有一个关键细节策略把input和comparisonBase都转换为UtcDateTime再做比较。也就是说时间戳本身的 UTC 偏移量offset不参与距离计算两个带不同 offset 但指向同一瞬间的时间点会被视为零距离。这一点在 DateTimeOffsetHumanizeTests.cs 的PrecisionStrategy_DifferentOffsets用例中得到验证两个相差 7.5 小时的 offset 的DateTimeOffset被正确比较。命名空间提示2.13.14 版本 API 文档中标注该类位于Humanizer.DateTimeHumanizeStrategy命名空间而在当前仓库源码PrecisionDateTimeOffsetHumanizeStrategy.cs与 API 审批基线文件PublicApiApprovalTest.Approve_Public_Api.DotNet8_0.verified.txt中该类与接口均已归属Humanizer根命名空间。如果你的项目引用的是 2.13.14 或更旧的包版本引用时请按对应版本的命名空间书写。2.2Humanize(DateTimeOffset, DateTimeOffset, CultureInfo)方法public string Humanize(DateTimeOffset input, DateTimeOffset comparisonBase, CultureInfo? culture);参数类型含义inputSystem.DateTimeOffset要人性化的人机可读目标时间点comparisonBaseSystem.DateTimeOffset比较基准时间点现在或任意锚点cultureSystem.Globalization.CultureInfo输出使用的语言文化传null时按运行时文化解析返回值System.String本地化、人性化的时间距离短语如6 hours ago、tomorrow、2 months ago该方法同时实现了接口IDateTimeOffsetHumanizeStrategy.Humanize见 API 文档的 Implements 段落。input大于comparisonBase时结果为未来时态Tense.Future如 from now否则为过去时态Tense.Past如 ago。三、precision参数如何驱动底层算法策略类本身只是一个外壳真正决定输出文本的算法在 DateTimeHumanizeAlgorithms.cs 中。Humanize的调用链为PrecisionDateTimeOffsetHumanizeStrategy.Humanize→ 取input.UtcDateTime/comparisonBase.UtcDateTime→ DateTimeHumanizeAlgorithms.PrecisionHumanize(DateTime, DateTime, double, CultureInfo)用Math.Abs(comparisonBase.Ticks - input.Ticks)构造TimeSpan差值并根据input comparisonBase判定Tense→ 私有PrecisionHumanize(TimeSpan, Tense, double, CultureInfo)执行下面这一级级联的阈值进位计算。从源码结构看精度系数参与每一级单位进位的判定阈值均为单位上限 × precisionDateTimeHumanizeAlgorithms.cs判定条件以精度系数p表示效果ts.Milliseconds 999 * pseconds 1seconds 59 * pminutes 1minutes 59 * phours 1hours 23 * pdays 1days 30 * p days 31months 131 days 365 * pfactor floor(days / 30)months days 30 * (factor p) ? factor 1 : factordays 365 * p days 366years 1days 365factor floor(days / 365)years days 365 * (factor p) ? factor 1 : factor理解precision数值含义的关键系数越大进位阈值越低结果越偏向向上取整。以默认值p 0.75为例59 × 0.75 44.25即某一级剩余 45 秒就会被进位为 1 分钟23 × 0.75 17.25即 18 小时即会被表述为 1 天a day30 × 0.75 22.5即 23 天即被表述为 1 个月。进位完成后算法按大单位优先的顺序选取第一个非零单位作为输出years → months → days → hours → minutes → seconds全为 0 时输出毫秒级刚刚短语并调用Configurator.GetFormatter(culture).DateHumanize(TimeUnit, Tense, count)生成最终本地化文本。这意味着输出短语会随culture切换语言且完全由IFormatter决定措辞如英文中 1 天差值是 a day ago / tomorrow 这类特化表达。与DefaultHumanize固定阈值算法见 DateTimeHumanizeAlgorithms.cs的差别在于默认策略的阈值是写死的经验值TotalMilliseconds 500、TotalSeconds 120、TotalDays 28等且月份换算使用29.5天/月、365天/年的除数精度策略则把所有边界都收敛到同一个可调系数p上语义更一致、行为更可预测。四、接入方式通过Configurator.DateTimeOffsetHumanizeStrategyHumanizer 的策略模式入口是 Configurator/// summary /// The strategy to be used for DateTimeOffset.Humanize /// /summary public static IDateTimeOffsetHumanizeStrategy DateTimeOffsetHumanizeStrategy { get; set; } new DefaultDateTimeOffsetHumanizeStrategy();DateTimeOffset.Humanize扩展方法DateHumanizeExtensions.cs并不直接内置算法而是委托给该全局策略public static string Humanize(this DateTimeOffset input, DateTimeOffset? dateToCompareAgainst null, CultureInfo? culture null) { var comparisonBase dateToCompareAgainst ?? DateTimeOffset.UtcNow; return Configurator.DateTimeOffsetHumanizeStrategy.Humanize(input, comparisonBase, culture); }因此切换到精度策略的完整用法是using Humanizer; using System.Globalization; // 1) 在应用启动时把 DateTimeOffset 的人性化策略替换为精度策略 Configurator.DateTimeOffsetHumanizeStrategy new PrecisionDateTimeOffsetHumanizeStrategy(0.75); // 2) 之后所有 DateTimeOffset.Humanize 调用都走精度算法 var baseTime new DateTimeOffset(2015, 7, 4, 5, 0, 0, TimeSpan.Zero); var inputTime new DateTimeOffset(2015, 7, 5, 4, 0, 0, TimeSpan.Zero); Console.WriteLine(inputTime.Humanize(baseTime)); // tomorrow Console.WriteLine(((DateTimeOffset?)null).Humanize()); // never // 也可以不经过扩展方法直接调用策略实例便于测试与 A/B 对比 var strategy new PrecisionDateTimeOffsetHumanizeStrategy(0.75); var a new DateTimeOffset(2019, 1, 27, 0, 0, 0, TimeSpan.Zero); var b new DateTimeOffset(2019, 3, 29, 0, 0, 0, TimeSpan.Zero); Console.WriteLine(strategy.Humanize(a, b, CultureInfo.InvariantCulture)); // 2 months agoConfigurator的文档注释对该属性有明确的工程约束见 Configurator.cs 的remarks该属性应只在应用启动阶段、任何人性化操作发生之前设置一次多线程环境下读取时应考虑可见性volatile 或同步生产环境中不建议在开始对外服务后再更换策略实例。上述代码示例应遵循这一约束编写。五、单元测试给出的行为证据DateTimeOffsetHumanizeTests.cs 为精度策略提供了多组可直接复现的行为基线测试类统一使用[UseCulture(en-US)]跨日跨时区场景PrecisionStrategy_SameOffset2015-07-05 04:00Z相对2015-07-04 05:00Z差值 23 小时。由于23 23 × 0.75 17.25触发小时→天进位最终输出tomorrowDateTimeOffsetHumanizeTests.cs。不同 offset 场景PrecisionStrategy_DifferentOffsets02:00与-05:00两个 offset 下的时间点差值为 6 小时 15 分钟输出6 hours ago验证了按UtcDateTime比较、offset 不影响结果的实现路径DateTimeOffsetHumanizeTests.cs。月份区间取整PrecisionStrategy_TwoMonthsAroundSixtyDays以2019-03-29为基准2019-01-27/28/29差 57~59 天三种输入均输出2 months ago。这正对应算法中factor floor(days / 30) 1、且days 30 × (1 0.75) 52.5时取factor 1 2的分支DateTimeOffsetHumanizeTests.cs。本地化回归Humanize_UsesSpecifiedCulture以多语言MemberData批量断言1 天前与2 天前的输出与Configurator.GetFormatter(culture).DateHumanize(...)完全一致验证了策略对culture参数的透传行为DateTimeOffsetHumanizeTests.cs。可空重载Never/Nullable_ExpectSameDateTimeOffset?为null时输出never非空可空值与直接调用结果一致DateTimeOffsetHumanizeTests.cs。以上用例说明精度策略的输出是确定性的——只要precision、两个时间点与culture固定输出即可复现这对测试与产品文案对齐都很友好。六、选型建议与适用边界结合源码与测试证据可以给出如下实践要点何时使用当你希望时间距离表述遵循一套统一的近似比例例如统一按 75% 阈值向上取整而不是默认策略里 500 毫秒/120 秒/90 分钟这类分散的经验阈值时切换到PrecisionDateTimeOffsetHumanizeStrategy更合适它同样适合作为 A/B 测试基线或自定义算法的参照实现。精度的调节方向precision增大 → 各级进位提前表述更整precision减小 → 表述更保守、更接近原始差值。默认值 0.75 是官方文档与测试用例共同使用的取值未经验证前不建议改动其含义假设。输出只取单一单位算法只输出最大非零单位如 2 天 3 小时会输出 2 days ago 而不是 2 days 3 hours ago这是精度策略与某些多单位时间格式化方案的本质区别。偏移量语义比较始终基于 UTC 时刻UtcDateTime跨时区数据可以直接比较无需手动转换。线程与初始化约束Configurator.DateTimeOffsetHumanizeStrategy的文档明确要求启动时设置一次如需按请求切换精度建议直接使用new PrecisionDateTimeOffsetHumanizeStrategy(p).Humanize(...)调用策略实例而不是改写全局属性。本文引用的核心文件策略实现、算法核心、全局配置、扩展方法入口 与 行为测试可沿这些路径继续深入阅读。赞分享开发工具【免费下载链接】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点击查看免费下载相关推荐open-code-review 接入 MCP 服务器扩展代码审查 Agent 的上下文与工具能力open code review 接入 MCP 服务器扩展代码审查 Agent 的上下文与工具能力 本文以 open code review 的 MCPMo开发工具Humanizer 中 DefaultDateTimeOffsetHumanizeStrategy 源码解析DateTimeOffset 相对时间人性化默认策略Humanizer 中 DefaultDateTimeOffsetHumanizeStrategy 源码解析DateTimeOffset 相对时间人性化默认策开发工具Humanizer PrecisionDateOnlyHumanizeStrategy 详解为 DateOnly 相对时间定制精确阈值Humanizer PrecisionDateOnlyHumanizeStrategy 详解为 DateOnly 相对时间定制精确阈值 本文围绕 Humani开发工具上一篇终极MoneyPrinter前端交互设计Web界面操作全解析下一篇PaddleGAN终极教程用MPRNet实现专业级图像去模糊与去噪创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表