亚洲欧美日韩国产成人|亚洲中文字幕无码中字|HEYZO在线无码综合|久久久不卡精品国产一区二|久久精品亚洲无中文东京热|中文字幕乱码一区三区免费|亚洲国产欧美在线观看片不卡|国产精品久久一区二区三区97

怎么可以錯(cuò)過(guò)(時(shí)間復(fù)雜度o1的算法有哪些)時(shí)間復(fù)雜度為o1的算法,你永遠(yuǎn)無(wú)法理解時(shí)間 (四)編程復(fù)雜度:時(shí)間表示與運(yùn)算,400大寫(xiě),

保健品 nanfang 2023-12-26 02:27 151 0

1.時(shí)間復(fù)雜度是o(1)的算法

本文繼續(xù)介紹計(jì)算機(jī)系統(tǒng)對(duì)時(shí)間的處理策略,并分類(lèi)介紹時(shí)間處理的謬誤與陷阱注意:《編程復(fù)雜性》系列只算是半成品受筆者見(jiàn)識(shí)所限,文中提及的內(nèi)容可能遠(yuǎn)不及時(shí)間編程的復(fù)雜之萬(wàn)一,歸類(lèi)也可能并不準(zhǔn)確,很多陷阱都是盤(pán)根錯(cuò)節(jié),難以理清。

2.時(shí)間復(fù)雜度o(1)是什么意思

無(wú)武漢城中村效的時(shí)間表示無(wú)效時(shí)間表示指給定的時(shí)間表示形式無(wú)法正確定位所指向的時(shí)間,通常由于該時(shí)間超出了表示形式所支持的時(shí)間范圍,或時(shí)間表示形式具有歧義性背景:計(jì)算機(jī)系統(tǒng)時(shí)間表示在計(jì)算機(jī)系統(tǒng)內(nèi)表示時(shí)間通常有兩種形式:?jiǎn)沃担ń^對(duì)時(shí)間, absolute time)和多值(民用時(shí)間, civil time)。

3.時(shí)間復(fù)雜度o(1)和o(2)

單值時(shí)間的通常表示形式為:基于某個(gè)時(shí)間錨點(diǎn),該時(shí)間距離錨點(diǎn)的時(shí)間差例如:Unix Time 是當(dāng)前時(shí)間距離 1970/1/1T00:00:00Z UTC 時(shí)間為錨點(diǎn)的時(shí)間差,通常為秒數(shù)或更細(xì)粒度的時(shí)間單位。

4.時(shí)間復(fù)雜度o(1)的例子

NTP Time format 時(shí)間戳是當(dāng)武漢城中村前時(shí)間距離 1900/1/1T00:00:00Z UTC 時(shí)間錨點(diǎn)的時(shí)間差NTP 的時(shí)間戳有 8 字節(jié)前 4 字節(jié)是作為無(wú)符號(hào)整型,表示秒數(shù);后 4 字節(jié)表示次秒粒度。

5.時(shí)間復(fù)雜度o(n)定義

多值時(shí)間的表示通常將“年/月/日/時(shí)/分/秒/… ”作為一個(gè)時(shí)刻的子組件例如 Python 的 datetimes 是使用以下的八元組表示:(year, month, day, hour, minute, second, microsecond, [optional] tzinfo)。

6.時(shí)間復(fù)雜度為o(n!)

忽略閏秒后,Unix 時(shí)間與標(biāo)準(zhǔn)日有著精確的對(duì)應(yīng)關(guān)系因此,Unix 時(shí)間與 UTC 時(shí)間形成了武漢城中村一一映射關(guān)系同樣,一旦時(shí)區(qū)信息描述了與 UTC 的精確時(shí)差,本地時(shí)間與 UTC 可以形成一一映射關(guān)系因此,假設(shè)以下條件滿足,絕對(duì)時(shí)間與民用時(shí)間是等價(jià)(即可以相互轉(zhuǎn)換)的:。

7.時(shí)間復(fù)雜度為o(nlogn)的算法

絕對(duì)時(shí)間忽略閏秒民用時(shí)間包含時(shí)區(qū)信息,且以與 UTC 時(shí)差形式存在時(shí)間表示的局限通常有兩類(lèi):歷法局限性:所使用的歷法只支持有限時(shí)間區(qū)間例如,格里高里歷從 1582 年開(kāi)始定義,無(wú)法嚴(yán)格表示 1582 年之前的時(shí)間。

8.時(shí)間復(fù)雜度o(n1/2)

實(shí)現(xiàn)局限性:指時(shí)間庫(kù)的實(shí)現(xiàn)導(dǎo)致的人為局限例如,Python 的時(shí)間庫(kù)只支持 0001-9999 年實(shí)現(xiàn)局限性實(shí)現(xiàn)的局限性的出現(xiàn)是由于追求實(shí)現(xiàn)的低復(fù)雜武漢城中村度,而放棄對(duì)少見(jiàn)場(chǎng)景或復(fù)雜情況的支持時(shí)間庫(kù)的取舍在當(dāng)時(shí)可能是合理的,但是隨著時(shí)間(!)的推進(jìn),可能原來(lái)合理的設(shè)計(jì)會(huì)帶來(lái)新的問(wèn)題。

9.時(shí)間復(fù)雜度o(n2)表明算法

典型的問(wèn)題有數(shù)值溢出、超出區(qū)間和精度不足數(shù)值溢出Year 2000/Y2Khttps://en.wikipedia.org/wiki/Year_2000_problem最著名的千年蟲(chóng)問(wèn)題在上古時(shí)期計(jì)算機(jī)資源還非常昂貴的時(shí)候,一位數(shù)字的增減都可能會(huì)造成可觀的影響。

10.時(shí)間復(fù)雜度o(e)和o(1)區(qū)別

為了節(jié)省資源,有相當(dāng)?shù)碾娔X系統(tǒng)從 COBOL 年代使用 YYMMDD 六位數(shù)字表示日期顯然,2000 年無(wú)法被正常地識(shí)別當(dāng)時(shí)預(yù)估 Y2K 可武漢城中村能會(huì)造成最高 6000 億美元的經(jīng)濟(jì)損失不過(guò),這個(gè)問(wèn)題雖然很著名,其實(shí)際上造成的影響并不像當(dāng)時(shí)媒體宣傳得那么嚴(yán)重。

當(dāng)然,有可能得益于媒體關(guān)注,使得政府和公司等都在 2000 年到來(lái)前花費(fèi)了大量精力修復(fù)相關(guān)問(wèn)題,避免了最壞情況的發(fā)生當(dāng)時(shí)有不少人認(rèn)為這是一種病毒(甚至有人以為這是一種真正的病毒),以為末日即將來(lái)臨,甚至開(kāi)始囤水囤食物。

例如在香港,有不少騙徒宣稱(chēng)有千年蟲(chóng)蛀蟲(chóng)藥,誘騙對(duì)千年蟲(chóng)問(wèn)題一知半解的民眾購(gòu)買(mǎi),是當(dāng)時(shí)典型的街頭騙案Year 2022微軟 Exchange 服務(wù)器出現(xiàn) 2022 年日期 Bug,暫時(shí)無(wú)法處理郵件,目前處理情況如何?- 知乎

2022 年的開(kāi)年大事故微軟的 Exchang武漢城中村e 服務(wù)器出現(xiàn)問(wèn)題,無(wú)法處理郵件事故原因很簡(jiǎn)單,Exchange 使用 YYMMDDHHMMSS 的整數(shù)格式存儲(chǔ),導(dǎo)致在 2022 年新年時(shí)超過(guò)了 int32 最大值 2147483648,導(dǎo)致溢出。

Exchange 當(dāng)時(shí)緊急使用了 211233000001 這種格式來(lái)表示 2022/1/2,續(xù)了一命后續(xù)修復(fù)了這個(gè)問(wèn)題這是一個(gè)典型的風(fēng)險(xiǎn)后置的例子 —— 好好的跑著的代碼改它干嘛?出事了再說(shuō)Year 2036。

前文提及, NTP Time Format 使用 32 bit unsigned int 來(lái)表示從 1900/01/01 開(kāi)始的秒數(shù)大部分人在使用時(shí)間戳?xí)r往往沒(méi)有感受,但其實(shí)一年有很多秒,武漢城中村2^31 秒只能表示大約 68 年的時(shí)間區(qū)間。

seconds_per_year = 365 * 86400 = 31536000presentable_years = 2147483648 / seconds_per_year = 68由于 NTP 無(wú)符號(hào)整型,所以它可以表示大約 68 * 2 = 136 年的時(shí)間區(qū)間。

NTP 是從 1900/01/01 作為錨定時(shí)間,所以它在 2036 年就會(huì)轉(zhuǎn)期,重新從 0 開(kāi)始計(jì)數(shù)離現(xiàn)在還有 14 年,這是下一個(gè)千年蟲(chóng)預(yù)祝所有的系統(tǒng)都可以正確地處理 NTP 的轉(zhuǎn)期這個(gè)問(wèn)題相對(duì)不嚴(yán)重,因?yàn)?nbsp;NTP 時(shí)間表示通常只在操作系統(tǒng)層面處理,不會(huì)透?jìng)鞯杰浖用妗?a style="color: red;">武漢城中村就是 NTP 時(shí)間表示通常不會(huì)用來(lái)作為時(shí)間的儲(chǔ)存格式。

所以只要操作系統(tǒng)及時(shí)更新即可另外,NTP Date Format 是更新的 NTP 格式,已經(jīng)轉(zhuǎn)換為了 128 bit int 來(lái)表示時(shí)間,使用 64 bit 表示秒這在宇宙完結(jié)之前應(yīng)該不會(huì)溢出了Year 2038

前文提及,2^31 秒只能覆蓋約 68 年的時(shí)間而 Unix Time 默認(rèn)是用 signed 32 bit int 來(lái)表示秒數(shù),所以只能表示約 68 年的時(shí)間Unix Time 是將 1970/01/01 作為錨點(diǎn),所以它將會(huì)在 2038 年溢出。

Y2038 是一個(gè)堪比 Y2K 的嚴(yán)重問(wèn)題當(dāng)前大部分操作系統(tǒng)和比較知名的庫(kù)都做了適武漢城中村配并且進(jìn)行了更新但是可以預(yù)見(jiàn),到時(shí)一定會(huì)有一些老的系統(tǒng)會(huì)雞飛狗跳,并且再發(fā)生一串事故超出區(qū)間Year 1970無(wú)法使用 Unix time 表示任何 1970-01-01 之前的數(shù)字。

負(fù)值的 Unix time 是未定義的因此,不要使用 Unix time 表示所有可能早于 1970 年的時(shí)間例如,不要使用 Unix time 存儲(chǔ)的生日說(shuō)起來(lái)您可能不信,但是這個(gè)世界上有人是早于 1970 年出生的。

Year 9999Python 時(shí)間庫(kù)使用民用時(shí)存儲(chǔ)時(shí)間它的年份的范圍是 datetime.MINYEAR (Year 1) 至 datetime.MAXYEAR (Year 9999)使用 Py武漢城中村thon 時(shí)間庫(kù)存儲(chǔ)超過(guò)公元 9999 年會(huì)有問(wèn)題。

在天文學(xué)等領(lǐng)域,已經(jīng)開(kāi)始造成困惑精度不足歷史上,CPU 的時(shí)鐘頻率很低,無(wú)法提供高精度的時(shí)間因此,有著久遠(yuǎn)歷史的計(jì)算機(jī)系統(tǒng)在涉及時(shí)間時(shí),往往會(huì)將其設(shè)計(jì)為較低的精度但現(xiàn)在隨著 CPU 時(shí)鐘頻率的提高,以及計(jì)算機(jī)應(yīng)用對(duì)更高的精度的要求,這使得這些系統(tǒng)可能會(huì)造成精度損失。

當(dāng)前,隨著 CPU 時(shí)鐘頻率的提升,大部分新的時(shí)間提供函數(shù)可以返回 ns 的精度但是要注意,這并不意味著這些函數(shù)的準(zhǔn)確度是 ns 級(jí)別注意這兩者的區(qū)別是:精度是測(cè)量值之間的差值準(zhǔn)確度是測(cè)量值與真實(shí)值之間的誤差。

首先,即使時(shí)間函數(shù)返回值的精度是 ns 級(jí)別,也不能說(shuō)明所有的返回值的精武漢城中村度(即時(shí)鐘精度)實(shí)際上是 ns 級(jí)別時(shí)鐘的真實(shí)精度取決于操作系統(tǒng)和硬件實(shí)現(xiàn)其次,前文提到過(guò),由于時(shí)鐘漂移,所以系統(tǒng)時(shí)鐘與真實(shí)時(shí)間一定會(huì)產(chǎn)生相對(duì)的偏差。

偏差值比實(shí)際精度的規(guī)模會(huì)大得多例如,如果 ntpd 每天同步時(shí)間,極可能會(huì)有 0.1 秒的偏差時(shí)間函數(shù)精度 <= 時(shí)鐘精度 <<= 時(shí)鐘偏差過(guò)度簡(jiǎn)化的時(shí)間表示主要指在時(shí)間表示時(shí)忽略必要的信息所導(dǎo)致的問(wèn)題。

民用時(shí)間不記錄時(shí)區(qū)如果不涉及國(guó)際化業(yè)務(wù),一般會(huì)為了簡(jiǎn)單起見(jiàn),使用民用時(shí)間存儲(chǔ)時(shí)間戳?xí)r,不存儲(chǔ)對(duì)應(yīng)時(shí)區(qū),而依賴(lài)系統(tǒng)自帶時(shí)區(qū)(通常是所在地時(shí)區(qū))這樣做的主要問(wèn)題是,并沒(méi)有公認(rèn)“正確”的本地時(shí)區(qū) -- 到底應(yīng)該使用某個(gè)固定的時(shí)區(qū)(如東八區(qū)),還是 UT武漢城中村C,還是使用數(shù)據(jù)中心所在的時(shí)區(qū)?。

在國(guó)內(nèi),8 小時(shí)是一個(gè)神奇的常數(shù)一旦發(fā)現(xiàn)記錄的時(shí)間和預(yù)期相差 8 個(gè)小時(shí),往往是因?yàn)槟承┑胤皆O(shè)置了時(shí)區(qū)而某些地方未設(shè)置時(shí)間一個(gè)可行(但不完備)的檢驗(yàn)是在單元測(cè)試中修改你的系統(tǒng)時(shí)區(qū),檢查測(cè)試是否仍然通過(guò)系統(tǒng)時(shí)區(qū)通過(guò) TZ 環(huán)境變量定義。

例如在 Bazel 中,默認(rèn)時(shí)間是 UTC可以通過(guò)設(shè)置 --test_env=TZ=Asia/Shanghai 調(diào)整時(shí)間為中國(guó)標(biāo)準(zhǔn)時(shí)間(CST)如果添加 --test_env=TZ=Asia/Shanghai。

與否會(huì)影響測(cè)試是否通過(guò),那么代碼中存在潛在的風(fēng)險(xiǎn)變更系統(tǒng)時(shí)區(qū)也是高危操作這可能會(huì)導(dǎo)致非常隱蔽的問(wèn)題發(fā)生考慮以下案例:CTO武漢城中村 們上任最喜歡干的一件事就是歸零化,即統(tǒng)一所有機(jī)房的時(shí)區(qū)到 UTC這確實(shí)是個(gè)基本無(wú)害的優(yōu)化 —— 唯一的缺點(diǎn)是確實(shí)可能有害。

假設(shè)我們有一個(gè) CRON job,定期轉(zhuǎn)賬5 2 * * 1-5 # "At 02:05 on every day-of-week from Monday through Friday."注意 CRON 使用的是 $TZ 環(huán)境變量給出的系統(tǒng)時(shí)區(qū)。

本來(lái)是 UTC+8,轉(zhuǎn)換為 UTC,相當(dāng)于時(shí)鐘回調(diào) 8 個(gè)小時(shí)那么,如果在今天已經(jīng)轉(zhuǎn)過(guò)一次賬,回調(diào) 8 個(gè)小時(shí)后,CRON 可能會(huì)在這一天再次觸發(fā)轉(zhuǎn)賬某些系統(tǒng)提供了 CRON_TZ 作為 CRON job 的時(shí)區(qū)。

顯式地聲明 Cr武漢城中村on 的時(shí)區(qū)有利于減少無(wú)意識(shí)更改時(shí)區(qū)而導(dǎo)致 Cron 錯(cuò)誤觸發(fā)的問(wèn)題以下是幾個(gè)導(dǎo)致事故的例子:https://blog.davidojeda.dev/4-time-zone-bugs-i-ran-into#the-bug-wrong-database-time-zone

建議升級(jí) clickhouse-go 驅(qū)動(dòng) · gohangout · GitHubGo MySql driver doesnt set time correctly - Stack Overflow時(shí)間戳缺少單位

指使用數(shù)值 timestamp 表示一個(gè)時(shí)刻但是,該 timestamp 并沒(méi)有標(biāo)明單位這使用戶很難猜測(cè)到底是什么單武漢城中村位把 timestamp 按錯(cuò)誤的單位理解會(huì)導(dǎo)致各種問(wèn)題發(fā)生時(shí)間運(yùn)算本章討論對(duì)時(shí)間進(jìn)行運(yùn)算的易錯(cuò)點(diǎn)。

中文里,“時(shí)間”具有多義性,可以表示:Time,即時(shí)間這個(gè)抽象概念I(lǐng)nstant,即時(shí)間點(diǎn),或時(shí)刻在英文中,Time 通常也會(huì)用以表示 Instant,如 what time is it?Duration,即時(shí)間量,或時(shí)長(zhǎng)。

當(dāng)討論“時(shí)間”,需要明確到底是時(shí)間點(diǎn)還是時(shí)間量非平凡的時(shí)間運(yùn)算通常有兩種:Instant + Duration = Instant,即給定一個(gè)時(shí)間點(diǎn),和一個(gè)時(shí)間偏移量,計(jì)算經(jīng)過(guò)偏移后的時(shí)間點(diǎn)Instant - Instant = Duration。

,即計(jì)算兩個(gè)時(shí)間之間的時(shí)間量武漢城中村差值(Duration +/- Duration = Duration 是平凡運(yùn)算,這里不贅述Instant + Instant 是不良定義的)前文提及了兩種時(shí)間表示:絕對(duì)時(shí)間和民用時(shí)間,并且提及兩者在絕大多數(shù)情況下可以互相轉(zhuǎn)化。

所以,時(shí)間點(diǎn)用絕對(duì)時(shí)間還是用民用時(shí)間表示,通常并沒(méi)有影響運(yùn)算的復(fù)雜之處在于時(shí)間量(Duration)前文介紹過(guò),由于以下原因,絕對(duì)時(shí)間和民用時(shí)間的時(shí)間量并沒(méi)有穩(wěn)定的對(duì)應(yīng)關(guān)系:一年有 365 天(閏年)一月有 30 天。

(每個(gè)月的天數(shù)都不盡相同)一天有 24 小時(shí)(夏令時(shí))一小時(shí)有 60 分鐘(夏令時(shí))一分鐘有 60 秒(閏秒)例如,當(dāng)我們說(shuō)“一個(gè)月后”,我們可能是指:武漢城中村30 天(30 * 86400 秒)后下個(gè)月同一日的同一時(shí)刻:由于上述的各種原因,“下一月同一日的同一時(shí)刻”有非常非常多的可能性。

為了方便起見(jiàn), 本文沿用 Joda Time 的術(shù)語(yǔ) Duration/Period 來(lái)區(qū)分兩個(gè)概念:Duration 是實(shí)耗時(shí)間/運(yùn)行時(shí)間的絕對(duì)時(shí)間的長(zhǎng)度Duration 的時(shí)間是絕對(duì)的,并且不受起始/終止時(shí)間影響。

Duration 可以通過(guò)秒、標(biāo)準(zhǔn)時(shí)、標(biāo)準(zhǔn)日等具有絕對(duì)時(shí)長(zhǎng)定義的單位表示例如,一小時(shí)指一標(biāo)準(zhǔn)時(shí),即 3600 秒一天指一標(biāo)準(zhǔn)日,即 86400 秒Period 作為運(yùn)行時(shí)間考慮到歷法系統(tǒng)的民用時(shí)長(zhǎng)度Period 的表示可以是自然天/年,因此 Perio武漢城中村d 的實(shí)耗時(shí)間(即 Duration)受起始時(shí)間的影響。

例如,2022.3.1 開(kāi)始的一自然年與 2023.3.1 開(kāi)始的一自然年時(shí)長(zhǎng)不同,后者由于閏年,多一自然天在日常開(kāi)發(fā)中,算術(shù)操作導(dǎo)致的問(wèn)題主要分為兩類(lèi):混淆 Duration 與 Period運(yùn)算結(jié)果不是有效時(shí)間,或者具有歧義。

以下以幾個(gè)常見(jiàn)場(chǎng)景的例子說(shuō)明可能出現(xiàn)的問(wèn)題計(jì)算 X min 后的時(shí)間考慮以下計(jì)算:Instant + Duration只不過(guò) Instant 是用 DateTime 表示的, Duration 是以 n Hours m Minutes 表示的。

具體怎么做?看上去是一個(gè)很簡(jiǎn)單——進(jìn)位就是例如:2003:09:12:武漢城中村12:57:23 + 2:58 從秒開(kāi)始進(jìn)位 (23 + 58 >= 60),如果溢出繼續(xù)向上進(jìn)位 (57 + 2 + 1 >= 60)。

這樣做會(huì)出現(xiàn)問(wèn)題容易犯錯(cuò),尤其是進(jìn)位可能會(huì)一直上升到年例如,在進(jìn)位月份時(shí),知道該天是不是當(dāng)月的最后一天還涉及到閏年前后需要處理的邊界情況非常多更嚴(yán)重的問(wèn)題是:沒(méi)有考慮時(shí)區(qū)變化,計(jì)算出來(lái)的結(jié)果可能是錯(cuò)誤的。

這里將 Duration 錯(cuò)當(dāng)成了 Period考慮以下情況:# Pacific Time2022-03-13T01:00:00Z + 10800S = ?如果按前文的計(jì)算方式,會(huì)得到錯(cuò)誤的結(jié)果:2022-03-13T04:00:00Z。

但是在 2022-0武漢城中村3-13 凌晨?jī)牲c(diǎn)時(shí),夏令時(shí)開(kāi)始,時(shí)鐘前調(diào)了一個(gè)小時(shí)所以,3 小時(shí)的 Duration 實(shí)際上相差了 4 小時(shí)的 Period計(jì)算兩個(gè)日期之間有幾天一個(gè)常見(jiàn)的任務(wù)是給定兩個(gè)日期,計(jì)算它們相隔相差多少自然天。

考慮下列的常見(jiàn)處理:time_t then_start_of_day = then_day.time()...; // 過(guò)去一天的零點(diǎn),以秒為單位,本地時(shí)間time_t today_start_of_day = today.time()...; // 今天的零點(diǎn),以秒為單位,本地時(shí)間constexpr kSecondsPerDay = 24 * 60 * 60; // 除以標(biāo)準(zhǔn)日時(shí)長(zhǎng)days武漢城中村_between = (today_start_of_day - then_start_of_day) / kSecondsPerDay;

這可能會(huì)出錯(cuò),因?yàn)榘?Period 誤作為 Duration:如果 [then, today] 的某一天因?yàn)?nbsp;夏令時(shí),只有小于 24 小時(shí)的民用時(shí),那么這一天實(shí)際上會(huì)小于 kSecondsPerDay也就是說(shuō),上述的算法由于下取整,會(huì)比實(shí)際的天數(shù) 。

