Java 8 的 java.time 包解決了舊版日期時間 api 的缺陷,推薦使用新版api提升線程安全性和開發效率。1. localdate 表示不帶時間的日期,適合處理生日等場景;2. localdatetime 處理無時區的日期時間,instant 用于時間戳;3. zoneid 和 zoneddatetime 解決時區問題,支持跨時區轉換;4. datetimeformatter 實現線程安全的日期時間格式化與解析,并建議采用 iso 標準格式避免錯誤。
在處理日期和時間時,Java 8 引入了全新的 java.time 包,徹底解決了舊版 API 的設計缺陷。如果你還在用 java.util.Date 或者被各種線程安全問題困擾,是時候擁抱新版的日期時間 API 了。
LocalDate:處理日期更清晰
LocalDate 是一個常用的類,用來表示不含時間的日期,比如“2025-07-03”。它是一個不可變對象,非常適合在多線程環境下使用。
舉個例子:
立即學習“Java免費學習筆記(深入)”;
LocalDate today = LocalDate.now(); // 獲取當前日期 System.out.println(today); // 輸出類似 2025-07-03
常見操作包括:
- 獲取某一天:LocalDate.of(2025, 7, 1)
- 增加或減少天數:today.plusDays(5) 或 today.minusWeeks(1)
- 判斷是否為閏年:today.isLeapYear()
這個類特別適合用于生日、節假日等只需要日期的場景。
LocalDateTime 和 Instant:處理時間和時間戳
如果需要同時處理日期和時間,可以用 LocalDateTime,它不包含時區信息。例如:
LocalDateTime now = LocalDateTime.now(); System.out.println(now); // 輸出類似 2025-07-03T20:47:12.123
而如果你要處理的是時間戳(如毫秒數),可以使用 Instant 類,它是對時間軸的精確描述,常用于日志記錄或系統間通信。
轉換方式如下:
Instant instant = now.atZone(ZoneId.of("UTC")).toInstant();
需要注意的是,LocalDateTime 不帶時區,所以跨地區的時間計算要格外小心。
ZoneId 和 ZonedDateTime:時區處理不再頭疼
處理全球用戶時,時區是個繞不開的問題。ZoneId 表示一個時區,比如 “Asia/Shanghai” 或 “America/New_York”。你可以用它來把 LocalDateTime 轉換為特定時區的時間:
ZoneId zone = ZoneId.of("Asia/Shanghai"); ZonedDateTime zonedNow = ZonedDateTime.now(zone); System.out.println(zonedNow); // 輸出含時區的時間
一些實用技巧:
- 查看所有可用時區:ZoneId.getAvailableZoneIds()
- 時間在不同時區之間的轉換:
ZonedDateTime newYorkTime = zonedNow.withZoneSameInstant(ZoneId.of("America/New_York"));
這樣處理后,不管用戶在哪個國家,都能顯示他們本地的時間。
格式化與解析:日期字符串的轉換
新版 API 提供了 DateTimeFormatter 來格式化和解析日期時間字符串。相比舊版的 SimpleDateFormat,它線程安全且使用簡單。
比如:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formatted = LocalDateTime.now().format(formatter); // 格式化為字符串 LocalDateTime parsed = LocalDateTime.parse("2025-07-03 20:47:00", formatter); // 解析字符串
幾個建議:
基本上就這些,新版 API 設計得非常直觀,但還是要多注意細節,比如時區和格式化方式,不然很容易踩坑。