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