少一天更好的辦法是區(qū)分時(shí)間與日期,調(diào)用時(shí)間庫(kù)計(jì)算 then_day 與 today 日期之間相差的自然日定時(shí)任務(wù)周期性事件是業(yè)務(wù)開(kāi)發(fā)中非常容易遇到的場(chǎng)景而且在大部分場(chǎng)景下,“周期”都是指民用時(shí)間周期,即 Peri武漢城中村od。

通常的例子包括:定期扣費(fèi)、信用卡還單過(guò)生日注意到定時(shí)任務(wù)會(huì)涉及到前述的問(wèn)題——算術(shù)結(jié)果不存在例如:閏年:1992.2.29 出生的人在 2022.2.29 的生日并不存在一月所含天數(shù)不確定:一個(gè)定期在每月 31 號(hào)扣費(fèi)的服務(wù),一年有 5 個(gè)月不存在 31 天。

對(duì)于不存在的時(shí)間,有幾種處理方式?jīng)]有絕對(duì)的正確與否,需要按照業(yè)務(wù)的實(shí)際情況判斷跳過(guò)適用于對(duì)發(fā)生的時(shí)間敏感,但對(duì)是否發(fā)生不敏感的情況例如,往往在 2.29 出生的人每四年過(guò)一次生日跳至最近的有效時(shí)間適用于對(duì)“必須發(fā)生”敏感,但對(duì)于發(fā)生的具體時(shí)間點(diǎn)并不敏感。

例如,按每月 31 號(hào)扣費(fèi)時(shí),每次 31 號(hào)并不存在時(shí)回退到當(dāng)月最后存在的一天等武漢城中村價(jià)于按“每月最后一天”扣費(fèi)報(bào)錯(cuò)或者禁止可能導(dǎo)致無(wú)效的時(shí)間設(shè)定謹(jǐn)慎使用,對(duì)用戶造成影響較大當(dāng)然,還有一個(gè)方案是不使用 Period 而使用絕對(duì)時(shí)間。

月卡,是常見(jiàn)的“一月后的今天”,例如充值續(xù)費(fèi)等應(yīng)該如何定義這一個(gè)月呢?Period/一個(gè)自然月:(MM, DD) -> (MM +1, DD or L)其中,L 是當(dāng)月的最后一天,如果 DD > MM+1 月的天數(shù)。

Duration/“30 天” :續(xù)費(fèi)固定為 30 天使用 Duration 有很多好處:計(jì)算簡(jiǎn)單無(wú)需進(jìn)行復(fù)雜的時(shí)間轉(zhuǎn)換,直接向時(shí)間戳添加 720 小時(shí)即可降本增效注意到假設(shè)用戶在一年的每一天都等概率地按月續(xù)費(fèi)會(huì)員,那么,我們粗略地估計(jì)一武漢城中村年有約 365 天,如果只提供按 30 天續(xù)費(fèi),大約可提升 (365 - 360)/365 = 1/73 的運(yùn)營(yíng)收入。

(注:玩笑)按天聚合數(shù)據(jù)下面的例子是 (Instant - Instant = Period) 的隱蔽問(wèn)題舉個(gè)例子,考慮一個(gè)服務(wù)器在硅谷的業(yè)務(wù),需要按天聚合業(yè)務(wù)數(shù)據(jù)并進(jìn)行數(shù)據(jù)分析一個(gè)自然的做法是:(簡(jiǎn)化實(shí)現(xiàn),不考慮效率等因素)。

