大廠程式設計師如何使用Java8日期時間及未來的前景如何?[圖]

minemi發表於2020-12-01

一、大廠如何使用Java8日期時間?
Java8前,處理日期時間時,使用的“三大件”
Date
Calender
SimpleDateFormat
以宣告時間戳、使用日曆處理日期和格式化解析日期時間。但這些類的API可讀性差、使用繁瑣,且非執行緒安全,如同設計的翔一樣的IO,也是Java讓人詬病的一大原因。
於是Java8推出全新日期時間類。這些類的API功能強大簡便、執行緒安全。
但畢竟Java8剛出這些類,諸如序列化、資料訪問等類庫都不支援Java8日期時間類,需在新老類中來回切換。比如,在業務邏輯層使用LocalDateTime,存入資料庫或者返回前端的時候還要切換回Date。因此,還不如沿用老的日期時間類。

大廠程式設計師如何使用Java8日期時間及未來的前景如何?[圖]

不過我們生活在最好的時代,基本主流類庫都支援新日期時間型別,但還有專案因還是用祖傳日期時間類,出現很多古今交錯的錯誤實踐。
比如
通過隨意修改時區,使讀取到的資料匹配當前時鐘
直接對讀取到的資料做加、減幾個小時的操作,來“修正資料”
本文旨在分析古今時間錯亂的本質原因,看看使用遺留日期時間類,來處理日期時間初始化、格式化、解析、計算等可能會遇到的問題,以及如何使用新日期時間類解決。
2初始化日期時間
初始化2020年11月11日11點11分11秒時間,這樣可行嗎?
日誌輸出時間是3029年12月11日11點11分11秒:
date:SatDec1111:11:11CST3920
這明顯是彩筆才會寫的垃圾程式碼,因為
年應該是和1900差值
月應該是0~11而非1~12
時應該是0~23,而非1~24
修正上述程式碼如下:
Datedate=newDate(2020-1900,10,11,11,11,11);
日誌輸出:
MonNov1111:11:11CST2019
當有國際化需求時,又得使用Calendar類初始化時間。
使用Calendar改造後,初始化時年引數直接使用當前年即可,月0~11。亦可直接使用Calendar.DECEMBER初始化月份,肯定不會犯錯。
分別使用當前時區和紐約時區初始化兩個相同日期:
日誌輸出
顯示兩個不同時間,說明時區發生作用。但更習慣年/月/日時:分:秒日期時間格式,對現在輸出的日期格式還不滿意,那就格式化日期時間
3時區問題
全球有24個時區,同一個時刻不同時區(比如中國上海和美國紐約)的時間不同。全球化專案,若初始化時間時未提供時區,那就不是真正意義上的時間,只能認為是我看到的當前時間的一個表示。
3.1Date類
Date無時區概念,任一機器使用newDate()初始化得到時間相同。因為,Date中儲存的是UTC時間,其為以原子鐘為基礎的統一時間,不以太陽參照計時,無時區劃分
Date中儲存的是一個時間戳,代表從1970年1月1日0點(Epoch時間)到現在的毫秒數。嘗試輸出Date(0):
System.out.println(newDate(0));
System.out.println(TimeZone.getDefault().getID()+":"+
TimeZone.getDefault().getRawOffset()/3600000);
得到1970年1月1日8點。我的機器在中國上海,相比UTC時差+8小時:
ThuJan0108:00:00CST1970
Asia/Shanghai:8
對於國際化專案,處理好時間和時區問題首先就是要正確儲存日期時間。
這裡有兩種
3.2如何正確儲存日期時間
儲存UTC
儲存的時間無時區屬性,不涉及時區時間差問題的世界統一時間。常說的時間戳或Java中的Date類就是這種方式,也是推薦方案
儲存字面量
比如年/月/日時:分:秒,務必同時儲存時區資訊。
 

有了時區,才能知道該字面量時間真正的時間點,否則它只是一個給人看的時間表示且只在當前時區有意義。而Calendar才具有時區概念,所以通過使用不同時區初始化Calendar,才能得到不同時間。小小動物園四年級作文400字寫家人(https://www.yuananren.com/zuowen/9795.html)正確地儲存日期時間後,就是正確展示,即要使用正確時區,將時間點展示為符合當前時區的時間表示。至此也就能理解為何會發生“時間錯亂”。


從字面量解析成時間&從時間格式化為字面量
對同一時間表示,不同時區轉換成Date會得到不同時間戳
比如2020-11-1111:11:11
對當前上海時區/紐約時區,轉化為UTC時間戳不同
WedNov1111:11:11CST2020:1605064271000
ThuNov1200:11:11CST2020:1605111071000
這就是UTC的意義,並非時間錯亂。對同一本地時間的表示,不同時區的人解析得到的UTC時間必定不同,反過來不同本地時間可能對應同一UTC。
格式化後出現的錯亂
即同一Date,在不同時區下格式化得到不同時間表示。
在當前時區和紐約時區格式化2020-11-1111:11:11
輸出如下,當前時區Offset(時差)是+8小時,對於-5小時的紐約
因此,有時資料庫中相同時間,由於伺服器時區設定不同,讀取到的時間表示不同。這不是時間錯亂,而是時區作用,因為UTC時間需根據當前時區解析為正確的本地時間。
所以要正確處理時區,在於存和讀兩階段
存,需使用正確的當前時區來儲存,這樣UTC時間才會正確
讀,也須正確設定本地時區,才能把UTC時間轉換為正確當地時間
Java8處理時區問題
時間日期類ZoneId、ZoneOffset、LocalDateTime、ZonedDateTime和DateTimeFormatter,使用起來更簡單清晰。
初始化上海、紐約和東京三時區
可使用ZoneId.of初始化一個標準時區,也可使用ZoneOffset.ofHours通過一個offset初始化一個具有指定時間差的自定義時區。
日期時間表示
LocalDateTime無時區屬性,所以命名為本地時區的日期時間
ZonedDateTime=LocalDateTime+ZoneId,帶時區屬性
因此,LocalDateTime僅是一個時間表示,ZonedDateTime才是一個有效時間。這裡將把2020-01-0222:00:00這個時間表示,使用東京時區解析得到一個ZonedDateTime。
使用DateTimeFormatter格式化時間
可直接通過withZone直接設定格式化使用的時區。最後,分別以上海、紐約和東京三個時區來格式化這個時間輸出:
日誌輸出:相同時區,經過解析存和讀的時間表示一樣(比如最後一行)
對不同時區,比如上海/紐約,輸出本地時間不同。
+9小時時區的晚上10點,對上海時區+8小時,所以上海本地時間為早10點
而紐約時區-5小時,差14小時,為晚上9點
小結
要正確處理國際化時間問題,推薦Java8的日期時間類,即
使用ZonedDateTime儲存時間
然後使用設定了ZoneId的DateTimeFormatter配合ZonedDateTime進行時間格式化得到本地時間表示。
二、11月程式語言:Python超越Java
20年間,Java和C都是交替登上第一和第二的位置。本月Python歷史性排名第二,超越了Java,可以被稱為程式設計歷史上的獨特事件。
近幾年Python發展越來越快,市場佔有率一直在提升,從去年開始已升至排行榜第三,這個月Python歷史性的排到了排行榜的第二位。
Python近幾年隨著大資料、資料探勘、人工智慧等領域的發展,越來越受到大家的青睞,由於Python上手學習比較簡單,除了很多專業的開發人員學習外,非專業的資料處理人員也開始慢慢的接觸Python。
從2018年開始,Python的關注度就在快速攀升,而Java相對來說有些下滑
國內的情況我們可以參照下百度的搜尋指數,2017年之前Java搜尋指數還是高於Python的,而2018年之後Python搜尋指數迅速攀升,超過Java。

相關文章