新闻详情

新闻详情

首页 / 资讯中心 / 详情

Humanizer 的 IFormatter 接口:多语言数字、日期与时间单位格式化的本地化核心

发布时间:2026/9/29 2:24:31来源:尧图网络
Humanizer 的 IFormatter 接口:多语言数字、日期与时间单位格式化的本地化核心
开发工具【免费下载链接】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点击查看免费下载导读IFormatter是 Humanizer 中负责本地化格式化的核心接口当你的语言对数字、日期、时长和数据单位存在复杂的语法规则时例如罗马尼亚语中 5 days 是 5 zile 而 24 days 是 24 de zile阿拉伯语中 2 days 是 يومين 而不是 2 يوم就需要通过该接口获取符合目标语言习惯的字符串。阅读完本文你将掌握IFormatter的全部 8 个方法签名与语义、Humanizer 内部的默认实现与注册机制以及如何基于源码路径定位任意语言的格式化逻辑。为什么需要 IFormatter语言规则差异是本地化的真正难点数字、日期和单位的本地化远不止翻译单词这么简单。以原文档给出的两个例子为证罗马尼亚语数字与名词之间存在介词de的插入规则5 days 写作 5 zile而 24 days 写作 24 de zile阿拉伯语名词存在单数、双数、复数等语法形态2 days 使用双数形式 يومين而不是 2 يوم。这类规则无法用简单的字符串替换表覆盖因此 Humanizer 抽象出IFormatter接口把给定一个时间单位、时态或数据单位返回目标语言对应的短语这一职责统一封装并由DefaultFormatter及基于声明式规则生成的ProfiledFormatter提供实现。IFormatter 接口全貌接口定义位于 src/Humanizer/Localisation/Formatters/IFormatter.cs其注释明确说明其职责是本地化 Humanizer 的数字、日期、时长和单位格式化。完整方法如下方法签名用途关键参数string DateHumanize_Now()返回现在的本地化文本无string DateHumanize_Never()返回从未发生的本地化文本无string DateHumanize(TimeUnit, Tense, int)返回相对日期短语如 2 days ago时间单位、过去/未来时态、数量string TimeSpanHumanize_Zero()返回零时长短语无string TimeSpanHumanize(TimeUnit, int, bool toWords false)返回时长短语时间单位、数量、是否用文字表达数字string TimeSpanHumanize_Age()返回年龄后缀格式无string DataUnitHumanize(DataUnit, double, bool toSymbol true)返回数据单位符号或全称数据单位、数量、是否输出符号string TimeUnitHumanize(TimeUnit)返回时间单位的符号时间单位方法中涉及的枚举均定义在源码中TimeUnitMillisecond、Second、Minute、Hour、Day、Week、Month、Year、TenseFuture、Past、DataUnit覆盖Bit、Byte到Exabyte、Pebibyte以及显式单位系统的DecimalKilobyte等 24 个取值。各方法详解DateHumanize_Now / DateHumanize_Never固定短语这两个无参方法分别返回当前时刻与永不的本地化文本。在 DefaultFormatter 实现 中它们直接读取生成好的短语表public virtual string DateHumanize_Now() phraseTable.DateNow ?? now; public virtual string DateHumanize_Never() phraseTable.DateNever ?? never;当某个语言未提供对应短语时会回退到英文的now/never。从源码结构可以推断短语数据来自按语言生成的LocalePhraseTable由LocalePhraseTableCatalog.Resolve(culture)解析见 DefaultFormatter.cs。DateHumanize(TimeUnit, Tense, int)相对日期短语这是DateHumanize扩展方法如DateTime.Humanize()最终调用的核心方法负责把2 天前、3 小时后这类语义转成目标语言string DateHumanize(Humanizer.TimeUnit timeUnit, Humanizer.Tense timeUnitTense, int unit);参数含义timeUnit描述的时间单位天、小时、月……timeUnitTense引用发生在过去Past还是未来Futureunit单位的数量。接口 XML 文档注明当timeUnit不受支持或unit为负数时会抛出ArgumentOutOfRangeException。底层实现TryFormatDateFromPhraseTable会依次处理零值输出 now、数量为 1 的单数形态、数量为 2 的精确双数模板再按复数规则渲染多数量短语见 DefaultFormatter.cs。TimeSpanHumanize(TimeUnit, int, bool toWords)时长短语string TimeSpanHumanize(Humanizer.TimeUnit timeUnit, int unit, bool toWordsfalse);toWords参数决定数字是否用文字输出例如英文下TimeSpanHumanize(Day, 2)输出 2 days而toWords: true时输出 two days。实现中FormatCountValue会根据toWords选择走NumberToWords数字转文字且支持按单位性别调用number.ToWords(gender, culture)见 ProfiledFormatter.cs还是直接输出数字字符串。数量为 1 时优先使用单数形态toWords为真时还会优先选用专门的单数文字变体SingleWordsVariant否则渲染复数/多数量形态见 DefaultFormatter.cs。TimeSpanHumanize_Zero零时长返回零时长0 秒的本地化文本默认实现为phraseTable.TimeSpanZero ?? no time见 DefaultFormatter.cs。仅在TimeSpanHumanize的toWords为真且数量为 0 时被使用。TimeSpanHumanize_Age年龄后缀该方法返回把已 humanize 的时长字符串转换为年龄表达的格式。原文档给出的英文示例是该格式添加 old 后缀使 40 years 变成 40 years old。默认实现返回短语表中的TimeSpanAge缺失时回退为{0}即原样输出见 DefaultFormatter.cs。因此各语言可以定义自己的年龄后缀模板例如英文{0} old。DataUnitHumanize(DataUnit, double, bool toSymbol)数据单位string DataUnitHumanize(Humanizer.DataUnit dataUnit, double count, bool toSymboltrue);toSymbol决定输出符号如KB还是完整单词如kilobyte。该方法是ByteSize.ToString()等字节格式化功能的本地化出口——在 ByteSize.cs 中字节对象会通过Configurator.GetFormatter(culture)拿到当前文化的 formatter然后对Exabyte、Petabyte、Gigabyte……逐个调用DataUnitHumanize(DataUnit.XXX, xxxBytes, toSymbol)来拼接本地化字符串。默认实现中若某语言缺少 Petabyte、Exabyte 或二进制单位Kibibyte 等的短语会回退到英文 formatter 处理见 DefaultFormatter.cs。TimeUnitHumanize(TimeUnit)时间单位符号返回给定时间单位的本地化符号例如英文的s、m、h、d。默认实现从短语表读取Symbol缺失则抛出InvalidOperationException见 DefaultFormatter.cs。该符号常用于TimeSpanHumanizeWithFractionalSeconds这类需要紧凑输出如 1.5s的场景。注册机制IFormatter 是如何被选中的所有 formatter 通过FormatterRegistry注册到Configurator.Formatters见 Configurator.cs。默认注册逻辑见 FormatterRegistry.csclass FormatterRegistry : LocaliserRegistryIFormatter { public FormatterRegistry() : base(c new DefaultFormatter(c)) FormatterRegistryRegistrations.Register(this); }LocaliserRegistryIFormatter的默认工厂为所有文化创建DefaultFormatter而FormatterRegistryRegistrations.Register(this)会为特殊语言覆盖更精确的实现如ProfiledFormatter。日常调用链是DateHumanize/TimeSpanHumanize/ByteSize.ToString等扩展方法 →Configurator.GetFormatter(culture)见 Configurator.cs→ 按当前线程文化解析出IFormatter实例 → 调用对应方法。DefaultFormatter支持两种构造方式传入CultureInfo或直接传入 locale 代码字符串如en后者内部通过new CultureInfo(localeCode)构造见 DefaultFormatter.cs。语言特异性规则的源码级原理复数形态检测器ProfiledFormatter对于阿拉伯语、俄语、波兰语、斯洛文尼亚语等复数规则复杂的语言ProfiledFormatter根据 YAML locale 数据生成的FormatterProfile选择不同的FormatterNumberDetectorKind检测器见 ProfiledFormatter.csSingularPlural1 用单数其余用复数ArabicLike1 单数、2 双数、3–10 复数、其余默认ArabicCardinal按% 100区分 few3–10与 many11–99形态Between2And4Paucal2–4 使用少量数paucal形态Polish以 2–4 结尾12–14 除外用 paucalSlovenian2 用双数、3–4 用 paucalRussian/Lithuanian使用各自的语法数字检测器。形态枚举FormatterNumberForm提供Zero、Singular、Dual、Paucal、Plural、Many、Default七种形态见 ProfiledFormatter.cs短语表据此解析出正确的词形。罗马尼亚语 de 介词罗马尼亚语的de介词规则在ShouldUseRomanianPreposition中实现当数字模 100 小于 1 或大于 19 时即非 1–19 的整数范围需要插入de见 ProfiledFormatter.cs因此才有 5 zile 与 24 de zile 的区别。卢森堡语的 Eifeler 规则卢森堡语则应用 EifelerRule.cs 判断数字文字后的辅音是否触发n后缀省略由FormatterSecondaryPlaceholderMode.LuxembourgishEifelerN模式驱动见 ProfiledFormatter.cs。性别感知的数字转文字某些语言的时间单位有语法性别。ProfiledFormatter通过UnitGenders字典把TimeUnit映射到GrammaticalGender转换数字文字时调用number.ToWords(gender, culture)见 ProfiledFormatter.cs。如何自定义实现 IFormatter当目标语言无法用声明式规则覆盖时可以实现IFormatter的 8 个方法并将其注册进Configurator.Formatters。从DefaultFormatter的结构看DefaultFormatter.cs它同时实现了IGrammaticalCaseTimeSpanFormatter以支持带语法格的时长短语俄语、立陶宛语等且该接口对派生自DefaultFormatter的自定义类有显式实现要求GetType().Assembly与DefaultFormatter程序集不一致时会抛出NotSupportedException见 DefaultFormatter.cs。这意味着如果需要语法格支持自定义类必须显式实现IGrammaticalCaseTimeSpanFormatter而不能仅依赖基类。建议的自定义路径优先继承DefaultFormatter或直接注册基于 YAML 生成的ProfiledFormatter新增语言通常只需添加 locale 数据见 ProfiledFormatter.cs 的注释只有规则极其特殊时才手写IFormatter实现。小结IFormatter是 Humanizer 本地化能力的抽象边界8 个方法分别覆盖相对日期、时长、年龄、数据单位与时间单位符号DefaultFormatter提供基于短语表的通用实现ProfiledFormatter通过声明式 profile 承载各语言的复数、介词、性别与词形规则而Configurator.Formatters注册表负责按文化解析出正确的实例。理解这一接口你就掌握了 Humanizer 所有 Humanize 系列扩展方法DateTime.Humanize()、TimeSpan.Humanize()、ByteSize.ToString()等最终输出多语言文本的完整链路。赞分享开发工具【免费下载链接】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 IFormatter 接口深度解析多语言日期、时间跨度与数据单位的本地化格式化Humanizer IFormatter 接口深度解析多语言日期、时间跨度与数据单位的本地化格式化 IFormatter 是 Humanizer 本地化体系中开发工具Humanizer 本地化格式化核心接口 IFormatter 完全解析多语言日期、时长与数据单位的可扩展格式化契约Humanizer 本地化格式化核心接口 IFormatter 完全解析多语言日期、时长与数据单位的可扩展格式化契约 IFormatter 是 Humaniz开发工具Humanizer IFormatter 接口全解析多语言数字、日期与时长的本地化格式化机制Humanizer IFormatter 接口全解析多语言数字、日期与时长的本地化格式化机制 导读 IFormatter 是 Humanizer 本地化体系的开发工具上一篇QtScrcpy安卓投屏与键鼠映射10分钟上手下一篇Audacity 免费音频编辑完整指南5 步从录音到成品创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

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

较早相关资讯

最新相关资讯

Handy 离线语音转文字:5分钟上手指南 2026/9/29 3:15:41

Handy 离线语音转文字:5分钟上手指南

Handy 离线语音转文字:5分钟上手指南 【免费下载链接】Handy A free, open source, and extensible speech-to-text application that works completely offline. 项目地址: https://gitcode.com/GitHub_Trending/handy11/Handy 开会赶不上记笔记&#xff0c…

阅读更多 →
Mapbox 是什么:从在线地图到机器人、车端与空间智能的地理位置平台 2026/9/29 3:15:41

Mapbox 是什么:从在线地图到机器人、车端与空间智能的地理位置平台

1. 理解 Mapbox Mapbox 是一个面向开发者和企业的地理位置平台。它提供地图渲染、地图样式设计、地理编码、地点搜索、路径规划、导航、交通数据、边界数据、移动数据、离线部署等能力,开发者可以通过 API、SDK 和 Mapbox Studio 把这些能力集成到 Web、移动 App、…

阅读更多 →
Jupytext 实战指南:用 MyST Markdown 承载 Go 语言(GoNB)Notebook 2026/9/29 3:15:41

Jupytext 实战指南:用 MyST Markdown 承载 Go 语言(GoNB)Notebook

开发工具 【免费下载链接】jupytext Jupyter Notebooks as Markdown Documents, Julia, Python or R scripts 项目地址: https://gitcode.com/gh_mirrors/ju/jupytext 点击查看 免费下载 摘要 本指南以 Jupytext 仓库中的 Go 语言 Notebook 转换样例为核心&#x…

阅读更多 →
MySQL+Redis缓存一致性深度剖析:从「先更新DB再删缓存」到Canal+MQ生产兜底方案 2026/9/29 3:15:41

MySQL+Redis缓存一致性深度剖析:从「先更新DB再删缓存」到Canal+MQ生产兜底方案

前言 Cache Aside(旁路缓存)模式下,先更新数据库、再删除缓存是互联网最通用的读写方案。很多同学只知道这套流程,却忽略一个致命风险:删除缓存操作失败怎么办?网络抖动、Redis宕机、超时异常,都…

阅读更多 →
SpringMVC请求参数接收全解析:从@RequestParam到@RequestBody的底层原理与实战 2026/9/29 3:15:41

SpringMVC请求参数接收全解析:从@RequestParam到@RequestBody的底层原理与实战

接手过不少半路出家的SpringMVC项目,也面试过很多候选人,我发现在“请求参数接收”这块,真正能讲透、遇到问题能快速定位的人还真不多。多数人停留在“会用RequestParam和RequestBody”的阶段,但对参数到底是怎么从HTTP请求走到Co…

阅读更多 →
BepInEx 从零安装:15 分钟跑通 Unity 模组框架 2026/9/29 3:15:34

BepInEx 从零安装:15 分钟跑通 Unity 模组框架

BepInEx 从零安装:15 分钟跑通 Unity 模组框架 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx BepInEx 是面向 Unity Mono、IL2CPP 和 .NET 游戏的插件框架&#xff0c…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