ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Humanizer 日期人性化指南:DefaultDateOnlyHumanizeStrategy 源码解读与实战

Humanizer 日期人性化指南:DefaultDateOnlyHumanizeStrategy 源码解读与实战 开发工具【免费下载链接】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点击查看免费下载导读DefaultDateOnlyHumanizeStrategy是 Humanizer 中负责将DateOnly日期之间的时间距离转换成自然语言的核心默认策略。通过它你可以一行代码把2024-01-01与2024-01-02之间的差距描述为 tomorrow或者把两年前的日子描述为 2 years ago。读完本文你将掌握该策略的完整 API、底层算法逻辑、与DateTimeHumanizeAlgorithms的调用关系、跨文化本地化机制以及如何用Configurator.DateOnlyHumanizeStrategy替换默认实现。一、类概述默认的时间距离 → 文字计算器在 Humanizer 的版本 2.11.10 文档website/versioned_docs/version-2.11.10/api/Humanizer.DateTimeHumanizeStrategy.DefaultDateOnlyHumanizeStrategy.md中该类被定义为The default distance of time - words calculator.对应的源码位于 src/Humanizer/DateTimeHumanizeStrategy/DefaultDateOnlyHumanizeStrategy.cs#if NET6_0_OR_GREATER namespace Humanizer; /// summary /// The default distance of time - words calculator. /// /summary public class DefaultDateOnlyHumanizeStrategy : IDateOnlyHumanizeStrategy { /// summary /// Calculates the distance of time in words between two provided dates /// /summary public string Humanize(DateOnly input, DateOnly comparisonBase, CultureInfo? culture) DateTimeHumanizeAlgorithms.DefaultHumanize(input, comparisonBase, culture); } #endif关键事实平台前提整个类被#if NET6_0_OR_GREATER条件编译指令包裹。原因在于DateOnly类型是 .NET 6 引入的因此该策略只在 .NET 6 及更高版本的目标框架下可用。在 .NET Framework 4.8 等旧平台上不存在这个类型也就没有这个类。继承关系继承自System.Object实现接口IDateOnlyHumanizeStrategy。核心职责接收两个DateOnly和一个可选CultureInfo返回描述时间距离的本地化字符串。委托实现类体极其精简——真正的算法被委托给静态类DateTimeHumanizeAlgorithms.DefaultHumanize。二、接口契约IDateOnlyHumanizeStrategy接口定义在 src/Humanizer/DateTimeHumanizeStrategy/IDateOnlyHumanizeStrategy.cs#if NET6_0_OR_GREATER namespace Humanizer; /// summary /// Implement this interface to create a new strategy for DateOnly.Humanize and hook it in the Configurator.DateOnlyHumanizeStrategy /// /summary public interface IDateOnlyHumanizeStrategy { /// summary /// Calculates the distance of time in words between two provided dates used for DateOnly.Humanize /// /summary string Humanize(DateOnly input, DateOnly comparisonBase, CultureInfo? culture); } #endif接口文档注释明确了两件事该接口是DateOnly.Humanize()扩展方法背后可插拔的策略抽象自定义策略通过Configurator.DateOnlyHumanizeStrategy属性挂载。方法签名解析Humanize(DateOnly, DateOnly, CultureInfo)参数类型含义inputSystem.DateOnly要人性化的目标日期comparisonBaseSystem.DateOnly比较基准日期cultureSystem.Globalization.CultureInfo可空本地化文化信息null时使用当前线程文化返回值System.String——两个日期之间时间距离的本地化文字描述。三、底层算法DateTimeHumanizeAlgorithms.DefaultHumanizeDefaultDateOnlyHumanizeStrategy的Humanize直接调用 src/Humanizer/DateTimeHumanizeStrategy/DateTimeHumanizeAlgorithms.cs 中的DefaultHumanize(DateOnly, DateOnly, CultureInfo)#if NET6_0_OR_GREATER public static string DefaultHumanize(DateOnly input, DateOnly comparisonBase, CultureInfo? culture) { if (input comparisonBase) { return DateOnlyHumanizeToday(culture); } var tense input comparisonBase ? Tense.Future : Tense.Past; var diffDays Math.Abs(comparisonBase.DayNumber - input.DayNumber); var ts new TimeSpan(diffDays, 0, 0, 0); var sameMonth comparisonBase.AddMonths(tense Tense.Future ? 1 : -1) input; var days Math.Abs(input.DayNumber - comparisonBase.DayNumber); return DefaultHumanize(ts, sameMonth, days, tense, culture); } #endif算法关键点同日短路input comparisonBase时直接返回 today通过DateOnlyHumanizeToday获取本地化表述不进入通用计时逻辑。时态判定input comparisonBase为未来Tense.Future否则为过去Tense.Past。天差计算使用DateOnly.DayNumber计算绝对天数差DayNumber是从0001-01-01起的连续天数天然规避了跨月、跨年计算的复杂性并构造一个天级TimeSpan。同月判断sameMonth用于 28~30 天边界场景的特殊处理——若恰好相差整月则输出 1 month否则仍按天数输出。核心分级判定逻辑随后进入私有的DefaultHumanize(TimeSpan, bool, int, Tense, CultureInfo)重载这是一连串由小到大的时间单位判定条件输出单位示例en-USts.TotalMilliseconds 500毫秒数量 0nowts.TotalSeconds 60秒30 seconds agots.TotalSeconds 120分钟数量 1a minute agots.TotalMinutes 60分钟45 minutes from nowts.TotalMinutes 90小时数量 1an hour agots.TotalHours 24小时6 hours from nowts.TotalHours 48天按日历天数yesterday / tomorrowts.TotalDays 7天3 days agots.TotalDays 28周2 weeks from now28 ≤ TotalDays 30月若 sameMonth或天one month from now / 29 days agoTotalDays 345月按 29.5 天/月折算6 months ago其余年按 365 天/年折算至少 12 years ago本地化出口所有分支最终都调用var formatter Configurator.GetFormatter(culture); return formatter.DateHumanize(TimeUnit.Year, tense, years);即数字与单位本身不硬编码在算法中而是交给按文化解析出的IFormatter渲染。这正是 Humanizer 能输出 3 days agoen、vor 3 Tagende、3 天前zh-CN等不同表述的原因。完整判定链参见 DateTimeHumanizeAlgorithms.cs。四、入口链路DateOnly.Humanize 扩展方法策略本身不会直接被调用而是通过 src/Humanizer/DateHumanizeExtensions.cs 的扩展方法进入#if NET6_0_OR_GREATER public static string Humanize(this DateOnly input, DateOnly? dateToCompareAgainst null, CultureInfo? culture null) { var comparisonBase dateToCompareAgainst ?? DateOnly.FromDateTime(DateTime.UtcNow); return Configurator.DateOnlyHumanizeStrategy.Humanize(input, comparisonBase, culture); } #endif实际用法示例using Humanizer; var releaseDate new DateOnly(2024, 1, 1); var today new DateOnly(2024, 1, 2); releaseDate.Humanize(today); // yesterday today.Humanize(releaseDate); // tomorrow var twoYearsAgo new DateOnly(2022, 1, 1); twoYearsAgo.Humanize(today); // 2 years ago // 不传基准日期时默认与 UTC 当前日期比较 new DateOnly(2024, 3, 1).Humanize(); // 依据当前日期输出 // 指定文化 new DateOnly(2024, 1, 1).Humanize(today, new CultureInfo(fr-FR));要点说明dateToCompareAgainst为null时基准日期取DateOnly.FromDateTime(DateTime.UtcNow)UTC 当天culture为null时由Configurator.GetFormatter(null)回退到当前线程文化还有DateOnly?可空重载值为null时输出 never调用Formatter.DateHumanize_Never()。五、可插拔机制Configurator.DateOnlyHumanizeStrategyDefaultDateOnlyHumanizeStrategy是配置中心默认挂载的策略。在 src/Humanizer/Configuration/Configurator.cs 中public static IDateOnlyHumanizeStrategy DateOnlyHumanizeStrategy { get; set; } new DefaultDateOnlyHumanizeStrategy();这意味着默认情况下所有DateOnly.Humanize()调用走的都是DefaultDateOnlyHumanizeStrategy你可以整体替换策略例如换用PrecisionDateOnlyHumanizeStrategy以获得更精确的单位判定其默认精度为0.75见 src/Humanizer/DateTimeHumanizeStrategy/PrecisionDateOnlyHumanizeStrategy.cs或实现自己的IDateOnlyHumanizeStrategy注入Configurator.DateOnlyHumanizeStrategy new PrecisionDateOnlyHumanizeStrategy(0.75);从源码注释可看出这类全局配置在并发/生产环境下应谨慎修改尽量在应用启动阶段设置。六、测试佐证策略行为已被充分验证DefaultDateOnlyHumanizeStrategy的行为在 tests/Humanizer.Tests/DateOnlyHumanizeTests.cs 中有系统化的单元测试覆盖[UseCulture(en-US)] public class DateOnlyHumanizeTests { [Fact] public void DefaultStrategy_SameDate() { var inputTime new DateOnly(2015, 07, 05); var baseTime new DateOnly(2015, 07, 05); const string expectedResult today; var actualResult inputTime.Humanize(baseTime); Assert.Equal(expectedResult, actualResult); } [Fact] public void DefaultStrategy_MonthApart() { var inputTime new DateOnly(2015, 08, 05); var baseTime new DateOnly(2015, 07, 05); const string expectedResult one month from now; var actualResult inputTime.Humanize(baseTime); Assert.Equal(expectedResult, actualResult); } [Fact] public void DefaultStrategy_DaysAgo() { var inputTime new DateOnly(2015, 07, 02); var baseTime new DateOnly(2015, 07, 05); const string expectedResult 3 days ago; var actualResult inputTime.Humanize(baseTime); Assert.Equal(expectedResult, actualResult); } }这些测试印证了本文第三节描述的算法行为同日 → today、整月差 → one month from now、3 天差 → 3 days ago。此外SameDate_UsesDateOnlyWordingWithoutChangingCultureFallback测试验证了同日场景在en-GB输出 today、在fr-FR输出 maintenant证明 today 的表述同样走本地化管道Humanize_UsesSpecifiedCulture测试则利用LocaleCoverageData遍历各语言验证策略对指定文化的正确应用。七、小结维度结论类定位DateOnly.Humanize()的默认时间距离 → 文字策略平台要求仅 .NET 6DateOnly类型依赖接口实现IDateOnlyHumanizeStrategy算法入口DateTimeHumanizeAlgorithms.DefaultHumanize(DateOnly, DateOnly, CultureInfo)本地化通过Configurator.GetFormatter(culture)的DateHumanize渲染可替换性Configurator.DateOnlyHumanizeStrategy可注入任意实现DefaultDateOnlyHumanizeStrategy表面看是一个一行委托的薄壳实则把分级单位换算与多语言渲染两大复杂问题分别交给了DateTimeHumanizeAlgorithms和IFormatter体系是 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 的 DefaultDateOnlyHumanizeStrategy把 DateOnly 距离转化为人类可读文字的实现与源码剖析Humanizer 的 DefaultDateOnlyHumanizeStrategy把 DateOnly 距离转化为人类可读文字的实现与源码剖析 导读 本文开发工具Humanizer 日期人性化指南DateHumanizeExtensions 全方法解析与底层实现Humanizer 日期人性化指南DateHumanizeExtensions 全方法解析与底层实现 导读 DateHumanizeExtensions 是开发工具Humanizer DefaultDateOnlyHumanizeStrategy 深入解析DateOnly 相对时间人性化输出策略Humanizer DefaultDateOnlyHumanizeStrategy 深入解析DateOnly 相对时间人性化输出策略 本文聚焦 Humaniz开发工具上一篇Express测试驱动开发实践如何用TDD构建高质量Web应用下一篇AI System中的数学原理从线性代数到深度学习算法创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表