Java8 由Oracle在2014年發佈,是繼Java5之後最具革命性的版本了。
Java8吸收其他語言的精髓帶來了函數式編程,lambda表達式,Stream流,新日期時間接口等一系列新特性,學會了這些新特性,可以讓你實現高效編碼、優雅編碼。
熱門精選文章,更多技術乾貨,微信搜索訂閱號【碼者圈】:
【Java8新特性】01 函數式接口和Lambda表達式你真的會了嗎
【Java8新特性】02 函數式接口和Lambda表達式實戰練習:環繞執行模式使行爲參數化
【Java8新特性】03 Stream流式數據處理
【Java8新特性】04 詳解Lambda表達式中Predicate Function Consumer Supplier函數式接口
【Java8新特性】05 使用Optional取代null
1. Java8之前糟糕的日期時間API
(1) Date
java.util.Date類是Jdk 1.0引入的,易用性非常糟糕,比如年份的起始是1900年,月份的起始是0。比如要表示2019年6月18日,創建一個Date實例:
Date date = new Date(119, 5, 18);
Date類已經不推薦使用了。
(2) Calendar
爲了解決Date糟糕的設計,Jdk 1.1 引入了java.util.Calendar類。不幸的是Calendar沒有扛起大任,仍然暴露出很多設計缺陷,導致寫代碼時容易出現問題,比如月份還是從0開始。
由於Date和Calendar推出的時間很接近,造成程序員對使用哪個類感到困惑。
還有一個很大的問題,Date和Calendar都是可變的類,這種設計會導致程序出現各種問題。
Date和Calendar的種種問題導致程序員們紛紛拋棄原生的jdk日期時間庫,轉投第三方組件如Joda-Time,Java設計者似乎意識到這個問題,在借鑑Joda-Time的基礎上終於在Java8版本中加入了新的日期時間包java.time.*
2. Java8 新的日期時間API
(1)日期時間常用類
針對日期和時間,Java8提供了LocalDate, LocalTime, LocalDateTime, Instant等常用類。Instant類是機器容易理解的類,通常以毫秒等整數值對時間進行建模。
創建實例常見操作:
// 當前日期
LocalDate date1 = LocalDate.now();
// 指定日期
LocalDate date2 = LocalDate.of(2019, 6, 18);
LocalDate date3 = LocalDate.of(2019, Month.JULY, 18);
// 當前時間
LocalTime time1 = LocalTime.now();
// 指定時間
LocalTime time2 = LocalTime.of(21, 10, 59);
// 當前日期時間
LocalDateTime dateTime1 = LocalDateTime.now();
// 指定日期時間
LocalDateTime dateTime2 = LocalDateTime.of(2019, 6, 18, 21, 10, 59);
// 當前時間戳
Instant instant1 = Instant.now();
// 指定時間戳
Instant instant2 = Instant.ofEpochMilli(1000000L);
(2)時間計算
可以用plus,minus對時間日期進行操作:
LocalDate today = LocalDate.of(2019, 6, 18);
LocalDate tomorrow = today.plus(1L, ChronoUnit.DAYS);
System.out.println(tomorrow); // output: 2019-06-19
LocalDate yesterday = today.minus(1L, ChronoUnit.DAYS);
System.out.println(yesterday); // output: 2019-06-17
你還可以通過Duration計算兩個時間的間隔:
Duration duration = Duration.between(dateTime2, dateTime1);
System.out.println(duration.toHours()); // output: 841
Period通過用來計算兩個日期之間的間隔:
Period period = Period.between(date2, date1);
System.out.println(period.toTotalMonths()); // output: 1
Duration和Period還包含了很多實用的方法如from,of等,大家可以自行看源碼進行學習。
(3)時間解析和格式化
LocalDate,LocalTime,LocalDateTime都有parse靜態方法用來解析給定的時間日期串:
// 時間日期解析
LocalDateTime parsedDateTime = LocalDateTime.parse("2019/06/18 12:11:10",
DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"));
System.out.println(parsedDateTime); // output: 2019-06-18T12:11:10
時間格式化可以使用java8提供的新類DateTimeFormatter,java8之前的SimpleDateFormat不推薦大家再用了。
// 時間日期格式化
LocalDateTime dateTime = LocalDateTime.now();
// 使用自定義formatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(dateTime.format(formatter)); // output: 2019-07-23 23:09:19
// 使用系統自帶formatter
System.out.println(dateTime.format(DateTimeFormatter.ISO_DATE_TIME)); // output: 2019-07-23T23:09:19.31
(4)時區使用方法
java8之前使用java.util.TimeZone類處理時區,java8新增ZoneId替代TimeZone。
ZoneId實例化方法:
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
ZoneId zoneId2 = ZoneId.systemDefault();
老時區對象轉化爲新時區:
ZoneId zoneId3 = TimeZone.getDefault().toZoneId();
帶時區的時間表示方法:
LocalDateTime dateTime2 = LocalDateTime.of(2019, 6, 18, 21, 10, 59);
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
ZonedDateTime zonedDateTime = dateTime2.atZone(zoneId);
// output: 2019-06-18T21:10:59+08:00[Asia/Shanghai]
System.out.println(zonedDateTime);
ZoneId zoneId2 = ZoneId.systemDefault();
ZonedDateTime zonedDateTime2 = dateTime2.atZone(zoneId2);
// output: 2019-06-18T21:10:59+08:00[Asia/Shanghai]
System.out.println(zonedDateTime2);
3. 總結
LocalDate, LocalTime, LocalDateTime, ZoneId之間的關係可以用一張圖解釋:
【碼者圈】屬於編碼者自己的圈子,掃描二維碼關注,第一時間獲取更多技術乾貨!