DateTime還是DateTimeOffset?Now還是UtcNow?


(此文章同時發表在本人微信公眾號“dotNET每日精華文章”,歡迎右邊二維碼來關注。)

題記:新年第一篇文章,就來談談關於時間的簡單技術問題:該用DateTime還是DateTimeOffset?該用Now還是UtcNow?

首先需要說明的是.NET中出現兩個保存時間的數據結構是由於歷史的原因。DateTime一開始就出現在.NET的基礎類型中;為了解決DateTime中的一些缺陷,又保證代碼能夠兼容,就多出了一個DateTimeOffset。

DateTime只保存兩部分信息:Ticks和Kind。一個Tick是100納秒(1萬Tick等於1毫秒),Ticks記錄了從1/1/0001 12:00 AM到現在經過了多少100納秒。Kind保存的是DateTimeKind枚舉值,有Utc、Local和Unspecified 。Utc意味着Tick計數表示協調世界時間的數量,其不會受到夏令時或者時區的影響。Local表示本地時間的數量,會受到夏令時的影響。由於DateTime並不保存時區偏移,所以要獲得真正的UTC時間,就會檢查計算機當前的市區設置,那么ToUniversalTime和ToLocalTime方法都會進行這樣的轉換。Kind的第三種值Unspecified,意味着我們不知道到底是本地時間還是UTC時間。所以這種情況只能表示年月日,時間無法精確表示。

DateTime除了存在這個問題,還會在進行比較的時候,其不會考慮Kind是UTC還是Local,從而導致錯誤。DateTime在進行字符串化的時候,對於某些標准格式也會出現問題(根源還是時區的問題),比如ToString("u")的時候,會直接把Local當作UTC來處理。

為了解決上述時區和轉換的問題,DateTimeOffset應運而生。它只保存Ticks,不保存Kind,且Ticks總是相對於UTC的值。

從官方文檔給出的建議來看,我們總是應該使用DateTimeOffset,只有僅僅表示日期和不需要關心時區的時候才使用DateTime。https://msdn.microsoft.com/en-us/library/bb384267.aspx

另外,在Stackoverflow上的這個回答http://stackoverflow.com/a/14268167,也很形象的描述了DateTimeOffset和DateTime的區別和優勢。簡而言之,DateTimeOffset是一種瞬時時間(即絕對時間),DateTime是一種歷法時間(即鍾表時間)。

最后,這兩個數據類型都有Now和UtcNow兩個方法。Now用於獲取現在的時間,UtcNow獲取Utc的現在時間。而實際上,Now內部是先調用UtcNow,然后進行轉換得到。所以,在一般情況下,都應該使用UtcNow。

在文章結束的時候,給大家留個小問題,協調世界時間(Coordinated Universal Time)的簡寫為什么是UTC,而不是CUT?下次文章公布答案。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM