java中的時間與時區:LocalDateTime和Date


LocalDateTime

LocalDateTime本身不包含時區信息,它存儲的是年、月、日、時分秒,納秒這樣的數字。
在不同的時區下,這樣的數字代表不同的時間。

比如一個LocalDateTime存儲2020-01-01 08:00:00,這里省略納秒。
對北京和東京的人來看這個時間,都認為是本地時間的話,在真實時間上,因為時區的差異,其實是相差1個小時的時間的。

構造函數

既然不帶時區,那么考慮LocalDateTime的構造函數:

LocalDateTime dtUtc = LocalDateTime.now(ZoneOffset.UTC);

為什么這里又有時區了呢?其實這是一個方便的方法:

如果只是為了獲取當前系統所在默認時區的一個本地時間,那么用LocalDateTime.now()無參數構造方法即可,而如果我想知道現在在UTC時區那里本地顯示的是什么時間,就可以用LocalDateTime.now(ZoneOffset.UTC)這個構造方法了。

所以對於我們東八區來說:


//假如這個時間是:2020-01-01 10:00:00
LocalDateTime dtLocal = LocalDateTime.now();

//那么這個時間就會存儲:2020-01-01 02:00:00,提前8個小時
LocalDateTime dtUtc = LocalDateTime.now(ZoneOffset.UTC);

在構造后,LocalDateTime同樣不攜帶時區信息,仍然只是表示一個顯示時間而已。

Date

Date存儲的是一個毫秒數,准確說是從1970-01-01 00:00:00到現在經過的毫秒數。
而這個毫秒數是有時區的,它存儲的永遠是現在針對UTC時區時的1970年零點,經過的毫秒數。怎么理解?

比如兩個程序員在同一時刻,一個在英國,一個在中國,同時調用new Date(),那么此時Date中存儲的毫秒數是完全相同的(當然是理想情況的同時,以及系統沒有誤差)。所不同的是在輸出時,GMT0時區,直接使用這個毫秒數計算得到顯示時間,而北京GMT+8顯示時,會在這個時間上增加8小時,即時區偏移。

所以如下兩個格式化類型,在當前東八區的使用場景,輸出實際是一樣的:

        SimpleDateFormat bjSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");     // 北京
        bjSdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));  // 設置北京時區

      SimpleDateFormat dftSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");     // 不設置時區

構造

因為Date有時區信息,所以構造Date也就需要時區信息。
因此,不能直接從LocalDateTime轉換成Date,因為無法確定這個LodalDateTime究竟是哪個時區的這個時間。
而要借助Instant,因為Instant也代表從UTC開始的一個偏移時間。

LocalDateTime dt  = LocalDateTime.now();
Date dt2 = Date.from(dt.toInstant(ZoneOffset.of("+8"))); //東八區

輸出


免責聲明!

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



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