新闻详情

新闻详情

首页 / 资讯中心 / 详情

Humanizer PrecisionDateTimeHumanizeStrategy 详解:用 precision 因子精确控制“时间距离”人文化的阈值

发布时间:2026/9/26 3:09:24来源:尧图网络
Humanizer PrecisionDateTimeHumanizeStrategy 详解:用 precision 因子精确控制“时间距离”人文化的阈值
开发工具【免费下载链接】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点击查看免费下载导读PrecisionDateTimeHumanizeStrategy是 Humanizer 提供的“基于精度的两时间点距离计算器”它通过一个可配置的precision因子默认 0.75把毫秒、秒、分钟、小时、天、月、年等时间单位的进位阈值整体前移从而让DateTime.Humanize()输出的相对时间短语如yesterday、an hour ago、2 months ago更贴合业务需要的“渐进感”。读完本文你将掌握该策略的构造方式、Humanize方法签名、底层进位算法的数学原理、如何通过Configurator在启动时全局切换策略以及它在DateTimeOffset、DateOnly、TimeOnly上的对应实现。类概述它是什么PrecisionDateTimeHumanizeStrategy位于Humanizer.DateTimeHumanizeStrategy命名空间官方注释将其定义为 Precision-based calculator for distance between two times基于精度的两个时间点之间距离的计算器。它直接实现策略接口IDateTimeHumanizeStrategy类声明如下public class PrecisionDateTimeHumanizeStrategy(double precision .75) : IDateTimeHumanizeStrategy来源PrecisionDateTimeHumanizeStrategy.cs其继承关系为System.Object→PrecisionDateTimeHumanizeStrategy并实现 IDateTimeHumanizeStrategy 接口。该接口本身极其精简只约定了一个方法public interface IDateTimeHumanizeStrategy { string Humanize(DateTime input, DateTime comparisonBase, CultureInfo? culture); }来源IDateTimeHumanizeStrategy.cs这意味着任何实现了该接口的类型都可以挂进Configurator.DateTimeHumanizeStrategy而PrecisionDateTimeHumanizeStrategy就是官方提供的“带精度调节”实现之一。构造函数唯一的参数precision策略的构造函数只接收一个可选参数public PrecisionDateTimeHumanizeStrategy(double precision 0.75);参数说明参数类型默认值含义precisiondouble0.75逼近近似进位的精度因子未提供时使用 0.75 作为默认精度构造函数通过主构造函数primary constructor语法把precision存入只读字段readonly double precision precision;见 PrecisionDateTimeHumanizeStrategy.cs后续所有计算都围绕这个因子展开。从实现细节看precision的取值范围虽然没有显式校验但根据算法逻辑下文会推导其合理语义区间是(0, 1]附近——它表示“一个单位被判定为已满并进位时实际需要达到该单位完整值的比例”。取值越小越早进位取 1 时约等于按完整单位严格进位。Humanize 方法把两个 DateTime 之间的距离变成一句话策略通过实现接口方法完成人文化输出public string Humanize(System.DateTime input, System.DateTime comparisonBase, System.Globalization.CultureInfo culture);参数语义参数类型含义inputDateTime要被“人文化”的目标时间comparisonBaseDateTime比较基准时间通常是“现在”cultureCultureInfo输出短语所使用的区域文化传null时使用当前线程文化方法本身只是薄封装真正的计算委托给DateTimeHumanizeAlgorithms.PrecisionHumanize(input, comparisonBase, precision, culture)见 PrecisionDateTimeHumanizeStrategy.cs。返回值是本地化、人文化的两时间距离文本例如英文下的yesterday、an hour ago、a month from now。底层算法precision 因子如何改变进位阈值要真正理解这个策略必须读它的算法实现 DateTimeHumanizeAlgorithms.cs。整个流程分为三步。第一步计算 TimeSpan 与时态var ts new TimeSpan(Math.Abs(comparisonBase.Ticks - input.Ticks)); var tense input comparisonBase ? Tense.Future : Tense.Past;DateTimeHumanizeAlgorithms.cs即取两时间 Tick 差值的绝对值作为间隔input晚于基准则为Tense.Futurefrom now早于基准则为Tense.Pastago。注意第一步用的是绝对差值所以算法天然是对称的。第二步从小单位向大单位逐级进位核心逻辑DateTimeHumanizeAlgorithms.cs先取出TimeSpan的Seconds、Minutes、Hours、Days分量然后自下而上判断是否进位毫秒进位秒ts.Milliseconds 999 * precision时seconds 1秒进位分钟seconds 59 * precision时minutes 1分钟进位小时minutes 59 * precision时hours 1小时进位天hours 23 * precision时days 1天进位月days 30 * precision且days 31时months 1若31 days 365 * precision则按factor floor(days / 30)计算days 30 * (factor precision)时取factor 1否则取factor天进位年days 365 * precision且days 366时years 1若days 365按factor floor(days / 365)days 365 * (factor precision)时取factor 1否则取factor。以默认precision 0.75为例几个关键阈值立刻变得“提前”进位事件严格阈值precision1 时默认阈值precision0.75毫秒 → 秒999 ms999 × 0.75 749.25 ms即 750 ms 就进 1 秒秒 → 分钟59 s59 × 0.75 44.25 s即 45 s 就进 1 分钟分钟 → 小时59 min59 × 0.75 44.25 min即 45 min 就进 1 小时小时 → 天23 h23 × 0.75 17.25 h即 18 h 就进 1 天天 → 月首月30 d30 × 0.75 22.5 d即 23 d 就进 1 个月天 → 年首年365 d365 × 0.75 273.75 d即 274 d 就进 1 年这也正是测试中45 seconds输出a minute ago、45 minutes输出an hour ago、18 hours输出yesterday、23 days输出one month ago的原因见 DateTimeHumanizePrecisionStrategyTests.cs。第三步从大单位向小单位选择输出进位计算完成后算法从大到小选择第一个非零单位交给formatter.DateHumanize(...)输出var formatter Configurator.GetFormatter(culture); if (years 0) return formatter.DateHumanize(TimeUnit.Year, tense, years); if (months 0) return formatter.DateHumanize(TimeUnit.Month, tense, months); if (days 0) return formatter.DateHumanize(TimeUnit.Day, tense, days); if (hours 0) return formatter.DateHumanize(TimeUnit.Hour, tense, hours); if (minutes 0) return formatter.DateHumanize(TimeUnit.Minute, tense, minutes); if (seconds 0) return formatter.DateHumanize(TimeUnit.Second, tense, seconds); return formatter.DateHumanize(TimeUnit.Millisecond, tense, 0);DateTimeHumanizeAlgorithms.csTimeUnit枚举覆盖Millisecond、Second、Minute、Hour、Day、Week、Month、Year共八个单位见 TimeUnit.cs。格式化阶段通过Configurator.GetFormatter(culture)解析当前文化对应的 DefaultFormatter从本地化短语表LocalePhraseTable中取出形如DateHumanize(TimeUnit.Day, Tense.Past, 1)→yesterday的本地化文本。这也解释了为什么culture参数会直接影响最终字符串如中文输出昨天、一小时前。实战接入如何全局切换并使用该策略通过 Configurator 全局配置Humanizer 的扩展方法DateTime.Humanize()最终会读取全局配置属性Configurator.DateTimeHumanizeStrategyConfigurator.cs默认值是DefaultDateTimeHumanizeStrategy。官方文档与源码注释均强调该属性应在应用启动阶段、任何 Humanize 操作发生之前设置一次并在多线程场景下注意同步见 Configurator.cs 的 remarks。仓库自带的完整可运行示例configuration/Program.cs展示了标准用法using System.Globalization; using Humanizer; #if HUMANIZER_V2 using Humanizer.Configuration; using Humanizer.DateTimeHumanizeStrategy; #endif var culture CultureInfo.GetCultureInfo(en-US); var comparison new DateTime(2025, 1, 20, 12, 0, 0, DateTimeKind.Utc); Configurator.DateTimeHumanizeStrategy new PrecisionDateTimeHumanizeStrategy(precision: 0.75); var result comparison.AddMinutes(-45).Humanize( utcDate: true, dateToCompareAgainst: comparison, culture: culture); if (result ! an hour ago) throw new InvalidOperationException($Unexpected result: {result}); Console.WriteLine(result);运行输出为an hour ago因为 45 分钟已经满足44.25分钟的最小进位阈值所以没有输出45 minutes ago而是直接进位为an hour ago。注意示例中的#if HUMANIZER_V2条件编译——在 Humanizer v2 时代Configurator与策略类型位于Humanizer.Configuration/Humanizer.DateTimeHumanizeStrategy命名空间需要显式using按当前仓库更高版本编译时无需这些额外 using。在调用点使用扩展方法配置完成后日常调用只需Humanize()扩展方法。其入口实现DateHumanizeExtensions.cs逻辑如下var comparisonBase dateToCompareAgainst ?? DateTime.UtcNow; utcDate ?? input.Kind ! DateTimeKind.Local; comparisonBase utcDate.Value ? comparisonBase.ToUniversalTime() : comparisonBase.ToLocalTime(); return Configurator.DateTimeHumanizeStrategy.Humanize(input, comparisonBase, culture);要点解读dateToCompareAgainst为null时默认以DateTime.UtcNow为基准utcDate为null时按input.Kind推断非 Local 即按 UTC 处理比较基准会根据utcDate统一转换为 UTC 或本地时间避免混用时区边界出错最终输出委托给当前配置的策略这正是“只改Configurator一处即可全局切换算法”的插件式设计。可空重载DateTime?.Humanize()在值为null时返回文化的 never 短语DateHumanize_Never()见 DateHumanizeExtensions.cs。与其他策略的关系与差异PrecisionDateTimeHumanizeStrategy是官方策略家族的一员同一目录下还有策略类实现接口特点DefaultDateTimeHumanizeStrategyIDateTimeHumanizeStrategy默认策略使用固定经验阈值如 500ms 输出 now、60s 输出秒、120s 输出 1 分钟等代码见 DateTimeHumanizeAlgorithms.csPrecisionDateTimeHumanizeStrategyIDateTimeHumanizeStrategy本文主角阈值可由precision连续调节PrecisionDateTimeOffsetHumanizeStrategyIDateTimeOffsetHumanizeStrategy面向DateTimeOffset内部先取UtcDateTime再走同一套精度算法PrecisionDateTimeOffsetHumanizeStrategy.csPrecisionDateOnlyHumanizeStrategyIDateOnlyHumanizeStrategy面向DateOnly同日返回 today 短语否则按DayNumber差值计算PrecisionDateOnlyHumanizeStrategy.csPrecisionTimeOnlyHumanizeStrategyITimeOnlyHumanizeStrategy面向TimeOnly按 Tick 差走同一精度算法PrecisionTimeOnlyHumanizeStrategy.cs两个默认策略与两个精度策略共享同一套静态算法类DateTimeHumanizeAlgorithms只是分别调用DefaultHumanize与PrecisionHumanize两条路径。默认策略是“硬编码的经验阈值”例如 2 小时内输出1 hour精度策略则把进位点数学化。官方场景文档也明确指出“默认策略选择的是熟悉的边界如 yesterday当应用需要更渐进gradual的阈值时应使用 Precision 系列策略”见 relative-dates-and-times.mdx。此外DateOnly/TimeOnly的精度策略仅在NET6_0_OR_GREATER目标框架下编译源码中有#if NET6_0_OR_GREATER守卫对应扩展方法也只在相同条件下可用DateHumanizeExtensions.cs。行为验证测试用例给出的精确边界仓库测试文件 DateTimeHumanizePrecisionStrategyTests.cs 用precision 0.75逐一锁定了边界行为可作为理解算法的手册输入期望输出Past期望输出Future749 msnownow750 msone second agoone second from now1749 msone second agoone second from now1750 ms2 seconds ago2 seconds from now44 s44 seconds ago44 seconds from now45 sa minute agoa minute from now104 sa minute agoa minute from now105 s2 minutes ago2 minutes from now17 h17 hours ago17 hours from now18 hyesterdaytomorrow41 hyesterdaytomorrow42 h2 days ago2 days from now22 d22 days ago22 days from now23 done month agoone month from now8 个月8 months ago8 months from now9 个月one year agoone year from now21 个月2 years ago2 years from now测试通过 DateHumanize.cs 的辅助方法在锁内切换Configurator.DateTimeHumanizeStrategynew PrecisionDateTimeHumanizeStrategy(precision.Value)后验证输出DateHumanize.cs并同时覆盖 UTC 与本地基准、注入固定基准日期2013-06-20 09:58:22 UTC以保证确定性DateHumanize.cs。使用注意事项结合 relative-dates-and-times.mdx 的官方提醒与源码逻辑使用时有几点需要留意时区一致性不要把本地DateTime与 UTC 基准混比。Humanize会按utcDate参数转换比较基准混用Kind可能导致边界移动。官方示例均显式传入utcDate: true与同一个 UTC 基准保证输出确定。TimeOnly缺乏日期上下文TimeOnly没有日历日期信息跨午夜比较时算法无法判断事件属于昨天还是明天应避免对需要“昨天/明天”语义的场景使用TimeOnly.Humanize()。策略切换时机Configurator.DateTimeHumanizeStrategy应在应用启动时设置一次运行期改动在多线程下有可见性与一致性风险。precision的语义它控制“进位提前量”不是输出粒度。若希望输出更保守更接近真实完整单位可把precision调高趋近 1若希望更激进地聚合成大单位则调低。默认 0.75 已在“及时进位”与“信息准确”之间取得平衡。文化差异最终短语由文化相关的Formatter渲染同一条时间差在不同CultureInfo下输出语言不同若要结果确定务必显式传入culture。综上PrecisionDateTimeHumanizeStrategy是 Humanizer 相对时间人文化体系中“可调精度”的关键一环它把进位阈值从硬编码经验值升级为precision × 单位满值的数学规则并通过Configurator一处切换即可作用于全局所有DateTime.Humanize()调用适合时间线、审计日志、通知文案等需要渐进式时间表达的 .NET 场景。赞分享开发工具【免费下载链接】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 PrecisionDateTimeHumanizeStrategy 详解用 precision 因子控制相对时间的中文/本地化 Humanize 输出Humanizer PrecisionDateTimeHumanizeStrategy 详解用 precision 因子控制相对时间的中文/本地化 Human开发工具Humanizer 高精度时间距离人类化PrecisionDateTimeHumanizeStrategy 深度解析Humanizer 高精度时间距离人类化PrecisionDateTimeHumanizeStrategy 深度解析 PrecisionDateTimeHum开发工具Humanizer 中的 PrecisionDateTimeOffsetHumanizeStrategy可控制精度阈值的 DateTimeOffset 人性化时间距离算法Humanizer 中的 PrecisionDateTimeOffsetHumanizeStrategy可控制精度阈值的 DateTimeOffset 人性化开发工具上一篇RetroBar 复古任务栏如何把 Windows 11 换成经典 XP 任务栏下一篇Unlock-Music指南浏览器内免安装解密ncm、qmc、kgm等加密音乐文件的完整教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

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

较早相关资讯

最新相关资讯

开放式代码审查:从流程设计到团队协作的实践指南 2026/9/26 3:53:54

开放式代码审查:从流程设计到团队协作的实践指南

做研发这十多年,我陆陆续续参加过上千次代码评审,也亲眼看着不少团队的 review 制度从认真到敷衍,最后变成一个“点个通过”的过场。真正让我下定决心把 open-code-review 这套机制彻底想透的,是几年前的一场线上事故:…

阅读更多 →
AI新时代下的图床管理方案:Cloudflare R2 + MCP + Skills 配置指南(含 TaoToken 统一 Key 接入) 2026/9/26 3:53:54

AI新时代下的图床管理方案:Cloudflare R2 + MCP + Skills 配置指南(含 TaoToken 统一 Key 接入)

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

阅读更多 →
openclaw 启用完整的工具集:从 config 到 gateway 打通命令执行能力 2026/9/26 3:53:54

openclaw 启用完整的工具集:从 config 到 gateway 打通命令执行能力

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

阅读更多 →
Openclaw 究竟是什么?从配置文件到 CC Switch 的完整接入 TaoToken 实践 2026/9/26 3:53:54

Openclaw 究竟是什么?从配置文件到 CC Switch 的完整接入 TaoToken 实践

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

阅读更多 →
人因交互方法配 TaoToken:从 settings.json 到 CC Switch 的配置骨架 2026/9/26 3:53:54

人因交互方法配 TaoToken:从 settings.json 到 CC Switch 的配置骨架

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

阅读更多 →
惊艳全场!带着Claude Code味儿的ChatGPT Image2发布,重构AI生图市场,重塑多行业格局 2026/9/26 3:53:47

惊艳全场!带着Claude Code味儿的ChatGPT Image2发布,重构AI生图市场,重塑多行业格局

/* 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
📞 ✉