到了2038年時(shí)間戳溢出了怎么辦?
當(dāng)前位置:點(diǎn)晴教程→知識管理交流
→『 技術(shù)文檔交流 』
計(jì)算機(jī)中的時(shí)間看完這篇文章相信你會對計(jì)算機(jī)中的時(shí)間有更系統(tǒng)全面的認(rèn)識。 我經(jīng)常自嘲,自己寫的程序運(yùn)行不超過3年,因?yàn)榇蟛糠猪?xiàng)目方就早早跑路了。大多數(shù)項(xiàng)目上線后,你跟這個(gè)項(xiàng)目就再無瓜葛,關(guān)于時(shí)間你只需要保證時(shí)區(qū)正確就不會有太大問題,哈哈。 但是今天我想認(rèn)真對待時(shí)間這個(gè)問題,作為一個(gè)庫作者或基礎(chǔ)軟件作者,就需要考慮下游項(xiàng)目萬一因?yàn)槟闾幚頃r(shí)間不當(dāng)而造成困擾,影響范圍就比較廣了。 計(jì)算機(jī)中與時(shí)間有關(guān)的關(guān)鍵詞: 時(shí)間類型 時(shí)間戳(timestamp) 定時(shí)器(例如js中setInterval()) 時(shí)間計(jì)算 時(shí)間段 超時(shí)(setTimeout()) 時(shí)間片 GMT UTC Unix時(shí)間戳 ISO8601 CST EST 看到這些你可能會疑惑,為何一個(gè)時(shí)間竟然如此復(fù)雜!! 如果下面的問題你都能答上來,那這篇文章對你的幫助微乎其微,不如做些更有意義的事情。
正文開始 1. 兩種時(shí)間標(biāo)準(zhǔn)UTC和GMT都是時(shí)間標(biāo)準(zhǔn),定義事件的精度。它們只表示 零時(shí)區(qū) 的時(shí)間,本地時(shí)間則需要與 時(shí)區(qū) 或偏移 結(jié)合后表示。這兩個(gè)標(biāo)準(zhǔn)之間差距通常不會超過一秒。 UTC(協(xié)調(diào)世界時(shí))UTC,即協(xié)調(diào)世界時(shí)(Coordinated Universal Time),是一種基于原子鐘的時(shí)間標(biāo)準(zhǔn)。它的校準(zhǔn)是根據(jù)地球自轉(zhuǎn)的變化而進(jìn)行的,插入或刪除閏秒的實(shí)際需求在短期內(nèi)是難以預(yù)測的,因此這個(gè)決定通常是在需要校準(zhǔn)的時(shí)候發(fā)布。 閏秒通常由國際電信聯(lián)盟(ITU) 和國際度量衡局(BIPM) 等組織進(jìn)行發(fā)布。由國際原子時(shí)(International Atomic Time,TAI) 通過閏秒 的調(diào)整來保持與地球自轉(zhuǎn)的同步。 GMT(格林尼治標(biāo)準(zhǔn)時(shí)間)以英國倫敦附近的格林尼治天文臺(0度經(jīng)線,本初子午線)的時(shí)間為基準(zhǔn)。使用地球自轉(zhuǎn)的平均速度來測量時(shí)間,是一種相對于太陽的平均時(shí)刻。盡管 GMT 仍然被廣泛使用,但現(xiàn)代科學(xué)和國際標(biāo)準(zhǔn)更傾向于使用UTC。 2. 兩種顯示標(biāo)準(zhǔn)上面我們討論的時(shí)間標(biāo)準(zhǔn)主要保證的是時(shí)間的精度,時(shí)間顯示標(biāo)準(zhǔn)指的是時(shí)間的字符串表示格式。我們熟知的有 RFC 5322 和 ISO 8601。 RFC 5322 電子郵件消息格式的規(guī)范RFC 5322 的最新版本是在2008年10月在IETF發(fā)布的,你閱讀時(shí)可能有了更新的版本。
格式通常如下: Thu, 14 Dec 2023 05:36:56 GMT 時(shí)區(qū)部分為了可讀可以如下表示: Thu, 14 Dec 2023 05:36:56 CST Thu, 14 Dec 2023 05:36:56 +0800 Thu, 14 Dec 2023 05:36:56 +0000 Thu, 14 Dec 2023 05:36:56 Z 但并不是所有程序都兼容這種時(shí)區(qū)格式,通常程序會忽略時(shí)區(qū),在寫程序時(shí)要做好測試。標(biāo)準(zhǔn)沒有定義毫秒數(shù)如何顯示。 需要注意的是,有時(shí)候我們會見到這種格式Tue Jan 19 2038 11:14:07 GMT+0800 (中國標(biāo)準(zhǔn)時(shí)間),這是js日期對象轉(zhuǎn)字符串的格式,它與標(biāo)準(zhǔn)無關(guān),千萬不要混淆了。 ISO 8601ISO 8601 最新版本是 ISO 8601:2019,發(fā)布日期為2019年11月15日,你閱讀時(shí)可能有了更新的版本。 下面列舉一些格式示例: 2004-05-03T17:30:08+08:00 2004-05-03T17:30:08+00:00 2004-05-03T17:30:08Z 2004-05-03T17:30:08.000+08:00 標(biāo)準(zhǔn)并沒有定義小數(shù)位數(shù),保險(xiǎn)起見秒后面一般是3位小數(shù)用來表示毫秒數(shù)。 字母 "Z" 是 "zero"(零)的縮寫,因此它被用來表示零時(shí)區(qū),也可以使用+00:00,但Z更直觀且簡潔。
日期與時(shí)間合并表示時(shí),要在時(shí)間前面加一大寫字母T,如要表示東八區(qū)時(shí)間2004年5月3日下午5點(diǎn)30分8秒,可以寫成2004-05-03T17:30:08+08:00或20040503T173008+08。 在編寫API時(shí)推薦使用ISO 8601標(biāo)準(zhǔn)接收參數(shù)或響應(yīng)結(jié)果,并且做好時(shí)區(qū)測試,因?yàn)椴煌幊陶Z言中實(shí)現(xiàn)可能有差異。 時(shí)區(qū)劃分和偏移全球被分為24個(gè)時(shí)區(qū),每個(gè)時(shí)區(qū)對應(yīng)一個(gè)小時(shí)的時(shí)間差。 時(shí)區(qū)劃分由IANA維護(hù)和管理,其時(shí)區(qū)數(shù)據(jù)庫被稱為 TZ Database(或 Olson Database)。這個(gè)數(shù)據(jù)庫包含了全球各個(gè)時(shí)區(qū)的信息,包括時(shí)區(qū)的名稱、標(biāo)識符、以及歷史性的時(shí)區(qū)變更數(shù)據(jù),例如夏令時(shí)的開始和結(jié)束時(shí)間等。在許多操作系統(tǒng)(如Linux、Unix、macOS等)和編程語言(如Java、Python等)中得到廣泛應(yīng)用。 TZ Database具體見我整理的表格,是從Postgresql中導(dǎo)出的一份Excel,關(guān)注公眾號"程序飼養(yǎng)員",回復(fù)"tz" 時(shí)區(qū)標(biāo)識符采用"洲名/城市名"的命名規(guī)范,例如:"America/New_York"或"Asia/Shanghai"。這種命名方式旨在更準(zhǔn)確地反映時(shí)區(qū)的地理位置。時(shí)區(qū)的具體規(guī)定和管理可能因國家、地區(qū)、或國際組織而異。 有一些時(shí)區(qū)是按照半小時(shí)或15分鐘的間隔進(jìn)行偏移的,以適應(yīng)地理和政治需求。在某些地區(qū),特別是位于邊界上的地區(qū),也可能采用不同的時(shí)區(qū)規(guī)則。 EST,CST、GMT(另外一個(gè)含義是格林尼治標(biāo)準(zhǔn)時(shí)間)這些都是時(shí)區(qū)的縮寫。 這種簡寫存在重復(fù),如CST 可能有多種不同的含義,China Standard Time(中國標(biāo)準(zhǔn)時(shí)間),它對應(yīng)于 UTC+8,即東八區(qū)。Central Standard Time(中部標(biāo)準(zhǔn)時(shí)間) 在美國中部標(biāo)準(zhǔn)時(shí)間的縮寫中也有用。中部標(biāo)準(zhǔn)時(shí)間對應(yīng)于 UTC-6,即西六區(qū)。因此在某些軟件配置時(shí)不要使用簡稱,一定要使用全稱,如”Asia/Shanghai“。 采用東八區(qū)的國家和地區(qū)有哪些
計(jì)算機(jī)系統(tǒng)中的時(shí)間 —— Unix時(shí)間戳Unix時(shí)間戳(Unix timestamp)定義為從1970年01月01日00時(shí)00分00秒(UTC)起至現(xiàn)在經(jīng)過的總秒數(shù)(秒是毫秒、微妙、納秒的總稱)。 這個(gè)時(shí)間點(diǎn)通常被稱為 "Epoch" 或 "Unix Epoch"。時(shí)間戳是一個(gè)整數(shù),表示從 Epoch 開始經(jīng)過的秒數(shù)。 一些關(guān)鍵概念:
為什么是1970年1月1日?這個(gè)選擇主要是出于歷史和技術(shù)的考慮。 Unix 操作系統(tǒng)的設(shè)計(jì)者之一,肯·湯普森(Ken Thompson)和丹尼斯·里奇(Dennis Ritchie)在開發(fā) Unix 操作系統(tǒng)時(shí),需要選擇一個(gè)固定的起始點(diǎn)來表示時(shí)間。1970-01-01 00:00:00 UTC 被選為起始時(shí)間。這個(gè)設(shè)計(jì)的簡潔性和通用性使得 Unix 時(shí)間戳成為計(jì)算機(jī)系統(tǒng)中廣泛使用的標(biāo)準(zhǔn)方式來表示和處理時(shí)間。 時(shí)間戳為什么只能表示到2038年01月19日03時(shí)14分07秒?在許多系統(tǒng)中,結(jié)構(gòu)體time_t 被定義為 long,具體實(shí)現(xiàn)取決于編譯器和操作系統(tǒng)的架構(gòu)。例如,在32位系統(tǒng)上,time_t 可能是32位的 long,而在64位系統(tǒng)上,它可能是64位的 long。 32位有符號long類型,實(shí)際表示整數(shù)只有31位,最大能表示十進(jìn)制2147483647(01111111 11111111 11111111 11111111)。 > new Date(2147483647000) < Tue Jan 19 2038 11:14:07 GMT+0800 (中國標(biāo)準(zhǔn)時(shí)間) 實(shí)際上到2038年01月19日03時(shí)14分07秒,便會到達(dá)最大時(shí)間,過了這個(gè)時(shí)間點(diǎn),所有32位操作系統(tǒng)時(shí)間便會變?yōu)?0000000 00000000 00000000 00000000。因具體實(shí)現(xiàn)不同,有可能會是1901年12月13日20時(shí)45分52秒,這樣便會出現(xiàn)時(shí)間回歸的現(xiàn)象,很多軟件便會運(yùn)行異常了。 至于時(shí)間回歸的現(xiàn)象相信隨著64位操作系統(tǒng)的產(chǎn)生逐漸得到解決,因?yàn)橛?4位操作系統(tǒng)可以表示到292,277,026,596年12月4日15時(shí)30分08秒。 另外,考慮時(shí)區(qū)因素,北京時(shí)間的時(shí)間戳的起始時(shí)間是1970-01-01T08:00:00+08:00。
該文章在 2024/2/19 11:46:17 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |