Java 8 日期時間 API

Java 8 新特性 Java 8 新特性


Java 8通過發佈新的Date-Time API (JSR 310)來進一步加強對日期與時間的處理。

在舊版的 Java 中,日期時間 API 存在諸多問題,其中有:

  • 非線程安全 − java.util.Date 是非線程安全的,所有的日期類都是可變的,這是Java日期類最大的問題之一。

  • 設計很差 − Java的日期/時間類的定義並不一致,在java.util和java.sql的包中都有日期類,此外用於格式化和解析的類在java.text包中定義。java.util.Date同時包含日期和時間,而java.sql.Date僅包含日期,將其納入java.sql包並不合理。另外這兩個類都有相同的名字,這本身就是一個非常糟糕的設計。

  • 時區處理麻煩 − 日期類並不提供國際化,沒有時區支持,因此Java引入了java.util.Calendar和java.util.TimeZone類,但他們同樣存在上述所有的問題。

Java 8 在 java.time 包下提供了很多新的 API。以下為兩個比較重要的 API:

  • Local(本地) − 簡化了日期時間的處理,沒有時區的問題。

  • Zoned(時區) − 通過制定的時區處理日期時間。

新的java.time包涵蓋了所有處理日期,時間,日期/時間,時區,時刻(instants),過程(during)與時鐘(clock)的操作。


本地化日期時間 API

LocalDate/LocalTime 和 LocalDateTime 類可以在處理時區不是必須的情況。代碼如下:

Java8Tester.java 檔

import java.time.LocalDate; import java.time.LocalTime; import java.time.LocalDateTime; import java.time.Month; public class Java8Tester { public static void main(String args[]){ Java8Tester java8tester = new Java8Tester(); java8tester.testLocalDateTime(); } public void testLocalDateTime(){ // 獲取當前的日期時間 LocalDateTime currentTime = LocalDateTime.now(); System.out.println("當前時間: " + currentTime); LocalDate date1 = currentTime.toLocalDate(); System.out.println("date1: " + date1); Month month = currentTime.getMonth(); int day = currentTime.getDayOfMonth(); int seconds = currentTime.getSecond(); System.out.println("月: " + month +", 日: " + day +", 秒: " + seconds); LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012); System.out.println("date2: " + date2); // 12 december 2014 LocalDate date3 = LocalDate.of(2014, Month.DECEMBER, 12); System.out.println("date3: " + date3); // 22 小時 15 分鐘 LocalTime date4 = LocalTime.of(22, 15); System.out.println("date4: " + date4); // 解析字串 LocalTime date5 = LocalTime.parse("20:15:30"); System.out.println("date5: " + date5); } }

執行以上腳本,輸出結果為:

$ javac Java8Tester.java
$ java Java8Tester
當前時間: 2016-04-15T16:55:48.668
date1: 2016-04-15
月: APRIL, 日: 15, 秒: 48
date2: 2012-04-10T16:55:48.668
date3: 2014-12-12
date4: 22:15
date5: 20:15:30

使用時區的日期時間API

如果我們需要考慮到時區,就可以使用時區的日期時間API:

Java8Tester.java 檔

import java.time.ZonedDateTime; import java.time.ZoneId; public class Java8Tester { public static void main(String args[]){ Java8Tester java8tester = new Java8Tester(); java8tester.testZonedDateTime(); } public void testZonedDateTime(){ // 獲取當前時間日期 ZonedDateTime date1 = ZonedDateTime.parse("2015-12-03T10:15:30+05:30[Asia/Shanghai]"); System.out.println("date1: " + date1); ZoneId id = ZoneId.of("Europe/Paris"); System.out.println("ZoneId: " + id); ZoneId currentZone = ZoneId.systemDefault(); System.out.println("當期時區: " + currentZone); } }

執行以上腳本,輸出結果為:

$ javac Java8Tester.java
$ java Java8Tester
date1: 2015-12-03T10:15:30+08:00[Asia/Shanghai]
ZoneId: Europe/Paris
當期時區: Asia/Shanghai

Java 8 新特性 Java 8 新特性