隨心所欲的DateTime續--變化的時區(1)


上篇提到DateTime的顯示格式,忽略了一個重要元素--時區。多時區用戶的項目的時間顯示問題常常被人詬病,一旦時間跟金錢掛鈎,出了問題就不是客服投訴罵兩句那么簡單了。那么究竟怎樣才能構建一個滿足多時區用戶的項目呢?這要先從時區說起。

時區知多少

timezones-map

如圖,全球被划分為24個時區,0時區為基准,每個時區相隔1小時,往東則加時間,往西則減時間,這種記時方式成為UTC(協調世界時)。比如北京在東邊第八個時區,簡稱東八區,而東八區可簡寫為“UTC +8”。

在人類科技尚不發達的早期,人們用天文學知識計算時區時間,稱為GMT(格林威治時間)。這種方式略有誤差,但日常生活並不影響,后來隨着科技的進步漸漸被UTC取代,但依然有人習慣性稱GMT時間,因此,對我們來說,UTC和GMT意思等同。

在.Net中,用DateTimeUtcNow屬性可快速獲取0時區的時間,以我們所處的“UTC +8”為例,兩者相差8小時:

Console .WriteLine( DateTime .Now);     // 2012/12/21 11:50:37
Console .WriteLine( DateTime .UtcNow); // 2012/12/21 3:50:37

可定義時區的時間類-- DateTimeOffSet

DateTime類沒有時區信息,默認當前機器的時區。如果想指定時區,可使用DateTimeOffset類,時差用TimeSpan表示。比如,以下代碼分別獲取當前“UTC +2”和“UTC -5”的時間:

DateTimeOffset dt = new DateTimeOffset ( DateTimeOffset .UtcNow.DateTime, TimeSpan .FromMinutes(120));
DateTimeOffset dt2 = new DateTimeOffset ( DateTimeOffset .UtcNow.DateTime, TimeSpan .FromMinutes(-300));

為了方便,我用小時計算時差,但更准確的的單位應該用分鍾。因為時區雖按小時划分,但有些城市地區所在的時區並不是整數,比如印度的新德里在東5.5區,加拿大的紐芬蘭在西3.5區,還有一個逆天的尼泊爾在東5.45區,因此把時差換算為分鍾更為准確。

注:本來第一個參數使用DateTime.UtcNow,結果會拋出異常。因為第一個參數必須是時區為0的DataTime,而通過DateTime類屬性獲取的時間會默認當前機器的時區,因此,改成DateTimeOffset.UtcNow.DateTime就沒有問題。

DateTime雖然默認了時區值,但無法獲取,如要訪問,需使用DateTimeOffset類的Offset屬性,代碼如下:

DateTimeOffset dt = new DateTimeOffset ( DateTimeOffset .UtcNow.DateTime, TimeSpan .FromMinutes(120));
Console .WriteLine(dt.Offset); // 02:00:00

獲取用戶的時區信息

上面所述都是獲取服務器時區的相關信息,那么,如何獲取訪問我們網站的用戶的時區信息呢?很可惜,瀏覽器發送請求的時候並不帶自身的時區,不過幸運的是,javascript提供了用戶的時區信息。代碼如下,運行結果如圖。

var date = new Date();
alert(date);

image

如果你想獲取用戶在哪個時區,只能從字符串中拆分,不過javascript提供了函數可以直接獲取時差,單位為分鍾。

var offset = date.getTimezoneOffset(); //-480

如何應對多時區的用戶

一個多時區的項目,如果在設計初考慮到時區,應將時間存為DateTime.UtcNow,這樣結合時差可得任意時區時間。如果一個項目已存成了DateTime.Now,結果半路殺出多時區問題,除了罵娘以外,只能將時間切換為0時區,再根據時差計算。通常獲取用戶時區的做法是--javascript獲取時差存入表單,並提交到服務器。

可是,並不是每次頁面訪問都有提交表單操作,如訪問首頁。如此一來必須要面對兩個選擇:

  1. 將時間獲取到頁面上,通過javascript根據時差換算。
  2. 將用戶時差保存在數據庫。

第一種麻煩且難以維護,容易造成重復代碼;第二種一旦碰到用戶時差改變,數據就沒了意義。最重要一點是數據真實性,因為javascript獲取的時間取自當前電腦,即該時間可隨意更改。且要命的是,我們通過時區獲取時差,時差得到時間,這個過程本身是不准確的,因為有夏令時的存在。

也就是說,如果時間顯示無關輕重,可采用以上應對方法。一旦時間和利益掛鈎,就會造成很大的問題。那么,究竟該如何應對多時區用戶的問題呢?下篇解答,未完待續。 ^_^

 

感謝園友匹配度的提醒和留言! ^_^


免責聲明!

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



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