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),仅供参考