溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java8中如何使用日期時間

發(fā)布時間:2021-08-10 16:40:15 來源:億速云 閱讀:146 作者:Leah 欄目:編程語言

Java8中如何使用日期時間,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

初始化日期時間

初始化2020年11月11日11點(diǎn)11分11秒時間,這樣可行嗎?

Java8中如何使用日期時間

日志輸出時間是3029年12月11日11點(diǎn)11分11秒:

date : Sat Dec 11 11:11:11 CST 3920

這明顯是彩筆才會寫的垃圾代碼,因?yàn)?/p>

  • 年應(yīng)該是和1900差值

  • 月應(yīng)該是 0~11 而非 1~12

  • 時應(yīng)該是 0~23,而非 1~24

Java8中如何使用日期時間

修正上述代碼如下:

Date date = new Date(2020 - 1900, 10, 11, 11, 11, 11);

日志輸出:

Mon Nov 11 11:11:11 CST 2019

當(dāng)有國際化需求時,又得使用Calendar類初始化時間。

使用Calendar改造后,初始化時年參數(shù)直接使用當(dāng)前年即可,月0~11。亦可直接使用Calendar.DECEMBER初始化月份,肯定不會犯錯。

分別使用當(dāng)前時區(qū)和紐約時區(qū)初始化兩個相同日期:

Java8中如何使用日期時間

日志輸出

Java8中如何使用日期時間

顯示兩個不同時間,說明時區(qū)發(fā)生作用。但更習(xí)慣年/月/日 時:分:秒日期時間格式,對現(xiàn)在輸出的日期格式還不滿意,那就格式化日期時間

3 時區(qū)問題

全球有24個時區(qū),同一個時刻不同時區(qū)(比如中國上海和美國紐約)的時間不同。全球化項(xiàng)目,若初始化時間時未提供時區(qū),那就不是真正意義上的時間,只能認(rèn)為是我看到的當(dāng)前時間的一個表示。

3.1 Date類

Date無時區(qū)概念,任一機(jī)器使用new  Date()初始化得到時間相同。因?yàn)?,Date中保存的是UTC時間,其為以原子鐘為基礎(chǔ)的統(tǒng)一時間,不以太陽參照計時,無時區(qū)劃分

Date中保存的是一個時間戳,代表從1970年1月1日0點(diǎn)(Epoch時間)到現(xiàn)在的毫秒數(shù)。嘗試輸出Date(0):

System.out.println(new Date(0)); System.out.println(TimeZone.getDefault().getID() + ":" +     TimeZone.getDefault().getRawOffset()/3600000);

得到1970年1月1日8點(diǎn)。我的機(jī)器在中國上海,相比UTC時差+8小時:

Thu Jan 01 08:00:00 CST 1970 Asia/Shanghai:8

對于國際化項(xiàng)目,處理好時間和時區(qū)問題首先就是要正確保存日期時間。

這里有兩種

3.2 如何正確保存日期時間

  • 保存UTC

保存的時間無時區(qū)屬性,不涉及時區(qū)時間差問題的世界統(tǒng)一時間。常說的時間戳或Java中的Date類就是這種方式,也是推薦方案

  • 保存字面量

比如年/月/日 時:分:秒,務(wù)必同時保存時區(qū)信息。有了時區(qū),才能知道該字面量時間真正的時間點(diǎn),否則它只是一個給人看的時間表示且只在當(dāng)前時區(qū)有意義。

而Calendar才具有時區(qū)概念,所以通過使用不同時區(qū)初始化Calendar,才能得到不同時間。

正確地保存日期時間后,就是正確展示,即要使用正確時區(qū),將時間點(diǎn)展示為符合當(dāng)前時區(qū)的時間表示。至此也就能理解為何會發(fā)生“時間錯亂”。

從字面量解析成時間 & 從時間格式化為字面量

對同一時間表示,不同時區(qū)轉(zhuǎn)換成Date會得到不同時間戳

比如2020-11-11 11:11:11

Java8中如何使用日期時間

對當(dāng)前上海時區(qū)/紐約時區(qū),轉(zhuǎn)化為UTC時間戳不同

Wed Nov 11 11:11:11 CST 2020:1605064271000 Thu Nov 12 00:11:11 CST 2020:1605111071000

這就是UTC的意義,并非時間錯亂。對同一本地時間的表示,不同時區(qū)的人解析得到的UTC時間必定不同,反過來不同本地時間可能對應(yīng)同一UTC。

格式化后出現(xiàn)的錯亂

即同一Date,在不同時區(qū)下格式化得到不同時間表示。

在當(dāng)前時區(qū)和紐約時區(qū)格式化2020-11-11 11:11:11

Java8中如何使用日期時間

輸出如下,當(dāng)前時區(qū)Offset(時差)是+8小時,對于-5小時的紐約

Java8中如何使用日期時間

因此,有時數(shù)據(jù)庫中相同時間,由于服務(wù)器時區(qū)設(shè)置不同,讀取到的時間表示不同。這不是時間錯亂,而是時區(qū)作用,因?yàn)閁TC時間需根據(jù)當(dāng)前時區(qū)解析為正確的本地時間。

所以要正確處理時區(qū),在于存和讀兩階段

  • 存,需使用正確的當(dāng)前時區(qū)來保存,這樣UTC時間才會正確

  • 讀,也須正確設(shè)置本地時區(qū),才能把UTC時間轉(zhuǎn)換為正確當(dāng)?shù)貢r間

Java8處理時區(qū)問題

時間日期類ZoneId、ZoneOffset、LocalDateTime、ZonedDateTime和DateTimeFormatter,使用起來更簡單清晰。

初始化上海、紐約和東京三時區(qū)

可使用ZoneId.of初始化一個標(biāo)準(zhǔn)時區(qū),也可使用ZoneOffset.ofHours通過一個offset初始化一個具有指定時間差的自定義時區(qū)。

日期時間表示

  • LocalDateTime無時區(qū)屬性,所以命名為本地時區(qū)的日期時間

  • ZonedDateTime=LocalDateTime+ZoneId,帶時區(qū)屬性

因此,LocalDateTime僅是一個時間表示,ZonedDateTime才是一個有效時間。這里將把2020-01-02  22:00:00這個時間表示,使用東京時區(qū)解析得到一個ZonedDateTime。

使用DateTimeFormatter格式化時間

可直接通過withZone直接設(shè)置格式化使用的時區(qū)。最后,分別以上海、紐約和東京三個時區(qū)來格式化這個時間輸出:

Java8中如何使用日期時間

日志輸出:相同時區(qū),經(jīng)過解析存和讀的時間表示一樣(比如最后一行)

對不同時區(qū),比如上海/紐約,輸出本地時間不同。

+9小時時區(qū)的晚上10點(diǎn),對上海時區(qū)+8小時,所以上海本地時間為早10點(diǎn)

而紐約時區(qū)-5小時,差14小時,為晚上9點(diǎn)

Java8中如何使用日期時間

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI