
開發(fā)工具【免費下載鏈接】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點擊查看免費下載本篇技術(shù)文章圍繞 Humanizer 的PrecisionDateTimeOffsetHumanizeStrategy類展開講解它如何通過一個precision精度系數(shù)把兩個DateTimeOffset之間的時間差近似為幾分鐘前/幾天后/2 個月前這樣的自然語言表述。讀完本文你將掌握該策略類的完整 API 契約、精度系數(shù)在底層取整算法中的具體作用、如何通過Configurator將它接入DateTimeOffset.Humanize擴展方法以及官方單元測試對關(guān)鍵行為的驗證方式。一、類定位精度型距離時間計算器PrecisionDateTimeOffsetHumanizeStrategy是 Humanizer 用于計算兩個時間點之間距離distance of time in words的精度型策略類。它的官方 API 參考頁位于 PrecisionDateTimeOffsetHumanizeStrategy API 文檔文檔對其的定性是Precision-based calculator for distance between two times該類的聲明形態(tài)如下摘自 API 文檔public class PrecisionDateTimeOffsetHumanizeStrategy : Humanizer.DateTimeHumanizeStrategy.IDateTimeOffsetHumanizeStrategy它繼承自System.Object并實現(xiàn) IDateTimeOffsetHumanizeStrategy 接口。該接口的唯一職責是為DateTimeOffset.Humanize計算兩個日期之間的時間距離以自然語言表示public interface IDateTimeOffsetHumanizeStrategy { string Humanize(DateTimeOffset input, DateTimeOffset comparisonBase, CultureInfo? culture); }接口的實現(xiàn)可以在倉庫源碼中直接核對IDateTimeOffsetHumanizeStrategy.cs。從源碼結(jié)構(gòu)看IDateTimeOffsetHumanizeStrategy一共有兩個內(nèi)置實現(xiàn)構(gòu)成一組可替換的算法策略策略類算法特征DefaultDateTimeOffsetHumanizeStrategy默認策略采用固定的經(jīng)驗閾值500 毫秒、60 秒、90 分鐘、24 小時、28 天等不做可配置近似PrecisionDateTimeOffsetHumanizeStrategy本文主題所有取整閾值均由precision系數(shù)按比例縮放可統(tǒng)一調(diào)節(jié)進位的激進程度二、完整 API 面構(gòu)造器與 Humanize 方法2.1 構(gòu)造器PrecisionDateTimeOffsetHumanizeStrategy(double)構(gòu)造器簽名與 API 文檔一致public PrecisionDateTimeOffsetHumanizeStrategy(double precision 0.75);precisiondouble默認值0.75近似精度系數(shù)precision of approximation。文檔說明if not provided, 0.75 will be used as a default precision即不傳參時按 0.75 使用。該值在實例內(nèi)部被保存為一個只讀字段后續(xù)每次Humanize調(diào)用都使用構(gòu)造時確定的同一個精度系數(shù)實例本身不隨調(diào)用改變行為。在倉庫當前源碼中該類使用 C# 主構(gòu)造器參數(shù)聲明實現(xiàn)非常薄全部邏輯委托給共享算法類見 PrecisionDateTimeOffsetHumanizeStrategy.cspublic class PrecisionDateTimeOffsetHumanizeStrategy(double precision .75) : IDateTimeOffsetHumanizeStrategy { readonly double precision precision; /// summary /// Returns localized amp; humanized distance of time between two dates; given a specific precision. /// /summary public string Humanize(DateTimeOffset input, DateTimeOffset comparisonBase, CultureInfo? culture) DateTimeHumanizeAlgorithms.PrecisionHumanize(input.UtcDateTime, comparisonBase.UtcDateTime, precision, culture); }這里有一個關(guān)鍵細節(jié)策略把input和comparisonBase都轉(zhuǎn)換為UtcDateTime再做比較。也就是說時間戳本身的 UTC 偏移量offset不參與距離計算兩個帶不同 offset 但指向同一瞬間的時間點會被視為零距離。這一點在 DateTimeOffsetHumanizeTests.cs 的PrecisionStrategy_DifferentOffsets用例中得到驗證兩個相差 7.5 小時的 offset 的DateTimeOffset被正確比較。命名空間提示2.13.14 版本 API 文檔中標注該類位于Humanizer.DateTimeHumanizeStrategy命名空間而在當前倉庫源碼PrecisionDateTimeOffsetHumanizeStrategy.cs與 API 審批基線文件PublicApiApprovalTest.Approve_Public_Api.DotNet8_0.verified.txt中該類與接口均已歸屬Humanizer根命名空間。如果你的項目引用的是 2.13.14 或更舊的包版本引用時請按對應(yīng)版本的命名空間書寫。2.2Humanize(DateTimeOffset, DateTimeOffset, CultureInfo)方法public string Humanize(DateTimeOffset input, DateTimeOffset comparisonBase, CultureInfo? culture);參數(shù)類型含義inputSystem.DateTimeOffset要人性化的人機可讀目標時間點comparisonBaseSystem.DateTimeOffset比較基準時間點現(xiàn)在或任意錨點cultureSystem.Globalization.CultureInfo輸出使用的語言文化傳null時按運行時文化解析返回值System.String本地化、人性化的時間距離短語如6 hours ago、tomorrow、2 months ago該方法同時實現(xiàn)了接口IDateTimeOffsetHumanizeStrategy.Humanize見 API 文檔的 Implements 段落。input大于comparisonBase時結(jié)果為未來時態(tài)Tense.Future如 from now否則為過去時態(tài)Tense.Past如 ago。三、precision參數(shù)如何驅(qū)動底層算法策略類本身只是一個外殼真正決定輸出文本的算法在 DateTimeHumanizeAlgorithms.cs 中。Humanize的調(diào)用鏈為PrecisionDateTimeOffsetHumanizeStrategy.Humanize→ 取input.UtcDateTime/comparisonBase.UtcDateTime→ DateTimeHumanizeAlgorithms.PrecisionHumanize(DateTime, DateTime, double, CultureInfo)用Math.Abs(comparisonBase.Ticks - input.Ticks)構(gòu)造TimeSpan差值并根據(jù)input comparisonBase判定Tense→ 私有PrecisionHumanize(TimeSpan, Tense, double, CultureInfo)執(zhí)行下面這一級級聯(lián)的閾值進位計算。從源碼結(jié)構(gòu)看精度系數(shù)參與每一級單位進位的判定閾值均為單位上限 × precisionDateTimeHumanizeAlgorithms.cs判定條件以精度系數(shù)p表示效果ts.Milliseconds 999 * pseconds 1seconds 59 * pminutes 1minutes 59 * phours 1hours 23 * pdays 1days 30 * p days 31months 131 days 365 * pfactor floor(days / 30)months days 30 * (factor p) ? factor 1 : factordays 365 * p days 366years 1days 365factor floor(days / 365)years days 365 * (factor p) ? factor 1 : factor理解precision數(shù)值含義的關(guān)鍵系數(shù)越大進位閾值越低結(jié)果越偏向向上取整。以默認值p 0.75為例59 × 0.75 44.25即某一級剩余 45 秒就會被進位為 1 分鐘23 × 0.75 17.25即 18 小時即會被表述為 1 天a day30 × 0.75 22.5即 23 天即被表述為 1 個月。進位完成后算法按大單位優(yōu)先的順序選取第一個非零單位作為輸出years → months → days → hours → minutes → seconds全為 0 時輸出毫秒級剛剛短語并調(diào)用Configurator.GetFormatter(culture).DateHumanize(TimeUnit, Tense, count)生成最終本地化文本。這意味著輸出短語會隨culture切換語言且完全由IFormatter決定措辭如英文中 1 天差值是 a day ago / tomorrow 這類特化表達。與DefaultHumanize固定閾值算法見 DateTimeHumanizeAlgorithms.cs的差別在于默認策略的閾值是寫死的經(jīng)驗值TotalMilliseconds 500、TotalSeconds 120、TotalDays 28等且月份換算使用29.5天/月、365天/年的除數(shù)精度策略則把所有邊界都收斂到同一個可調(diào)系數(shù)p上語義更一致、行為更可預(yù)測。四、接入方式通過Configurator.DateTimeOffsetHumanizeStrategyHumanizer 的策略模式入口是 Configurator/// summary /// The strategy to be used for DateTimeOffset.Humanize /// /summary public static IDateTimeOffsetHumanizeStrategy DateTimeOffsetHumanizeStrategy { get; set; } new DefaultDateTimeOffsetHumanizeStrategy();DateTimeOffset.Humanize擴展方法DateHumanizeExtensions.cs并不直接內(nèi)置算法而是委托給該全局策略public static string Humanize(this DateTimeOffset input, DateTimeOffset? dateToCompareAgainst null, CultureInfo? culture null) { var comparisonBase dateToCompareAgainst ?? DateTimeOffset.UtcNow; return Configurator.DateTimeOffsetHumanizeStrategy.Humanize(input, comparisonBase, culture); }因此切換到精度策略的完整用法是using Humanizer; using System.Globalization; // 1) 在應(yīng)用啟動時把 DateTimeOffset 的人性化策略替換為精度策略 Configurator.DateTimeOffsetHumanizeStrategy new PrecisionDateTimeOffsetHumanizeStrategy(0.75); // 2) 之后所有 DateTimeOffset.Humanize 調(diào)用都走精度算法 var baseTime new DateTimeOffset(2015, 7, 4, 5, 0, 0, TimeSpan.Zero); var inputTime new DateTimeOffset(2015, 7, 5, 4, 0, 0, TimeSpan.Zero); Console.WriteLine(inputTime.Humanize(baseTime)); // tomorrow Console.WriteLine(((DateTimeOffset?)null).Humanize()); // never // 也可以不經(jīng)過擴展方法直接調(diào)用策略實例便于測試與 A/B 對比 var strategy new PrecisionDateTimeOffsetHumanizeStrategy(0.75); var a new DateTimeOffset(2019, 1, 27, 0, 0, 0, TimeSpan.Zero); var b new DateTimeOffset(2019, 3, 29, 0, 0, 0, TimeSpan.Zero); Console.WriteLine(strategy.Humanize(a, b, CultureInfo.InvariantCulture)); // 2 months agoConfigurator的文檔注釋對該屬性有明確的工程約束見 Configurator.cs 的remarks該屬性應(yīng)只在應(yīng)用啟動階段、任何人性化操作發(fā)生之前設(shè)置一次多線程環(huán)境下讀取時應(yīng)考慮可見性volatile 或同步生產(chǎn)環(huán)境中不建議在開始對外服務(wù)后再更換策略實例。上述代碼示例應(yīng)遵循這一約束編寫。五、單元測試給出的行為證據(jù)DateTimeOffsetHumanizeTests.cs 為精度策略提供了多組可直接復(fù)現(xiàn)的行為基線測試類統(tǒng)一使用[UseCulture(en-US)]跨日跨時區(qū)場景PrecisionStrategy_SameOffset2015-07-05 04:00Z相對2015-07-04 05:00Z差值 23 小時。由于23 23 × 0.75 17.25觸發(fā)小時→天進位最終輸出tomorrowDateTimeOffsetHumanizeTests.cs。不同 offset 場景PrecisionStrategy_DifferentOffsets02:00與-05:00兩個 offset 下的時間點差值為 6 小時 15 分鐘輸出6 hours ago驗證了按UtcDateTime比較、offset 不影響結(jié)果的實現(xiàn)路徑DateTimeOffsetHumanizeTests.cs。月份區(qū)間取整PrecisionStrategy_TwoMonthsAroundSixtyDays以2019-03-29為基準2019-01-27/28/29差 57~59 天三種輸入均輸出2 months ago。這正對應(yīng)算法中factor floor(days / 30) 1、且days 30 × (1 0.75) 52.5時取factor 1 2的分支DateTimeOffsetHumanizeTests.cs。本地化回歸Humanize_UsesSpecifiedCulture以多語言MemberData批量斷言1 天前與2 天前的輸出與Configurator.GetFormatter(culture).DateHumanize(...)完全一致驗證了策略對culture參數(shù)的透傳行為DateTimeOffsetHumanizeTests.cs??煽罩剌dNever/Nullable_ExpectSameDateTimeOffset?為null時輸出never非空可空值與直接調(diào)用結(jié)果一致DateTimeOffsetHumanizeTests.cs。以上用例說明精度策略的輸出是確定性的——只要precision、兩個時間點與culture固定輸出即可復(fù)現(xiàn)這對測試與產(chǎn)品文案對齊都很友好。六、選型建議與適用邊界結(jié)合源碼與測試證據(jù)可以給出如下實踐要點何時使用當你希望時間距離表述遵循一套統(tǒng)一的近似比例例如統(tǒng)一按 75% 閾值向上取整而不是默認策略里 500 毫秒/120 秒/90 分鐘這類分散的經(jīng)驗閾值時切換到PrecisionDateTimeOffsetHumanizeStrategy更合適它同樣適合作為 A/B 測試基線或自定義算法的參照實現(xiàn)。精度的調(diào)節(jié)方向precision增大 → 各級進位提前表述更整precision減小 → 表述更保守、更接近原始差值。默認值 0.75 是官方文檔與測試用例共同使用的取值未經(jīng)驗證前不建議改動其含義假設(shè)。輸出只取單一單位算法只輸出最大非零單位如 2 天 3 小時會輸出 2 days ago 而不是 2 days 3 hours ago這是精度策略與某些多單位時間格式化方案的本質(zhì)區(qū)別。偏移量語義比較始終基于 UTC 時刻UtcDateTime跨時區(qū)數(shù)據(jù)可以直接比較無需手動轉(zhuǎn)換。線程與初始化約束Configurator.DateTimeOffsetHumanizeStrategy的文檔明確要求啟動時設(shè)置一次如需按請求切換精度建議直接使用new PrecisionDateTimeOffsetHumanizeStrategy(p).Humanize(...)調(diào)用策略實例而不是改寫全局屬性。本文引用的核心文件策略實現(xiàn)、算法核心、全局配置、擴展方法入口 與 行為測試可沿這些路徑繼續(xù)深入閱讀。贊分享開發(fā)工具【免費下載鏈接】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點擊查看免費下載相關(guān)推薦open-code-review 接入 MCP 服務(wù)器擴展代碼審查 Agent 的上下文與工具能力open code review 接入 MCP 服務(wù)器擴展代碼審查 Agent 的上下文與工具能力 本文以 open code review 的 MCPMo開發(fā)工具Humanizer 中 DefaultDateTimeOffsetHumanizeStrategy 源碼解析DateTimeOffset 相對時間人性化默認策略Humanizer 中 DefaultDateTimeOffsetHumanizeStrategy 源碼解析DateTimeOffset 相對時間人性化默認策開發(fā)工具Humanizer PrecisionDateOnlyHumanizeStrategy 詳解為 DateOnly 相對時間定制精確閾值Humanizer PrecisionDateOnlyHumanizeStrategy 詳解為 DateOnly 相對時間定制精確閾值 本文圍繞 Humani開發(fā)工具上一篇終極MoneyPrinter前端交互設(shè)計Web界面操作全解析下一篇PaddleGAN終極教程用MPRNet實現(xiàn)專業(yè)級圖像去模糊與去噪創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考