Java 8 出來好久了,各位也可能已經在用了,不過其中新的時間日期 API 可能不多人用,甚至不知道怎麼上手。本文快速介紹一下其中的主要的類的概念和用法。java
Instant
Instant
表示一個 EPOCH 時間戳(即以 0 表示 1970-01-01T00:00:00Z),精確到納秒。Instant
對象不包含時區信息,且值是不可變的。code
雖然概念很簡單,可是它能夠很方便的和其餘時間日期對象之間進行交互和轉換。好比:對象
Instant
能夠用來構建一個時間段;Instant
加上一個時長能夠獲得另外一個 Instant
;Instant
加上一個時區能夠獲得一個 ZonedDateTime
對象。首先 Instant 有下面幾個常量:文檔
Instant.EPOCH
表示 1970-01-01T00:00:00ZInstant.MIN
表示 Instant 可度量的最先時間,公元前十億年Instant.MAX
表示 Instant 可度量的最晚時間,公元十億年咱們也能夠經過一些靜態方法來建立:字符串
Instant.now()
表示當前時間戳Instant.ofEpochMilli(long milliSec)
經過現有的毫秒時間戳來建立 Instant 對象Instant.ofEpochSecond(long seconds)
經過現有的秒時間戳來建立 Instant 對象Instant
對象包含兩個值:秒數和納秒數。其中秒數指的是 epoch 時間戳,而納秒數指的是該秒內的納秒時間。由此可知,Instant
對象的精確度比 System.currentTimeMillis()
高到不知道哪去了。get
因此從 Instant 能夠取到兩個值:Instant.getEpochSecond()
獲取秒數部分,Instant.getNano()
獲取納秒部分。it
plus()
, minus()
;isAfter()
, isBefore()
;until()
。下面是幾個例子:io
Instant instant1 = Instant.now(); Instant instant2 = instant1.plus(Duration.ofSeconds(100)); // 添加 100 秒 System.out.println(instant2.isAfter(instant1)); // true System.out.println(instant1.until(instant2, ChronoUnit.SECONDS)); // 100
這部分將在後面介紹。class
LocalDate/LocalTime/LocalDateTime
LocalDate
表示年月日,其精確度到天。它是不包含時分秒的。方法
LocalTime
表示一天當中的時間,其精確度到納秒。它是不包含年月日的。
LocalDateTime
既包含日期也包含時間,可是不包含時區。它實際上就是 LocalDate
和 LocalTime
的組合。
這三個類都有下面的幾個靜態方法來建立對象:
now()
表示當前時間或日期的對象;of()
使用指定的值來建立;parse()
經過解析字符串來建立。此外一個 LocalDate
對象和一個 LocalTime
對象能夠組合爲一個 LocalDateTime
對象。
下面是幾個例子:
LocalTime localTime = LocalTime.now(); LocalDate localDate = LocalDate.of(2018, 3, 5); LocalDateTime localDateTime = LocalDateTime.parse("2018-03-05T12:34:56"); // 下面兩句是等價的 LocalDateTime localDateTime1 = localDate.atTime(localTime); LocalDateTime localDateTime2 = localTime.atDate(localDate);
此外它們還有各自的建立對象的靜態方法,具體請參考 API 文檔。
到了這裏你可能發現 LocalDateTime
和 Instance
本質上是同樣的,都表示一個全局跨度內的一個時間點。那麼二者是否能夠互換呢?很惋惜,不能直接互換。
由於 LocalDateTime
沒有帶時區,而 Instance
的時間戳是統一以格林尼治時間爲準的,因此相同的 LocalDateTime
在不一樣時區的 EPOCH 時間戳不一樣,轉換的時候必須附加一個時區。下面是例子:
// LocalDateTime -> Instant Instant instant = Instant .from(LocalDateTime.now().atZone(ZoneId.systemDefault())); // 或者 Instant instant = Instant.from(ZonedDateTime.now()); // Instant -> LocalDateTime LocalDateTime localDateTime = LocalDateTime .ofInstant(Instant.now(), ZoneId.systemDefault());
Duration/Period
Duration 表示以秒爲單位的時長,精確到納秒。Period 表示以天爲單位的時長,精確到天。
有三類方法能夠建立時長對象:
of()
經過指定的值來建立;parse()
經過解析字符串來建立;between()
經過兩個時間點來建立。下面是幾個例子:
Duration duration1 = Duration.between(Instant.EPOCH, Instant.now()); Duration duration2 = Duration.between(LocalTime.parse("00:00:01"), LocalTime.now()); Period period1 = Period.parse("P1Y2M3D"); // 表示一年兩個月零三天 Period period2 = Period.of(1, 2, 3); // 同上
注意時長能夠爲負數。
以前說過,一個 Instant
加上一個時長能夠獲得另外一個 Instant
。下面是個例子:
Instant then = Instant.now().plus(period);
Period period2 = period1.plus(Period.ofDays(1));
表示 period1
加上一天。LocalDateTime time = LocalDateTime.now().plus(period);
。這裏必須注意的一點是,Duration
和 Period
的值不是單個數字,而是多個單位的組合,像 Period
是年月日的組合,好比 「1年零3個月零5天」,你不能把它看做是 (1 x 365 + 3 x 30 + 5) 天,由於這裏可能有閏年和非閏年的區別。因此 Period.ofYears(1)
是沒法轉換爲天數的。
當咱們要具體計算兩個時間點之間的秒數或天數,該怎麼辦呢?這裏有一個叫 ChronoUnit
的類。下面是幾個例子:
// 離那個什麼中華民族的偉大復興還有多少天 long days = ChronoUnit.DAYS.between(LocalDate.now(), LocalDate.of(2049, 10, 1));
其實 Java 8 的這套時間 API 比以前的 Date 和 Calendar 都要好懂得多,稍微練習一下就能夠運用自如。