val init_date = Date(2015, 3, 24, "US/Mountain View")for i in 0 until 100 { val today = init_date.addDays(i)

val tomorrow = init武漢城中村_date.addDays(i + 1) val daily_events = events_between(today.toMicros(), tomorrow.toMicros())

// daily_events 是每一天的事件}這個(gè)做法看上去很自然,也很合理,好像也沒(méi)有上文所說(shuō)的樸素運(yùn)算導(dǎo)致的問(wèn)題那么,這樣會(huì)有什么風(fēng)險(xiǎn)呢?答案是:會(huì)出現(xiàn)數(shù)據(jù)偏移由于我們通常使用的時(shí)區(qū)是基于地區(qū),tzdata 會(huì)自動(dòng)切換夏令時(shí)。

因此,在一年中切換至夏令時(shí)和切換至常規(guī)時(shí)間的兩天,它們的一天分別有 23 小時(shí)和 25 小時(shí),所以它們雖然確實(shí)是“一天(一自然日)”的數(shù)據(jù),但這一天可能會(huì)比正常日長(zhǎng)或短,可能會(huì)導(dǎo)致數(shù)武漢城中村據(jù)異常這時(shí),如果使用 Duration,反而不會(huì)產(chǎn)生時(shí)長(zhǎng)的偏移。

但這樣會(huì)產(chǎn)生另一個(gè)問(wèn)題:一年會(huì)有大概一半的時(shí)間的聚合不再是從[00:00, 24:00) 算做一天,而會(huì)是 [1:00, 1:00)這樣可能會(huì)導(dǎo)致其它的數(shù)據(jù)偏移發(fā)生另外,即使如此,在夏令時(shí)切換的那兩天,數(shù)據(jù)仍然可能會(huì)產(chǎn)生偏差——因此一天是 。

[0:00, 25:00),而另一天是 [1:00, 24:00),仍然可能產(chǎn)生數(shù)據(jù)的偏移當(dāng)聚合遇上夏令時(shí),沒(méi)有完美的方案理解業(yè)務(wù)模型,進(jìn)而選取更符合業(yè)務(wù)的取樣法重復(fù)的時(shí)間(反方向的鐘)前文提及,夏令時(shí)可能會(huì)導(dǎo)致運(yùn)算的結(jié)果不存在。

但是,更嚴(yán)重的問(wèn)題是夏令時(shí)導(dǎo)致的時(shí)間回調(diào),也就是同一個(gè)本地時(shí)間會(huì)武漢城中村發(fā)生兩次考慮如下時(shí)間,轉(zhuǎn)換成絕對(duì)時(shí)間是多少?date = "2022-11-06T01:30:00Z" Pacific Time答案是:不確定——因?yàn)橄牧顣r(shí)結(jié)束在該天的凌晨?jī)牲c(diǎn)發(fā)生,這時(shí)時(shí)鐘會(huì)回調(diào)一個(gè)小時(shí)。

所以,凌晨一點(diǎn)到兩點(diǎn)的時(shí)間,都會(huì)發(fā)生兩次考慮這個(gè)場(chǎng)景:約定在這個(gè)時(shí)間向用戶轉(zhuǎn)賬 5000 萬(wàn)錯(cuò)誤的處理會(huì)導(dǎo)致轉(zhuǎn)賬兩次這將導(dǎo)致非常嚴(yán)重的事故對(duì)于具有二義性的時(shí)間,有幾種處理方式?jīng)]有絕對(duì)的正確與否,需要按照業(yè)務(wù)的實(shí)際情況判斷:。

觸發(fā)兩次,即在所有可能的時(shí)間解釋下都觸發(fā)適用于對(duì)發(fā)生的時(shí)間敏感,但對(duì)是否重復(fù)發(fā)生不敏感的情況例如鬧鐘觸發(fā)一次,選取回調(diào)前發(fā)生或者回調(diào)后發(fā)生適用于對(duì)于發(fā)生次數(shù)敏感的情況例如武漢城中村定時(shí)支付具體選取哪次,應(yīng)該視業(yè)務(wù)場(chǎng)景而定。

報(bào)錯(cuò)或者禁止可能導(dǎo)致無(wú)效的時(shí)間設(shè)定。謹(jǐn)慎使用,這將對(duì)用戶造成較大影響。下篇繼續(xù)介紹實(shí)際時(shí)間編程時(shí)容易犯的錯(cuò)誤。

標(biāo)簽列表