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