
开发工具【免费下载链接】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.Localisation.TimeUnit是 Humanizer 库中定义时间单位的最小公共语言它将毫秒、秒、分钟、小时、天、周、月、年这 8 个时间粒度固化为一个枚举并作为桥梁连接日期人性化DateHumanize、时间跨度人性化TimeSpanHumanize、单位符号转换ToSymbol与多语言本地化格式化器。本文以该枚举为骨架结合 TimeUnit.cs 源码、TimeSpanHumanizeExtensions.cs 算法与 TimeUnitToSymbolExtensions.cs 扩展方法完整讲解其定义、底层调用链、本地化机制与实战用法。读完本文你将掌握如何用maxUnit/minUnit精确控制人性化输出的粒度理解月/年近似计算的边界并能把时间单位转成任意文化的符号形式。一、TimeUnit 枚举定义与字段速查1.1 官方 API 定义关联文档给出的 API 签名与字段数值如下public enum TimeUnit字段数值含义Millisecond0一毫秒Second1一秒Minute2一分钟Hour3一小时Day4一天Week5一周Month6一月Year7一年1.2 源码中的完整实现仓库中的实际定义位于 TimeUnit.cs与文档完全一致且每个成员都带有明确的 XML 文档注释。该枚举直接驻留在Humanizer.Localisation命名空间下其设计意图从源码注释可见一斑Represents the time units supported by Humanizers relative-time and duration formatters.也就是说TimeUnit是 Humanizer 相对时间relative-time与时长duration格式化两大功能线的公共枚举。它的取值顺序从小到大本身就构成了算法遍历的优先级基础——在 TimeSpanHumanizeExtensions.cs 中库通过Enumerable.Reverse(Enum.GetValuesTimeUnit())得到一个从大到小排列的单位数组用于从最大单位开始逐级拆解时间跨度static readonly TimeUnit[] TimeUnits [.. Enumerable.Reverse(Enum.GetValuesTimeUnit())];这一细节说明枚举成员的声明顺序不是随意的它直接参与算法的单位降序遍历逻辑。二、TimeUnit 在人性化算法中的三大核心应用TimeUnit本身不携带行为它的价值体现在被各大扩展方法消费的调用链中。以下是它最核心的三个应用场景。2.1 TimeSpan.Humanize用 maxUnit / minUnit 控制输出粒度TimeSpan.Humanize是时长人性化的主入口其签名见 TimeSpanHumanizeExtensions.cs中两个直接以TimeUnit为类型的参数决定了输出的上下边界public static string Humanize( this TimeSpan timeSpan, int precision 1, CultureInfo? culture null, TimeUnit maxUnit TimeUnit.Week, TimeUnit minUnit TimeUnit.Millisecond, string? collectionSeparator , , bool toWords false)参数语义来自源码 XML 注释maxUnit最大单位默认TimeUnit.Week输出中允许出现的最大时间单位。默认值为Week意味着TimeSpan.FromDays(400).Humanize()不会直接输出 1 year而是落到以周为最大刻度的表达。特别要注意Month与Year一旦被选为maxUnit它们对大跨度超过 30 天时间的计算是近似值——按一年 365.2425 天、一个月 30.4369 天折算源码常量见 TimeSpanHumanizeExtensions.csconst double DaysInAYear 365.2425; // 格里高利历 const double DaysInAMonth DaysInAYear / 12;minUnit最小单位默认TimeUnit.Millisecond输出中允许出现的最小时间单位。例如要忽略毫秒级噪声可设minUnit: TimeUnit.Second。算法在GetTimeUnitPartTimeSpanHumanizeExtensions.cs中按timeUnitToGet maximumTimeUnit timeUnitToGet minimumTimeUnit过滤单位随后用switch表达式按单位类型拆解数值毫秒取Timespan.Milliseconds、天/周/月/年走各自的特殊大小写分支见GetTimeUnitNumericalValueTimeSpanHumanizeExtensions.cs。实测示例对应 TimeSpanHumanizeTests.cs 的TimeSpanWithMaxTimeUnit测试TimeSpan.FromMilliseconds(2_016_000_000).Humanize(maxUnit: TimeUnit.Year); // 例如输出 3 weeks当 maxUnit 为 Week 时 // 或 1 month 级别的近似表达当 maxUnit 为 Month/Year 时配合precision参数可输出多段组合例如Humanize(precision: 4, culture: culture, maxUnit: TimeUnit.Year)见 TimeSpanHumanizeTests.cs。2.2 日期人性化DefaultHumanize 的分级阈值在相对日期算法 DateTimeHumanizeAlgorithms.cs 中TimeUnit是每个判断分支的返回值标签。DefaultHumanize(TimeSpan, ...)内部以一系列阈值阶梯决定输出哪个单位时间跨度条件输出单位TotalMilliseconds 500TimeUnit.Millisecond0 毫秒即 nowTotalSeconds 60TimeUnit.SecondTotalSeconds 120TimeUnit.Minute1 分钟TotalMinutes 60TimeUnit.MinuteTotalMinutes 90TimeUnit.Hour1 小时TotalHours 24TimeUnit.HourTotalHours 48TimeUnit.DayTotalDays 7TimeUnit.DayTotalDays 28TimeUnit.WeekTotalDays ∈ [28, 30)且同年同月TimeUnit.MonthTotalDays 345TimeUnit.Month按floor(days / 29.5)折算其余TimeUnit.Year按floor(days / 365)折算每次判定后算法调用formatter.DateHumanize(TimeUnit.X, tense, count)把枚举传给格式化器由本地化层生成具体短语如 a minute ago / in 3 days。Tense过去/未来与TimeUnit一起决定了短语的最终形态。该算法同样服务于DateTime、DateTimeOffset、DateOnly、TimeOnly四种类型的人性化入口见 DateHumanizeExtensions.cs。2.3 单位符号ToSymbol 扩展方法TimeUnitToSymbolExtensions.cs 提供了把时间单位转成符号的单行入口public static string ToSymbol(this TimeUnit unit, CultureInfo? culture null) Configurator.GetFormatter(culture).TimeUnitHumanize(unit);对应的 en-US 实测输出由 TimeUnitToSymbolTests.cs 固化TimeUnitToSymbol()en-USTimeUnit.MillisecondmsTimeUnit.SecondsTimeUnit.MinuteminTimeUnit.HourhTimeUnit.DaydTimeUnit.WeekweekTimeUnit.MonthmoTimeUnit.Yeary基于此HumanizeToSymbols扩展见 TimeSpanHumanizeExtensions.cs可以把整个 TimeSpan 输出为紧凑符号串例如1h 30min其内部正是对每个TimeUnit部件调用TimeUnitHumanize获取本地化符号后拼接FormatTimePart中的string.Concat(amount, cultureFormatter.TimeUnitHumanize(timeUnit))见 TimeSpanHumanizeExtensions.cs。三、本地化机制TimeUnit 如何走向 100 语言TimeUnit的另一个身份是本地化短语表的键。默认格式化器 DefaultFormatter.cs 通过LocalePhraseTable由源码生成器从 YAML 生成的短语表为每个文化解析短语核心方法有三个DateHumanize(TimeUnit timeUnit, Tense timeUnitTense, int unit)——相对日期短语TimeSpanHumanize(TimeUnit timeUnit, int unit, bool toWords false)——时长短语TimeUnitHumanize(TimeUnit timeUnit)——单位符号。它们统一定义在 IFormatter.cs 接口中任何自定义格式化器都必须实现。从TimeUnit到本地化文本的映射源头是各语言的 YAML 文件例如 en.yml 中relativeDate段为每个past/future×TimeUnit组合配置了单数/复数短语past: minute: single: a minute ago multiple: afterCount: ago forms: singular: minute default: minutes仓库Locales/目录下包含 100 余个 yml如 zh-CN、ja、de、ru、ar 等这些文件经Humanizer.SourceGenerators编译期生成LocalePhraseTableCatalog从而让TimeUnit枚举值在不同的CultureInfo下产出完全不同的文本。这正是 Humanizer meets all your .NET needs for … dates, times, timespans 多语言能力的底层实现路径。对于需要语法格grammatical case的语言如匈牙利语、芬兰语、马拉雅拉姆语TimeUnit还参与IGrammaticalCaseTimeSpanFormatter接口的格变体解析DefaultFormatter.cs可见该枚举贯穿了从最基础的符号输出到最复杂的形态学本地化。四、进阶用法与注意事项4.1 以 TimeUnit 为参数的完整调用组合Humanize的完整形态TimeSpanHumanizeExtensions.cs允许同时控制精度、空单位计数与文化timeSpan.Humanize( precision: 2, countEmptyUnits: false, culture: new CultureInfo(zh-CN), maxUnit: TimeUnit.Year, minUnit: TimeUnit.Second, collectionSeparator: , toWords: false);precision最多返回的单位数默认 1只返回最大单位countEmptyUnits是否把数值为 0 的中间单位也计入precision前导空单位永远不计collectionSeparator多段输出的连接符为 null 时使用文化默认的集合格式化器。4.2 ToAge 与符号模式的单位边界TimeSpan.ToAge(...)TimeSpanHumanizeExtensions.cs默认maxUnit TimeUnit.Year把时长转成 40 years old 式的年龄表达HumanizeToSymbols/HumanizeToSymbolsWithFractionalSeconds同样接受TimeUnit边界参数其中小数秒模式要求maxUnit落在TimeUnit.Second与TimeUnit.Year之间否则抛ArgumentOutOfRangeExceptionValidateFractionalSecondArgumentsTimeSpanHumanizeExtensions.cs。4.3 需要留意的三点边界事实月与年的近似性默认maxUnit TimeUnit.Week时不会触发月/年近似只有显式把maxUnit设为Month/Year大跨度时间才会按 365.2425 天/年、30.4369 天/月的固定比率折算源码注释明确说明这是 approximations。符号与词的差异toWords为 true 时单位前的数字转为文字如 one day且部分语言为词模式提供独立的短语变体SingleWordsVariant/MultipleWordsVariant见 DefaultFormatter.cs。枚举顺序即算法顺序TimeUnit的成员声明顺序被Enum.GetValues直接消费新增单位时需谨慎调整拆解算法GetTimeUnitNumericalValue的 switch与其保持一致。五、可验证的源码与测试指引想要在本地深入验证上述行为可直接阅读与运行以下文件枚举定义src/Humanizer/Localisation/TimeUnit.cs符号扩展与测试src/Humanizer/TimeUnitToSymbolExtensions.cs、tests/Humanizer.Tests/TimeUnitToSymbolTests.cs时长算法src/Humanizer/TimeSpanHumanizeExtensions.cs、tests/Humanizer.Tests/TimeSpanHumanizeTests.cs日期算法src/Humanizer/DateTimeHumanizeStrategy/DateTimeHumanizeAlgorithms.cs、tests/Humanizer.Tests/DateHumanize.cs本地化短语源src/Humanizer/Locales/en.yml及同目录其他语言的 yml在测试项目中直接运行dotnet test tests/Humanizer.Tests/Humanizer.Tests.csproj --filter FullyQualifiedName~TimeUnitToSymbolTests即可复现文中符号映射表--filter FullyQualifiedName~TimeSpanWithMaxTimeUnit可验证maxUnit边界行为。理解TimeUnit这一最小枚举就等于拿到了解读 Humanizer 全部时间人性化能力的钥匙。赞分享开发工具【免费下载链接】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 的 TimeUnit 枚举支撑相对时间、时长与速率本地化格式化的时间单位体系Humanizer 的 TimeUnit 枚举支撑相对时间、时长与速率本地化格式化的时间单位体系 导读 TimeUnit 是 Humanizer 库中定义时间开发工具Humanizer 时间单位体系TimeUnit详解枚举定义、符号映射与本地化机制Humanizer 时间单位体系TimeUnit详解枚举定义、符号映射与本地化机制 TimeUnit 是 Humanizer 中用于描述相对时间与时间跨度开发工具Humanizer 的 Tense 枚举深入解析过去与未来时态在 .NET 时间人性化中的定位与用法Humanizer 的 Tense 枚举深入解析过去与未来时态在 .NET 时间人性化中的定位与用法 导读 Tense 是 Humanizer 本地化Loc开发工具上一篇openEuler内存与存储管理GMEM内存池与HSAK高效存储解决方案的完整指南 下一篇5个实用技巧用Rprocps-ng提升你的Linux系统管理效率创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考