ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Humanizer 的 DefaultTimeOnlyHumanizeStrategy 深度解析:TimeOnly 相对时间人性化转换原理与实战指南

Humanizer 的 DefaultTimeOnlyHumanizeStrategy 深度解析:TimeOnly 相对时间人性化转换原理与实战指南 开发工具【免费下载链接】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点击查看免费下载DefaultTimeOnlyHumanizeStrategy是 Humanizer 中把TimeOnly时刻之间的差值转成自然语言如 12 hours from now、4 hours ago的默认策略类。本文以该 API 文档为主体结合仓库中的源码与测试完整讲解其方法签名、参数语义、底层分级换算算法、扩展方法调用链、配置替换方式与本地化输出机制帮助你理解并驾驭 Humanizer 的TimeOnly.Humanize全流程。类概览默认的 distance of time 计算器根据 API 文档该类的定位是 The default distance of time - words calculator即把两个时刻之间的距离换算成词语的默认计算器。其完整声明如下public class DefaultTimeOnlyHumanizeStrategy : Humanizer.ITimeOnlyHumanizeStrategy从继承与实现关系看继承自System.Object实现了 ITimeOnlyHumanizeStrategy 接口接口文档的说明明确指出实现该接口即可为TimeOnly.Humanize创建新策略并可通过Configurator.TimeOnlyHumanizeStrategy接入配置。需要特别注意的是在源码实现中整个类被#if NET6_0_OR_GREATER条件编译指令包裹。这是因为TimeOnly类型自 .NET 6 才引入因此该类以及整个ITimeOnlyHumanizeStrategy接口族只在 .NET 6 及以上目标框架下可用使用前请确认项目的目标框架。该类没有自定义构造函数与状态是一个极其轻量的策略实现核心逻辑全部委托给算法层。Humanize 方法方法签名、参数与返回值DefaultTimeOnlyHumanizeStrategy暴露的唯一方法是HumanizeAPI 文档给出的签名为public string Humanize(System.TimeOnly input, System.TimeOnly comparisonBase, System.Globalization.CultureInfo? culture);各参数语义如下参数类型含义inputTimeOnly要被人性化转换的时刻目标时刻comparisonBaseTimeOnly比较基准时刻用于计算与input的距离cultureCultureInfo?输出使用的区域文化null时使用当前线程的 CultureInfo返回值是string即两个时刻之间距离的本地化文字表述。方法实现了ITimeOnlyHumanizeStrategy.Humanize(TimeOnly, TimeOnly, CultureInfo)接口约定。从源码可以看到该方法的实现只有一行public string Humanize(TimeOnly input, TimeOnly comparisonBase, CultureInfo? culture) DateTimeHumanizeAlgorithms.DefaultHumanize(input, comparisonBase, culture);也就是说DefaultTimeOnlyHumanizeStrategy本身是薄壳真正的算法在 DateTimeHumanizeAlgorithms 的DefaultHumanize(TimeOnly, TimeOnly, CultureInfo)方法中。底层算法DefaultHumanize 的分级换算原理要真正理解这个策略必须深入 DateTimeHumanizeAlgorithms.cs 中针对TimeOnly的重载public static string DefaultHumanize(TimeOnly input, TimeOnly comparisonBase, CultureInfo? culture) { var tense input comparisonBase ? Tense.Future : Tense.Past; var ts new TimeSpan(Math.Abs(comparisonBase.Ticks - input.Ticks)); return DefaultHumanize(ts, true, 0, tense, culture); }这里有两个关键步骤时态Tense判定通过input comparisonBase判断目标时刻是否晚于基准时刻。晚于则标记为Tense.Future输出形如 in 2 hours 或英文的 2 hours from now否则标记为Tense.Past输出形如 2 hours ago。Tense枚举定义在 Tense.cs包含Future与Past两个成员。时间差计算用Math.Abs(comparisonBase.Ticks - input.Ticks)取两个TimeOnly的 Ticks 差绝对值构造一个不带日期部分的TimeSpan。注意这里对TimeOnly的差异只取绝对值不跨日期累计不会因为 昨天 23:00 到今天 01:00 就得到 2 天并且sameMonth参数固定传true、days固定传0这正是TimeOnly语义纯时刻、无日期在算法中的体现。随后进入核心的 DefaultHumanize(TimeSpan, bool, int, Tense, CultureInfo) 私有重载它像一个阈值阶梯从最小的单位开始逐级放大判断直到落入第一个满足条件的区间。整个判断链如下判断条件按顺序触发单位输出示例en-USPast 时态TotalMilliseconds 500Millisecond数量 0nowTotalSeconds 60Second数量ts.Secondsx seconds agoTotalSeconds 120Minute数量 1a minute agoTotalMinutes 60Minute数量ts.Minutesx minutes agoTotalMinutes 90Hour数量 1an hour agoTotalHours 24Hour数量ts.Hoursx hours agoTotalHours 48Day数量daysyesterday 一类表述TotalDays 7Day数量ts.Daysx days agoTotalDays 28Week数量ts.Days / 7x weeks agoTotalDays ∈ [28, 30)Month同月或 Daya month ago / x days agoTotalDays 345Month数量Floor(TotalDays / 29.5)x months ago其余情况Year数量Floor(TotalDays / 365)最小为 1x years ago几个值得注意的实现细节最小输出为 now当差值小于 500 毫秒时直接走TimeUnit.Millisecond且数量为 0 的分支经格式化器输出 now见 DefaultFormatter.cs 的DateHumanize_Now与DateHumanize_Today的短语表回退逻辑约一的模糊处理TotalSeconds 120输出 1 minute、TotalMinutes 90输出 1 hour这是借鉴 Stack Overflow 经典相对时间算法的近似策略源码注释中也保留了该出处链接月份换算系数 29.5TotalDays 345时按月均 29.5 天取整折算月份是纯时刻场景下对月的一种近似处理。最终算法调用Configurator.GetFormatter(culture)获取对应文化的格式化器再按TimeUnit枚举定义见 TimeUnit.cs含 Millisecond 到 Year 共 8 个成员、Tense与数量unit调用formatter.DateHumanize(...)完成短语渲染与本地化。扩展方法入口TimeOnly.Humanize 的完整调用链DefaultTimeOnlyHumanizeStrategy平时并不会被直接调用而是由扩展方法间接触发。在 DateHumanizeExtensions.cs 中定义了TimeOnly.Humanize入口public static string Humanize(this TimeOnly input, TimeOnly? timeToCompareAgainst null, bool useUtc true, CultureInfo? culture null) { var comparisonBase timeToCompareAgainst ?? TimeOnly.FromDateTime(useUtc ? DateTime.UtcNow : DateTime.Now); return Configurator.TimeOnlyHumanizeStrategy.Humanize(input, comparisonBase, culture); }该扩展方法的关键点timeToCompareAgainst比较基准null时默认取当前时刻useUtc当基准为null时决定取 UTC 当前时刻默认true还是本地时刻false通过TimeOnly.FromDateTime从DateTime提取纯时刻部分culture为null时使用当前线程文化真正执行时读取的是Configurator.TimeOnlyHumanizeStrategy属性而该属性默认值正是new DefaultTimeOnlyHumanizeStrategy()见下文配置一节。此外还有一个可空版本的重载 Humanize(this TimeOnly?)当TimeOnly?为null时不会抛异常而是返回本地化的 never通过formatter.DateHumanize_Never()实现。ITimeOnlyHumanizeStrategy接口本身定义在 ITimeOnlyHumanizeStrategy.cs签名与文档一致是实现自定义策略时必须遵循的契约。策略可插拔Configurator 与 Precision 策略对比DefaultTimeOnlyHumanizeStrategy只是默认实现Humanizer 通过 Configurator.cs 暴露了可替换的配置点public static ITimeOnlyHumanizeStrategy TimeOnlyHumanizeStrategy { get; set; } new DefaultTimeOnlyHumanizeStrategy();Configurator.TimeOnlyHumanizeStrategy属性默认被初始化为DefaultTimeOnlyHumanizeStrategy你可以在应用启动阶段替换成任意自定义的ITimeOnlyHumanizeStrategy实现。Configurator的 XML 注释明确提示该属性应在应用启动时只设置一次多线程场景下访问需注意线程安全使用 volatile 读取或合适的同步机制生产环境不应在服务运行后再变更。仓库内置的另一套策略是 PrecisionTimeOnlyHumanizeStrategy它与默认策略的核心区别在于对比项DefaultTimeOnlyHumanizeStrategyPrecisionTimeOnlyHumanizeStrategy算法入口DefaultHumanize固定阈值阶梯PrecisionHumanize基于精度参数的近似换算构造参数无double precision .75默认精度 0.75换算方式按毫秒/秒/分/时/日的硬编码阈值分级用precision参与各单位的进位判断如seconds 59 * precision则分钟进位适用场景大多数场景的默认选择需要控制近似程度的精度敏感场景精度策略的源码PrecisionHumanize分支位于 DateTimeHumanizeAlgorithms.cs其先计算TimeSpan差值与时态再进入带精度的单位换算逻辑。API 文档中PrecisionTimeOnlyHumanizeStrategy的说明同样可以在 Humanizer.PrecisionTimeOnlyHumanizeStrategy.md 查到。测试验证行为示例与边界保障仓库测试文件 TimeOnlyHumanizeTests.cs使用en-US文化直接验证了默认策略的行为可作为理解输出的权威参考// 同一时刻 - now var inputTime new TimeOnly(13, 07, 05); var baseTime new TimeOnly(13, 07, 05); inputTime.Humanize(baseTime); // now // 未来方向12 小时差 - 12 hours from now new TimeOnly(13, 08, 05).Humanize(new TimeOnly(1, 08, 05)); // 12 hours from now // 过去方向4 小时差 - 4 hours ago new TimeOnly(13, 07, 02).Humanize(new TimeOnly(17, 07, 05)); // 4 hours ago测试覆盖的关键点还包括文化敏感性Humanize_UsesSpecifiedCulture理论测试遍历所有已发布 locale验证culture参数生效——输出由Configurator.GetFormatter(culture).DateHumanize(TimeUnit.Minute, Tense.Future, 1)产生可空语义null的TimeOnly?调用Humanize()返回 never非空时与直接调用TimeOnly.Humanize()结果一致多策略并行隔离StrategiesAreIsolatedAcrossParallelCultures测试在同一时刻用不同线程、不同文化en-US/fr、fr/is并发执行默认策略与精度策略PrecisionTimeOnlyHumanizeStrategy(0.5)验证不同策略在不同文化下互不串扰分别产出 12 hours from now 与 demain。本地化输出从数值到短语的最后一公里DefaultTimeOnlyHumanizeStrategy计算出的只是单位 数量 时态这些中间结果最终的人类可读短语由格式化器渲染。在 DefaultFormatter.cs 中public virtual string DateHumanize(TimeUnit timeUnit, Tense timeUnitTense, int unit) TryFormatDateFromPhraseTable(timeUnit, timeUnitTense, unit, out var result) ? result : throw new InvalidOperationException(...);DefaultFormatter通过LocalePhraseTable由仓库中的 yml 语言资源与 SourceGenerator 生成的短语表驱动查找对应文化、单位、时态的单数/复数形式并用{count}、{prep}等占位符模板完成拼装见 DefaultFormatter.cs 的TryFormatDateFromPhraseTable与RenderCountedPhrase。这正是12 hours from now 在 en-US、而其他语言会输出各自语法结构的原因。实战小结何时使用、如何扩展综合以上分析使用DefaultTimeOnlyHumanizeStrategy的实战要点如下直接使用大多数情况下无需显式引用该类直接调用someTime.Humanize(comparisonBase, culture: ...)即可内部默认走该策略显式调用需要绕过扩展方法、直接获取策略时可new DefaultTimeOnlyHumanizeStrategy().Humanize(input, comparisonBase, culture)自定义策略实现ITimeOnlyHumanizeStrategy并在应用启动时赋值给Configurator.TimeOnlyHumanizeStrategy即可替换默认行为需要近似精度控制时可直接选用PrecisionTimeOnlyHumanizeStrategy(precision)框架前提由于依赖TimeOnly全部相关类型仅在NET6_0_OR_GREATER下编译可用文化输出始终记得culture参数为null时采用当前线程文化跨区域部署时建议显式传入目标CultureInfo以保证输出一致。通过本篇文章你已完整掌握DefaultTimeOnlyHumanizeStrategy从接口契约、方法签名到阈值算法、调用链、配置替换与本地化渲染的整个闭环可以直接在项目中使用或扩展 Humanizer 的TimeOnly.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点击查看免费下载相关推荐Humanizer 中 DefaultTimeOnlyHumanizeStrategy 源码解读TimeOnly 相对时间人性化的默认策略实现Humanizer 中 DefaultTimeOnlyHumanizeStrategy 源码解读TimeOnly 相对时间人性化的默认策略实现 本文围绕开发工具Humanizer 的 DefaultTimeOnlyHumanizeStrategy 详解TimeOnly 相对时间人文化的默认策略与源码剖析Humanizer 的 DefaultTimeOnlyHumanizeStrategy 详解TimeOnly 相对时间人文化的默认策略与源码剖析 导读 本文围开发工具Humanizer 中的 DefaultTimeOnlyHumanizeStrategy 详解TimeOnly 时间差人性化措辞的默认计算策略Humanizer 中的 DefaultTimeOnlyHumanizeStrategy 详解TimeOnly 时间差人性化措辞的默认计算策略 Default开发工具上一篇淘金币自动化脚本10 分钟 5 步配好每天省下 20 分钟下一篇一个 ini 文件调双风扇TPFanCtrl2 完整上手指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表