首页/新闻资讯/正文详情

Humanizer 的 IDateToOrdinalWordConverter 接口:定制本地化日期序数词转换的完整指南

发布时间:2026/9/25 4:34:26 来源:云帆数科 栏目:资讯中心
Humanizer 的 IDateToOrdinalWordConverter 接口:定制本地化日期序数词转换的完整指南
开发工具【免费下载链接】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点击查看免费下载导读IDateToOrdinalWordConverter是 Humanizer 中负责把DateTime转换为本地化序数词日期Ordinal Words的公开接口是ToOrdinalWords()扩展方法背后的本地化契约。本文以该接口为中心完整讲解它的两个方法签名、参数语义并深入src/Humanizer的源码实现——从默认转换器、模式化转换器到配置注册表与调用链最后给出自定义实现并接入 Humanizer 配置体系的完整方案帮助你掌握如何在多语言场景下精确控制日期序数词的输出格式。接口概览本地化ToOrdinalWords的契约IDateToOrdinalWordConverter位于命名空间Humanizer.Localisation.DateToOrdinalWords即Humanizer.Localisation.DateToOrdinalWords命名空间下的IDateToOrdinalWordConverter其定义如下public interface IDateToOrdinalWordConverter接口的 XML 文档说明其职责为将日期转换为ToOrdinalWords所用的本地化文本Converts dates into the localized text used byToOrdinalWords。也就是说Humanizer 对外暴露的DateTime.ToOrdinalWords()扩展方法本身不做任何格式化逻辑而是把工作委托给当前文化culture对应的这个转换器实例这正是 Humanizer 一贯的本地化注册表 策略接口设计模式。接口共声明了两个方法方法签名说明string Convert(DateTime date)将日期转换为当前文化的序数词日期文本string Convert(DateTime date, GrammaticalCase grammaticalCase)使用指定的语法格grammatical case转换日期对应接口源码见 IDateToOrdinalWordConverter.cs两个方法的实际定义与文档完全一致public interface IDateToOrdinalWordConverter { string Convert(DateTime date); string Convert(DateTime date, GrammaticalCase grammaticalCase); }方法详解Convert(DateTime date)签名string Convert(System.DateTime date);参数date—— 要格式化的System.DateTime实例。返回System.String—— 本地化的序数词日期字符串。语义将日期转换为序数词形式例如英文文化下2023 年 1 月 1 日会输出1st of January, 2023输出样式完全取决于当前线程的CultureInfo.CurrentCulture。Convert(DateTime date, GrammaticalCase grammaticalCase)签名string Convert(System.DateTime date, Humanizer.GrammaticalCase grammaticalCase);参数date—— 要格式化的日期grammaticalCase—— 要应用的语法格取值来自Humanizer.GrammaticalCase枚举。返回System.String—— 指定语法格下的本地化序数词日期字符串。语义对俄语、波兰语等具有格系统的语言序数词会随语法格主格、属格等变化例如俄语中Nominative与Genitive会产生不同的日期表达。对英语这类没有格系统的语言该参数不产生实际影响。关于GrammaticalCase的完整枚举值说明可参考仓库中的 GrammaticalCase.md API 文档。从接口到输出的完整调用链要理解这个接口在项目中的真实地位需要沿着调用链往下看。Humanizer 对使用者暴露的入口是 DateToOrdinalWordsExtensions.cs 中的扩展方法public static string ToOrdinalWords(this DateTime input) Configurator.DateToOrdinalWordsConverter.Convert(input); public static string ToOrdinalWords(this DateTime input, GrammaticalCase grammaticalCase) Configurator.DateToOrdinalWordsConverter.Convert(input, grammaticalCase);也就是说ToOrdinalWords()在内部从Configurator取回当前已解析的转换器再调用其Convert方法。而Configurator中对应属性的定义位于 Configurator.cspublic static LocaliserRegistryIDateToOrdinalWordConverter DateToOrdinalWordsConverters { get; } new DateToOrdinalWordsConverterRegistry();内部访问器Configurator.DateToOrdinalWordsConverter则通过DateToOrdinalWordsConverters.ResolveForCulture(null)解析当前文化对应的转换器实例见 Configurator.cs。注册表的实现是 DateToOrdinalWordsConverterRegistry.cs它继承自LocaliserRegistryIDateToOrdinalWordConverter其构造函数以DefaultDateToOrdinalWordConverter作为所有文化的默认兜底并通过DateToOrdinalWordsConverterRegistryRegistrations.Register(this)注入各语言特定的注册项class DateToOrdinalWordsConverterRegistry : LocaliserRegistryIDateToOrdinalWordConverter { public DateToOrdinalWordsConverterRegistry() : base(_ new DefaultDateToOrdinalWordConverter()) DateToOrdinalWordsConverterRegistryRegistrations.Register(this); }这里的DateToOrdinalWordsConverterRegistryRegistrations由Humanizer.SourceGenerators项目基于src/Humanizer/Locales下的 YAML 语言数据生成这就是各语言能够获得开箱即用本地化行为的底层机制。默认实现DefaultDateToOrdinalWordConverter的分支逻辑默认转换器 DefaultDateToOrdinalWordConverter.cs 是本接口最直接的参考实现其Convert(DateTime)逻辑非常清晰public virtual string Convert(DateTime date) { var culture CultureInfo.CurrentCulture; if (culture.TwoLetterISOLanguageName ! en) { return SanitizeNonEnglishDate(date.ToString(d, culture)); } return date.Day.Ordinalize() date.ToString( MMMM yyyy); }可以拆解为两条分支英语文化TwoLetterISOLanguageName en日份使用date.Day.Ordinalize()生成序数词如1st、22nd再拼接 MMMM yyyy格式的月份与年份最终得到1st of January, 2023这样的输出。非英语文化直接采用当前文化的短日期模式date.ToString(d, culture)短日期模式本身已包含各文化的日期顺序随后通过SanitizeNonEnglishDate清理输出中可能混入的排版方向控制符。SanitizeNonEnglishDate会剔除三种 Unicode 控制字符LeftToRightMarkU200E、RightToLeftMarkU200F和ArabicLetterMarkU061C。原因在于某些日历系统如阿拉伯语、希伯来语相关日历在短日期输出中会嵌入方向性标记若不清理当日期文本被嵌入更大的序数短语时会影响可读性。值得注意的是带语法格的重载Convert(DateTime, GrammaticalCase)在默认实现中直接忽略grammaticalCase参数并转发给无格版本public virtual string Convert(DateTime date, GrammaticalCase grammaticalCase) Convert(date);这是因为默认转换器不随语法格变化措辞。对应地Humanizer 还为 .NET 6 提供了DateOnly版本的默认实现 DefaultDateOnlyToOrdinalWordConverter.cs逻辑完全一致仅把输入类型换成DateOnly。模式化实现PatternDateToOrdinalWordsConverter与OrdinalDatePattern从源码结构看Humanizer 的本地化体系还为需要精确控制日期模板的语言提供了更灵活的实现——PatternDateToOrdinalWordsConverter.cs。它继承自DefaultDateToOrdinalWordConverter构造时接收一个OrdinalDatePattern模式对象class PatternDateToOrdinalWordsConverter(OrdinalDatePattern pattern) : DefaultDateToOrdinalWordConverter { public override string Convert(DateTime date) pattern.Format(date); }OrdinalDatePattern见 OrdinalDatePattern.cs将日期模板与日份渲染模式解耦其核心由两部分组成日份渲染模式OrdinalDateDayMode枚举定义于同一文件支持五种渲染方式Numeric文化感知的数字Ordinal序数词OrdinalWhenDayIsOne仅当月第一天使用序数词如部分语言中1er其余日期用数字MasculineOrdinalWhenDayIsOne同前但第一天的序数词强制使用阳性GrammaticalGender.Masculine形式DotSuffix数字后带点号后缀如德式1.。模板字符串模板内可包含{day}占位符。格式化时先按文化格式生成完整日期含真实的d日份说明符以保证斯拉夫语系中与月份相邻时能正确触发属格月份名再把DAY标记与数字日份一并替换为实际渲染的日份文本。该模式还支持通过months/monthsGenitive/hijriMonths数组覆盖月份名称并针对希吉拉历Hijri / UmAlQura自动切换到对应的月份数组。此外OrdinalDateCalendarMode枚举见 OrdinalDateCalendarMode.cs控制日历解析方式Gregorian强制使用格里高利历Native则保留文化的默认日历如泰历、希伯来历、波斯历使年份输出符合当地习惯。需要说明的是PatternDateToOrdinalWordsConverter、OrdinalDatePattern等类是 Humanizer 内部实现细节非public主要用于支撑由 YAML 语言数据生成出来的各语言注册项开发者一般无需直接使用它们。自定义实现并接入 Humanizer实操指南接口是public的因此你可以完全自定义日期序数词的输出规则。完整步骤分三步第一步实现接口using Humanizer; using Humanizer.Localisation.DateToOrdinalWords; public sealed class MyDateToOrdinalWordConverter : IDateToOrdinalWordConverter { public string Convert(DateTime date) $Day {date.Day} of {date:MMMM yyyy}; public string Convert(DateTime date, GrammaticalCase grammaticalCase) { // 若你的语言没有语法格可直接复用无格版本 return Convert(date); } }第二步注册到配置注册表Configurator.DateToOrdinalWordsConverters是公开的LocaliserRegistryIDateToOrdinalWordConverter可按文化注册自定义转换器Configurator.DateToOrdinalWordsConverters .Register(en, () new MyDateToOrdinalWordConverter());对于需要语法格变体的语言可以在Convert(date, grammaticalCase)中读取GrammaticalCase枚举值如Nominative、Genitive、Dative等分支处理以满足俄语、波兰语等格系统语言的日期表达需求。第三步通过扩展方法验证效果注册完成后调用ToOrdinalWords()扩展方法时Configurator.DateToOrdinalWordsConverter会按当前文化解析到你的实现var text new DateTime(2023, 1, 1).ToOrdinalWords(); // 在你的自定义实现下输出 Day 1 of January 2023与DateOnly变体的关系接口在 .NET 6.0 及以上还拥有对应的DateOnly版本 IDateOnlyToOrdinalWordConverter.cspublic interface IDateOnlyToOrdinalWordConverter { string Convert(DateOnly date); string Convert(DateOnly date, GrammaticalCase grammaticalCase); }它在命名上与IDateToOrdinalWordConverter一一对应只是输入类型换成DateOnly对应的扩展方法见 DateToOrdinalWordsExtensions.cs且仅当目标框架为NET6_0_OR_GREATER时可用。注册表侧同样有配套的Configurator.DateOnlyToOrdinalWordsConverters属性见 Configurator.cs。如果你要同时支持DateTime与DateOnly通常需要分别实现两个接口。小结IDateToOrdinalWordConverter虽只是一个两方法的小接口却是 Humanizer 日期序数词本地化体系的关键枢纽对外它是DateTime.ToOrdinalWords()扩展方法DateToOrdinalWordsExtensions.cs的实际执行者对内它由 DateToOrdinalWordsConverterRegistry.cs 按文化解析默认回退到 DefaultDateToOrdinalWordConverter.cs扩展实现该接口并通过Configurator.DateToOrdinalWordsConverters.Register(...)注册即可为任意文化提供完全自定义的日期序数词输出包括语法格敏感的变体。理解了这个接口你就掌握了 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 的 IDateToOrdinalWordConverter日期转序数词文本的本地化转换接口解析Humanizer 的 IDateToOrdinalWordConverter日期转序数词文本的本地化转换接口解析 IDateToOrdinalWordCon开发工具Humanizer 本地化日期序数词转换IDateOnlyToOrdinalWordConverter 接口全解Humanizer 本地化日期序数词转换IDateOnlyToOrdinalWordConverter 接口全解 在 Humanizer 中把日期如 20开发工具Humanizer 日期序数词本地化指南解析 IDateToOrdinalWordConverter 与 ToOrdinalWords 的完整实现链路Humanizer 日期序数词本地化指南解析 IDateToOrdinalWordConverter 与 ToOrdinalWords 的完整实现链路 导读开发工具上一篇如何为 AWS 配置 OIDC 信任让 GitHub Actions 获取临时凭证下一篇PDBRipper XNTSV格式导出结构化数据提取的高级应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

Linux zip命令压缩文件夹完全指南:从基础参数到踩坑实践
Linux zip命令压缩文件夹完全指南:从基础参数到踩坑实践

最近不少朋友问我,Linux 下到底怎么用 zip 命令压缩文件夹,说实话,这个问题看起来基础,但真用起来坑还挺多,尤其是从 Windows 习惯切过来的人,最容易在路径、编码、递归这几件事上翻车。这篇就把我在实际环… · 2026/9/25 4:34:26

5个IO口驱动20段188数码管的时分复用方案
5个IO口驱动20段188数码管的时分复用方案

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

猫抓资源嗅探与 M3U8 合并:把网页媒体存到本地的完整指南
猫抓资源嗅探与 M3U8 合并:把网页媒体存到本地的完整指南

猫抓资源嗅探与 M3U8 合并:把网页媒体存到本地的完整指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 你想把正在看的在线视频存到硬… · 2026/9/25 4:34:20

人工智能数学基础:习题答案+源代码如何帮你彻底弄懂公式
人工智能数学基础:习题答案+源代码如何帮你彻底弄懂公式

简介:一份聚焦人工智能数学基础的资源包,由唐宇迪编著,面向AI学生与从业者,帮助逐项补齐线性代数、概率统计、微积分、最优化、图论、离散数学与动态规划等核心数学短板,通过习题与代码将理论落到实践。压缩包整体约6.… · 2026/9/25 8:20:28

HDMI信号传输原理:从TMDS编码到音频PCM打包的FPGA实现
HDMI信号传输原理:从TMDS编码到音频PCM打包的FPGA实现

HDMI 这玩意儿现在满大街都是,电视、显示器、机顶盒、笔记本、游戏机,甚至树莓派和 FPGA 开发板上都标配。但真要问一句“HDMI 到底是怎么把画面和声音从一根线送过去的”,能说清楚的人并不多。我当初调 FPGA 的 HDMI 输出时,对着… · 2026/9/25 8:20:22

8G显存本地部署minimaxh3:ComfyUI剪枝版+加速LoRA实战
8G显存本地部署minimaxh3:ComfyUI剪枝版+加速LoRA实战

1. 为什么要在8G显存上折腾minimaxh3本地部署先把结论摆在前面:8G显存跑minimaxh3,能跑,但绝对不是“点一下按钮就出片”的体验。我前后折腾了差不多两周,从最初的直接爆显存,到后来能把一段5秒的480P视频稳定生成出来… · 2026/9/25 8:20:16

物联网健康监测系统设计:从树莓派网关到多传感器报警闭环
物联网健康监测系统设计:从树莓派网关到多传感器报警闭环

简介:一套面向物联网开发者和嵌入式学习者的健康监测系统设计资料,围绕树莓派网关、加速度计、音频与视频监测、Web端应用等核心模块展开,覆盖从硬件数据采集、传感器信号处理到云端传输与远程管理的完整链路,可支撑课程设计、项目… · 2026/9/25 8:20:16

Atlas 300V 24G部署YOLO实战:从硬件认知到推理调优全流程
Atlas 300V 24G部署YOLO实战:从硬件认知到推理调优全流程

最近后台私信里问得最多的一个东西,就是Atlas 300V 24G。问来问去其实就两句话:这卡到底是不是运算加速卡?能不能用来部署YOLO?我的回答一直很直接:能,而且就是干这个的。Atlas 300V 24G是华为昇腾阵营里一… · 2026/9/25 8:20:16

让Codex像安全工程师一样审代码:Cloudflare Security Audit Skill解析
让Codex像安全工程师一样审代码:Cloudflare Security Audit Skill解析

现在让任何一个主流编程代理去“审一遍代码安全”,它多半会给你交出一份看似全面的报告:SQL 注入、XSS、SSRF 列得整整齐齐,但仔细一看,全是模型对漏洞定义的通识复述,既没确认数据流是否真的从用户输入走到了危险函数… · 2026/9/25 8:20:16

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

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

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

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

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

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

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码