新闻详情

新闻详情

首页 / 资讯中心 / 详情

Humanizer IDateOnlyToOrdinalWordConverter 接口详解:在 .NET 中将 DateOnly 日期本地化为序数词表示

发布时间:2026/9/28 3:13:05来源:尧图网络
Humanizer IDateOnlyToOrdinalWordConverter 接口详解:在 .NET 中将 DateOnly 日期本地化为序数词表示
开发工具【免费下载链接】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 项目中负责将System.DateOnly日期转换为本地化序数词文本的IDateOnlyToOrdinalWordConverter接口梳理其方法签名、默认实现原理、语言配置机制与自定义替换方式。读者读完本文后将掌握DateOnly.ToOrdinalWords()的完整调用链扩展方法 → 注册表 → 转换器理解英语与非英语文化的不同渲染策略并能通过Configurator为自己的文化定制转换器。接口定位ToOrdinalWords的 DateOnly 本地化转换器在 Humanizer 中将日期转换为序数词Ordinal Words如英文的1st of January, 2023由一组按文化culture注册的转换器完成。IDateOnlyToOrdinalWordConverter正是这一机制中面向 .NET 6 新增值类型System.DateOnly的抽象契约其源码位于 src/Humanizer/Localisation/DateToOrdinalWords/IDateOnlyToOrdinalWordConverter.cs。接口的官方定位在文档中被概括为一句话The interface used to localise the ToOrdinalWords method即用于将ToOrdinalWords方法本地化的接口。它在 Humanizer 中承担三项职责接收一个仅包含日期无时间的DateOnly值依据当前线程文化CultureInfo.CurrentCulture输出本地化的序数词日期文本为存在语法格Grammatical Case体系的语言提供按格变形的重载。需要注意一个硬性前提该接口整体包裹在#if NET6_0_OR_GREATER条件编译指令中参见 IDateOnlyToOrdinalWordConverter.cs。因为System.DateOnly类型自 .NET 6 才引入所以只有在目标框架为 .NET 6 或更高版本时Humanizer 才会编译并暴露该接口对应的扩展方法DateOnly.ToOrdinalWords()同样受此约束。方法契约两个重载的签名、参数与返回语义接口对外暴露两个方法均返回System.String。Convert(DateOnly date)string Convert(System.DateOnly date);参数dateSystem.DateOnly类型表示要格式化的日期仅包含年、月、日无时间分量。返回值System.String当前文化下的本地化序数词日期字符串。英文环境下典型输出如1st of January, 2023、22nd of December, 2020。Convert(DateOnly date, GrammaticalCase grammaticalCase)string Convert(System.DateOnly date, Humanizer.GrammaticalCase grammaticalCase);参数date同上System.DateOnly类型。参数grammaticalCaseHumanizer.GrammaticalCase枚举表示要应用的语法格如主格 Nominative、属格 Genitive 等。该枚举的定义可参考 Humanizer.GrammaticalCase.md。返回值System.String按指定语法格输出的本地化序数词日期字符串。语法格参数主要服务于俄语、波兰语等拥有格变化体系的语言同一日期在不同格下会产出不同词形例如俄语中主格与属格形式不同。对于英语这类没有语法格的语言该参数不会改变输出结果。与 DateTime 版本的对应关系IDateToOrdinalWordConverterHumanizer 中还存在一个面向System.DateTime的平行接口IDateToOrdinalWordConverter定义于 src/Humanizer/Localisation/DateToOrdinalWords/IDateToOrdinalWordConverter.cs其两个方法签名分别为string Convert(DateTime date)与string Convert(DateTime date, GrammaticalCase grammaticalCase)与IDateOnlyToOrdinalWordConverter一一对应、结构完全平行唯一的差异是入参类型不同。两者通过各自的注册表独立管理接口注册表暴露的 Configurator 属性IDateOnlyToOrdinalWordConverterDateOnlyToOrdinalWordsConverterRegistryConfigurator.DateOnlyToOrdinalWordsConverters仅 .NET 6IDateToOrdinalWordConverterDateToOrdinalWordsConverterRegistryConfigurator.DateToOrdinalWordsConverters从源码结构看这种平行设计让DateOnly与DateTime两条转换管线互不干扰便于针对新类型独立做本地化适配。完整调用链从扩展方法到转换器IDateOnlyToOrdinalWordConverter本身并不直接面向调用者日常使用入口是DateToOrdinalWordsExtensions提供的扩展方法。该文件位于 src/Humanizer/DateToOrdinalWordsExtensions.cs其中#if NET6_0_OR_GREATER区块内的两个方法public static string ToOrdinalWords(this DateOnly input) Configurator.DateOnlyToOrdinalWordsConverter.Convert(input); public static string ToOrdinalWords(this DateOnly input, GrammaticalCase grammaticalCase) Configurator.DateOnlyToOrdinalWordsConverter.Convert(input, grammaticalCase);调用链可概括为三层扩展方法层DateOnly.ToOrdinalWords()/ToOrdinalWords(GrammaticalCase)位于 DateToOrdinalWordsExtensions.cs配置解析层Configurator.DateOnlyToOrdinalWordsConverter内部通过DateOnlyToOrdinalWordsConverters.ResolveForCulture(null)按当前文化解析出具体实现见 Configurator.cs转换器实现层由DateOnlyToOrdinalWordsConverterRegistry按文化返回对应的IDateOnlyToOrdinalWordConverter实例。注册表DateOnlyToOrdinalWordsConverterRegistry定义于 src/Humanizer/Configuration/DateOnlyToOrdinalWordsConverterRegistry.cs它继承自LocaliserRegistryIDateOnlyToOrdinalWordConverter构造函数以DefaultDateOnlyToOrdinalWordConverter作为兜底实现并通过DateOnlyToOrdinalWordsConverterRegistryRegistrations.Register(this)由 Humanizer 的源生成器Source Generator注入各语言的具体注册项。这意味着未显式注册的文化会自动回退到默认转换器不会抛出异常。默认实现原理英语序数词 非英语短日期清理默认实现DefaultDateOnlyToOrdinalWordConverter位于 src/Humanizer/Localisation/DateToOrdinalWords/DefaultDateOnlyToOrdinalWordConverter.cs其核心逻辑按语言分支处理public virtual string Convert(DateOnly date) { var culture CultureInfo.CurrentCulture; if (culture.TwoLetterISOLanguageName ! en) { // 非英语文化直接使用当前文化的短日期模式 d // 并清理部分日历在格式化输出中嵌入的方向控制符。 return SanitizeNonEnglishDate(date.ToString(d, culture)); } return date.Day.Ordinalize() date.ToString( MMMM yyyy); }两点关键行为值得展开英语文化将date.Day通过Ordinalize()转换为序数词1 → 1st、2 → 2nd、3 → 3rd、22 → 22nd再拼接 MMMM yyyy格式的完整月份与年份最终得到1st of January, 2023这类输出。其中月份名称与年份数字来自当前文化的DateTimeFormat。非英语文化直接采用date.ToString(d, culture)的短日期格式如俄语的25.01.2023、德语的25.01.2023因为非英语文化本身已能正确表达日期次序Humanizer 不再额外改写。随后通过SanitizeNonEnglishDate剔除短日期输出中可能出现的三类 Unicode 方向控制符——U200ELeft-To-Right Mark、U200FRight-To-Left Mark、U061CArabic Letter Mark避免这些不可见字符在嵌入更大的序数词短语时干扰阅读与字符串比较。关于语法格重载默认实现中的Convert(DateOnly date, GrammaticalCase grammaticalCase)直接委托给Convert(date)并忽略grammaticalCase——因为默认兜底转换器不随语法格改变措辞。格变化能力由各语言专属的转换器提供。语言专属实现OrdinalDatePattern 模板引擎从源码结构看多数语言的DateOnly序数词转换器并非重复造轮子而是复用DefaultDateOnlyToOrdinalWordConverter的派生类PatternDateOnlyToOrdinalWordsConverter见 src/Humanizer/Localisation/DateToOrdinalWords/PatternDateOnlyToOrdinalWordsConverter.cs。它接收一个预构建的OrdinalDatePattern仅重写Convert方法委托给pattern.Format(date)。OrdinalDatePattern定义于 src/Humanizer/Localisation/DateToOrdinalWords/OrdinalDatePattern.cs是一个可配置的模板格式化器包含以下核心设计模板与占位符模板字符串中通过{day}占位符标记日的渲染位置。格式化时先用带标记的格式串走DateOnly.ToString(format, culture)再把标记替换为按dayMode渲染出的日文本从而保证模板其余部分月份、年份、分隔符完整遵循文化习惯。日渲染模式OrdinalDateDayMode枚举定义于 OrdinalDatePattern.cs模式行为Numeric日渲染为文化感知的纯数字Ordinal日始终渲染为序数词day.Ordinalize()OrdinalWhenDayIsOne仅当月第一天day 1使用序数词其余为数字MasculineOrdinalWhenDayIsOne仅 day 1 时使用阳性Masculine序数形式其余为数字DotSuffix数字后附加点号后缀如德语风格的25.日历模式OrdinalDateCalendarModeGregorian默认强制使用本地化公历与Native保留文化原生日历例如泰语佛历的年份输出。在强制公历时若当前文化不支持本地化公历会依次尝试其OptionalCalendars中可用的公历实例。月份覆盖数组允许为特定文化覆盖月份名称对斯拉夫语系等存在属格Genitive月份形态的语言monthsGenitive数组会在日与月份相邻d MMMM或MMMM d模式时被自动选中例如俄语中日期短语内的月份使用属格形式。该判断逻辑会区分d/dd月内日与ddd/dddd星期说明符避免误判。希吉来日历当文化使用HijriCalendar或UmAlQuraCalendar时可提供独立的hijriMonths月份数组。方向控制符清理格式化完成后统一剥离U200E、U200F、U061C与默认实现的清理策略保持一致。这一模板引擎的存在使得为一种语言新增DateOnly序数词支持时只需声明模板 日模式 月份数组而无需编写完整转换逻辑——这正是各语言配置文件src/Humanizer/Locales 目录下的 YAML 资源经源生成器转化为注册代码的基础。自定义转换器通过 Configurator 替换实现当默认或内置的本地化输出不满足需求时可通过Configurator.DateOnlyToOrdinalWordsConverters注册表替换指定文化的转换器。注册表暴露于 Configurator.cs#if NET6_0_OR_GREATER public static LocaliserRegistryIDateOnlyToOrdinalWordConverter DateOnlyToOrdinalWordsConverters { get; } new DateOnlyToOrdinalWordsConverterRegistry(); #endif自定义实现只需实现接口的两个方法例如public class MyDateOnlyToOrdinalWordConverter : IDateOnlyToOrdinalWordConverter { public string Convert(DateOnly date) $Day {date.Day} of {date:MMMM yyyy}; public string Convert(DateOnly date, GrammaticalCase grammaticalCase) Convert(date); }注册方式须在应用启动阶段完成且应在任何ToOrdinalWords调用之前Configurator.DateOnlyToOrdinalWordsConverters.Register( new CultureInfo(en-US), () new MyDateOnlyToOrdinalWordConverter());从 DateOnlyToOrdinalWordsConverterRegistry.cs 的实现可知未注册的文化会稳定回退到DefaultDateOnlyToOrdinalWordConverter因此自定义注册只影响目标文化不影响其他文化的既有行为。测试与契约保障Humanizer 对DateOnly序数词转换的验证覆盖了三类测试资产语言期望数据LocaleCoverageDatatests/Humanizer.Tests/Localisation/LocaleCoverageData.cs中提供了DateOnlyToOrdinalWords2022January25ExpectationTheoryData等多组理论数据覆盖 1 月 25 日、1 月 1 日、2 月 3 日、2 月 29 日闰年、9 月 4 日、11 月 7 日、3 月 2 日、10 月 31 日、12 月 31 日等边界日期且与DateTime版本的期望数据共享保证两条管线输出一致。未支持文化回退CoverageGapTeststests/Humanizer.Tests/CoverageGapTests.cs显式验证了对未支持文化调用Configurator.DateOnlyToOrdinalWordsConverters.ResolveForCulture(...)时的兜底行为确保解析不抛异常。公共 API 契约PublicApiApprovalTest.Approve_Public_Api.DotNet8_0.verified.txttests/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.Approve_Public_Api.DotNet8_0.verified.txt以快照方式锁定了Configurator.DateOnlyToOrdinalWordsConverters属性及ToOrdinalWords(this DateOnly)、ToOrdinalWords(this DateOnly, GrammaticalCase)两个扩展方法的公开签名任何破坏性变更都会被 API 审批测试拦截。使用前提与注意事项小结框架版本IDateOnlyToOrdinalWordConverter及DateOnly.ToOrdinalWords()仅在 .NET 6 及以上框架可用#if NET6_0_OR_GREATER使用DateTime版本的ToOrdinalWords不受此限制。文化敏感性输出完全取决于调用线程的CultureInfo.CurrentCulture跨文化测试时需显式切换文化Humanizer.Tests 中为此提供了UseCultureAttribute辅助。语法格仅对存在格变化的语言产生实际差异英语及默认兜底实现会忽略grammaticalCase参数。配置时机若需自定义转换器应在应用启动阶段完成注册避免在运行时与并发场景下动态更换注册表。方向控制符非英语文化输出已内置清理不可见方向标记的逻辑字符串比较与嵌入场景下无需额外处理。赞分享开发工具【免费下载链接】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 本地化日期序数词转换IDateOnlyToOrdinalWordConverter 接口全解Humanizer 本地化日期序数词转换IDateOnlyToOrdinalWordConverter 接口全解 在 Humanizer 中把日期如 20开发工具Humanizer 日期转序数词本地化接口深度解析IDateToOrdinalWordConverter 与 IDateOnlyToOrdinalWordConverterHumanizer 日期转序数词本地化接口深度解析IDateToOrdinalWordConverter 与 IDateOnlyToOrdinalWordCo开发工具Humanizer 本地化接口 IDateOnlyToOrdinalWordConverter 深度解析DateOnly 序数词日期的转换机制与自定义实现Humanizer 本地化接口 IDateOnlyToOrdinalWordConverter 深度解析DateOnly 序数词日期的转换机制与自定义实现 I开发工具上一篇PixiJS Graphics 完整指南从基础图元到 GraphicsContext 性能优化下一篇如何在STM32上构建高性能CNC控制器GRBL移植完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

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

较早相关资讯

最新相关资讯

HTTP1(Hypertext Transfer Protocol)超文本传输协议 2026/9/28 4:15:41

HTTP1(Hypertext Transfer Protocol)超文本传输协议

1.http:应用层协议http为什么叫“超文本”?超文本含义:http能传输文本、多媒体数据(图片、视频、音频等)。http发展过程HTTP/0.9(1991)——》HTTP/1.0(1992~1996)——》H…

阅读更多 →
宏重复被覆盖:同名宏重定义逻辑变,加 #ifndef 守护或改名 2026/9/28 4:15:41

宏重复被覆盖:同名宏重定义逻辑变,加 #ifndef 守护或改名

宏重复被覆盖:同名宏重定义逻辑变,加 #ifndef 守护或改名摘要:同名宏在多处 #define 且无守护时,后定义会覆盖先定义,导致"你以为的宏值"与实际不符,逻辑悄悄改变;不同编译单元因包含…

阅读更多 →
每天上万条安全告警怎么看?Python实战教你快速定位真正的攻击行为 2026/9/28 4:15:34

每天上万条安全告警怎么看?Python实战教你快速定位真正的攻击行为

在数字化时代,企业安全告警量爆炸式增长已成为常态。 一天数千条、甚至上万条的安全事件涌入SOC(安全运营中心),分析师们常常陷入“淹没的警报”困境:到底是紧急入侵,还是日常扫描、误报、已知行为&#xf…

阅读更多 →
DeepSeek 涨价后别急着换:用一份可复算的模拟账单比较三条路线(TaoToken 统一 Key 版) 2026/9/28 4:15:34

DeepSeek 涨价后别急着换:用一份可复算的模拟账单比较三条路线(TaoToken 统一 Key 版)

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

阅读更多 →
Copilot Plan Mode + TaoToken 多模型协同:复杂项目开发的配置骨架与验证实战 2026/9/28 4:15:34

Copilot Plan Mode + TaoToken 多模型协同:复杂项目开发的配置骨架与验证实战

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

阅读更多 →
【Spring基础系列】基于注解装配Bean 2026/9/28 4:15:34

【Spring基础系列】基于注解装配Bean

本文主要讲解Spring通过注解装配Bean的常用方式,包括Component、Repository、Service、Controller、Autowired、Resource和Qualifier。前言目前学习java也有一段时间,比较不适应的就是java的各种注解,因为它里面包含了太多的东西,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

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

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