天天看點

大廠日期時間處理最佳實踐(上)1 背景2 初始化日期時間

1 背景

Java8前,處理日期時間時,使用的“三大件”

  • Date
  • Calender
  • SimpleDateFormat

以聲明時間戳、使用月曆處理日期和格式化解析日期時間。但這些類的API可讀性差、使用繁瑣,且非線程安全,如同設計的翔一樣的IO,也是Java讓人诟病的一大原因。

于是Java8推出全新日期時間類。這些類的API功能強大簡便、線程安全。

但畢竟Java8剛出這些類,諸如序列化、資料通路等類庫都不支援Java8日期時間類,需在新老類中來回切換。比如,在業務邏輯層使用LocalDateTime,存入資料庫或者傳回前端的時候還要切換回Date。是以,還不如沿用老的日期時間類。

不過我們生活在最好的時代,基本主流類庫都支援新日期時間類型,但還有項目因還是用祖傳日期時間類,出現很多古今交錯的錯誤實踐。

比如

  • 通過随意修改時區,使讀取到的資料比對目前時鐘
  • 直接對讀取到的資料做加、減幾個小時的操作,來“修正資料”

本文旨在分析古今時間錯亂的本質原因,看看使用遺留日期時間類,來處理日期時間初始化、格式化、解析、計算等可能會遇到的問題,以及如何使用新日期時間類解決。

2 初始化日期時間

  • 初始化2020年11月11日11點11分11秒時間,這樣可行嗎?
  • 大廠日期時間處理最佳實踐(上)1 背景2 初始化日期時間
  • 日志輸出時間是3029年12月11日11點11分11秒:
date : Sat Dec 11 11:11:11 CST 3920      

這明顯是彩筆才會寫的垃圾代碼,因為

  • 年應該是和1900內插補點
  • 月應該是 0~11 而非 1~12
  • 時應該是 0~23,而非 1~24
  • 大廠日期時間處理最佳實踐(上)1 背景2 初始化日期時間
  • 修正上述代碼如下:
Date date = new Date(2020 - 1900, 10, 11, 11, 11, 11);      
  • 日志輸出:
Mon Nov 11 11:11:11 CST 2019      

當有國際化需求時,又得使用Calendar類初始化時間。

使用Calendar改造後,初始化時年參數直接使用目前年即可,月0~11。亦可直接使用Calendar.DECEMBER初始化月份,肯定不會犯錯。

  • 分别使用目前時區和紐約時區初始化兩個相同日期:
  • 大廠日期時間處理最佳實踐(上)1 背景2 初始化日期時間
  • 日志輸出
  • 大廠日期時間處理最佳實踐(上)1 背景2 初始化日期時間
  • 顯示兩個不同時間,說明時區發生作用。但更習慣年/月/日 時:分:秒日期時間格式,對現在輸出的日期格式還不滿意,那就格式化日期時間