Java Date 與時區


Java 中,一個 Date 類對象內部包含2個信息:

  • 絕對時間,即從1970-1-1 00:00:00.000 經過的毫秒數,表示為long類型
  • 時區

絕對時間與時區無關。假設同一時刻,地球東西半球各有一位程序狗執行了以下代碼,TA們將各自看到2行輸出,其中第一行是相同的數值,而第二行則(極有可能)顯示出不同的時間讀數:

1 Date now = new Date();
2 
3 System.out.println(now.getTime());
4 System.out.println(now);

構造Date對象時,使用構造函數 new Date(long) 獲得的對象其內部絕對時間是沒有歧義的,就是構造函數參數。但是如果使用其它需要給定年/月/日/...等日期/時間讀數的構造函數所獲得的對象,在不同的時區,其內部絕對時間將不一定相同。反過來,如果不同時區的Date對象,其內部絕對時間相同,但通過Date.getYear()/Date.getMonth()/...方法獲取到的讀書也將可能不同(上例就是這種情況)。對Date類,所有年/月/日/...讀數,不管是getter方法返回值還是setter方法/構造函數參數,都是代表本地時間,最終其內部絕對時間取決於所在的時區。

通過Date.getTimezoneOffset() 方法可以獲得時區。該方法返回本地時間與UTC/GMT之間的差值,單位為分鍾。例如我國時區為+08:00,也即我們的本地時間比UTC提前8小時(=480分鍾),例如,對於同一個時間描述“x年x月x日x時x分x秒x毫秒”,本地時間發生得UTC早480分鍾,也即絕對時間要比UTC小480分鍾,因此,Date.getTimezoneOffset()返回值為-480。

如果要構造一個給定UTC年/月/日/...時間讀數的Date對象,可借助 Date.UTC()方法先獲得其絕對時間,然后再通過new Date(long)構造函數獲得Date對象。注意,這樣獲得的Date對象,其getYear()/getMonth()/...等方法返回的日期/時間數值,已經轉換為本地時間,不(一定)同於先前給定的UTC時間。

如果要獲取某一個Date對象 that 所代表的絕對時間的UTC年/月/日/...日期/時間讀數,可如此構造一個新的Date對象:new Date(that.getTime() - 60000 * that.getTimezoneOffset()),然后調用其 getYear()/getMonth()/...等方法即可。

如果以MVC模式作為類比,Date對象的內部絕對時間是Model,其年/月/日/...讀數是View;同一個Model,在不同的時區,展現出來的View不同。如果需要在本地時間與UTC之間進行轉換,記住一個公式,對於同一View:

本地時間 - UTC = timezoneOffset

 


免責聲明!

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



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