- 开发工具
【免费下载链接】Humanizer
Humanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities
导读
ResourceKeys.DateHumanize是 Humanizer 本地化体系中的一个核心工具类,它按照既定命名约定为DateTime.Humanize(日期人性化)输出生成资源键。理解这一机制,你就能明白 Humanizer 如何把"3 分钟前""2 天后"这样的相对时间短语翻译成 100 多种语言的文案,也能够在自定义 Formatter 或调试本地化问题时直接利用这些键。本文围绕该类展开,结合仓库源码与测试,梳理其字段、方法约定、调用链和自定义实践。
类概览:静态的"键约定"封装
在 version-2.14.1 API 文档 中,该类型被定义为:
public static class ResourceKeys.DateHumanize它是一个public static class,不继承任何业务基类,继承链仅为System.Object。类的职责正如其 XML 注释所述:"Encapsulates the logic required to get the resource keys for DateTime.Humanize"——即封装为日期人性化获取资源键所需的一切逻辑。
从整体架构看,它位于 Humanizer 本地化(Localisation)子系统的"键生成"层:
- 消费方:
DefaultFormatter等 IFormatter 实现,它们把资源键与具体本地化文本关联; - 生成方:
ResourceKeys.DateHumanize提供约定式的键字符串; - 数据源:各个 Locale 的 YAML 短语表(见 src/Humanizer/Locales)。
字段:两个固定的常量资源键
该类暴露两个public const string字段,它们对应日期人性化中最特殊的两种状态——"从未发生"与"此时此刻":
| 字段 | 常量值 | 语义 |
|---|---|---|
ResourceKeys.DateHumanize.Never | "DateHumanize_Never" | 表示事件从未发生(如null日期)的文案键 |
ResourceKeys.DateHumanize.Now | "DateHumanize_Now" | 表示当前时刻的文案键 |
两者的字段类型都是System.String。这两个键在 Humanizer 中形成了稳定的公共契约:IFormatter接口就定义了对应的两个方法DateHumanize_Never()与DateHumanize_Now()(见 IFormatter.cs),DefaultFormatter则在 DefaultFormatter.cs 中实现:
public virtual string DateHumanize_Now() => phraseTable.DateNow ?? "now"; public virtual string DateHumanize_Never() => phraseTable.DateNever ?? "never";也就是说,键名DateHumanize_Now/DateHumanize_Never与IFormatter的方法名一一对应,这正是"约定"的体现。当某个 Locale 的短语表中缺少对应短语时,DefaultFormatter会回退到英文默认值"now"与"never";多语言实现则由生成的 Locale 短语表提供,例如日语短语表中DateHumanize_Now对应 "今"、泰米尔语对应 "இப்போது"、斯瓦希里语对应 "ugbu a"(见 GeneratedFormatterRuntimeTests.cs)。
方法:GetResourceKey 的约定生成规则
GetResourceKey是类的核心方法,原型为:
public static string GetResourceKey( Humanizer.Localisation.TimeUnit timeUnit, Humanizer.Localisation.Tense timeUnitTense, int count = 1);三个参数的语义
timeUnit(TimeUnit):时间单位枚举,包含Millisecond、Second、Minute、Hour、Day、Week、Month、Year八个取值;timeUnitTense(Tense):时态枚举,Future表示未来(如 "in 2 days"),Past表示过去(如 "2 days ago");count:单位数量,int类型,默认值为 1(文档中注明 "default is One")。
返回值的命名约定
方法返回形如DateHumanize_SingleMinuteAgo的资源键。将返回值反推即可还原出完整的命名规则:
DateHumanize_ + <单复数前缀> + <时间单位> + <时态后缀>其中:
- 单复数前缀:
count为 1 时使用Single,大于 1 时使用复数形式(如Multiple); - 时间单位:取自
TimeUnit枚举名(如Minute、Hour、Day); - 时态后缀:
Tense.Past对应Ago,Tense.Future对应FromNow。
例如GetResourceKey(TimeUnit.Minute, Tense.Past, 1)生成DateHumanize_SingleMinuteAgo;GetResourceKey(TimeUnit.Day, Tense.Future, 5)则会生成类似DateHumanize_MultipleDaysFromNow的键。这种命名约定让每个相对时间短语都拥有稳定、可预测、可调试的标识符,也使得本地化短语表(如 en.yml)中的条目能够按键名自动映射。
在 Humanize 调用链中的位置
要理解ResourceKeys.DateHumanize的价值,需要看清整条相对时间生成链路。以DateTime.Humanize()为例,入口是 DateHumanizeExtensions.cs:
- 计算对比基准(默认
DateTime.UtcNow),交由Configurator.DateTimeHumanizeStrategy处理; - 策略层(如 DefaultDateTimeHumanizeStrategy)调用 DateTimeHumanizeAlgorithms.cs 中的算法,把时间差换算成"单位 + 时态";
- 算法最终调用
formatter.DateHumanize(timeUnit, tense, count)(见 DateTimeHumanizeAlgorithms.cs),由DefaultFormatter从短语表取词渲染(DefaultFormatter.cs); - 短语表条目即由
GetResourceKey这类约定键进行组织与查找。
特殊情况下,null的DateTime?会走DateHumanize_Never()返回 "never" 类文案(DateHumanizeExtensions.cs),这正是Never字段对应的场景;当时间差不足 500ms 时,算法直接以TimeUnit.Millisecond渲染"此刻"语义(DateTimeHumanizeAlgorithms.cs),对应Now字段的场景。
测试与公共 API 契约
该类型作为公共 API 被 PublicApiApprovalTest 锁定在多个目标框架的 verified 文件中(如 DotNet10_0.verified.txt 中的DateHumanize_Never()与DateHumanize_Now()方法签名),任何签名变更都会在 CI 中被捕获。此外,GeneratedFormatterRuntimeTests.cs 和 CoverageGapTests.cs 会逐一验证各 Locale 的DateHumanize_Now/DateHumanize_Never输出,以及英文回退值"now"、"never",确保"键 → 多语言文案"映射不会出现缺口。
实践要点
- 调试本地化缺失:当某个语言缺少相对时间短语时,
DefaultFormatter会抛出InvalidOperationException,其中包含 Culture 名与单位信息(DefaultFormatter.cs)。此时可利用GetResourceKey生成期望的键,再到 src/Humanizer/Locales 对应 yml 中核对条目是否存在。 - 扩展自定义 Formatter:若继承
DefaultFormatter实现自定义本地化,应遵循DateHumanize_*键名约定命名短语条目,保证与IFormatter接口方法及短语表解析逻辑兼容。 - 了解回退行为:缺少短语时默认回退英文 "now"/"never",因此对外呈现永远有兜底文案,不会返回空字符串。
小结
ResourceKeys.DateHumanize用两个常量字段与一个静态方法,把DateTime.Humanize的资源键约定固化成了可复用的公共 API:Never/Now覆盖两种特殊状态,GetResourceKey则按"单复数 + 单位 + 时态"的统一约定为常规相对时间生成键。它与IFormatter、DefaultFormatter及 Locale 短语表共同构成了 Humanizer 日期人性化本地化的完整链路,是阅读和扩展该模块时最值得优先理解的入口之一。
- 开发工具
【免费下载链接】Humanizer
Humanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities
相关推荐
Humanizer 日期人性化资源键深入解析:ResourceKeys.DateHumanize 的命名约定、生成逻辑与本地化机制
Humanizer 日期人性化资源键深入解析:ResourceKeys.DateHumanize 的命名约定、生成逻辑与本地化机制 ResourceKeys.D
开发工具Humanizer 本地化资源键详解:理解 ResourceKeys.DateHumanize 及其在日期人性化中的核心作用
Humanizer 本地化资源键详解:理解 ResourceKeys.DateHumanize 及其在日期人性化中的核心作用 本文围绕 Humanizer 中
开发工具Humanizer 本地化资源键机制解析:ResourceKeys.TimeSpanHumanize 与 GetResourceKey 深入指南
Humanizer 本地化资源键机制解析:ResourceKeys.TimeSpanHumanize 与 GetResourceKey 深入指南 Resourc
开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考