一篇文章弄懂Java8中的時間處理
前言
java8借鑒瞭第三方日期庫joda很多的優點
java.time包
類名 | 描述 |
---|---|
Instant | 時間戳 |
Duration | 持續時間,時間差 |
LocalDate | 隻包含日期,比如:2020-05-20 |
LocalTime | 隻包含時間,比如:13:14:00 |
LocalDateTime | 包含日期和時間,比如:2020-05-20 13:14:00 |
Period | 時間段 |
ZoneOffset | 時區偏移量,比如:+8:00 |
ZonedDateTime | 帶時區的時間 |
Clock | 時鐘,比如獲取目前美國紐約的時間 |
java.time.format包
類名 | 描述 |
---|---|
DateTimeFormatter | 時間格式化 |
Java8提供瞭全新的時間處理框架,這裡就可以完全丟棄之前的Date、Calendar瞭。
具體的API的使用都是比較簡單的。這裡就不展開介紹瞭。
這裡主要介紹下一些主要的類
LocalDateTime
我們一般常用的就是這個瞭,用這個來表示日期時間。如LocalDateTime.now()
就可以基於當前默認時區得到當前的日期時間。
由於全球有好多時區,同一個日期時間,在不同的時區,反映到時間軸上是不同的。
LocalDateTime類型的日期時間是沒包含時區,所以它不能對應到時間軸上。說的直白點就是LocalDateTime不能轉換成自 1970-01-01T00:00:00Z 紀元以來的毫秒數。
ZonedDateTime
ZonedDateTime可以理解就是在LocalDateTime的基礎上添加上時區,所以它是可以反映到時間軸上的。
下面用夏令時舉個例子來看看LocalDateTime和LocalDateTime的區別。
夏令時是什麼這裡就不展開瞭,具體可以網上查下。看看我國1986開始的夏令時。
簡單來說就是在夏令時開始的時候,將時鐘向後撥1個小時。對應我國1986年開始的夏令時的做法,就是在每年四月中旬的第一個星期日當時鐘到達凌晨2點時,直接將時鐘撥到凌晨3點。也就是凌晨1點和凌晨3點之間之差1個小時。
由於1986年是開始實施的,所以1986年的夏令時是1986年5月4日開始的。
我們看看1987年的夏令時開始
根據我國當時的夏令時政策,1987年應該是1987年4月12日開始的。具體來說就是在1987-04-12 01:00:00 過一個小時後,時間應該是1987-04-12 03:00:00
LocalDateTime localDateTime = LocalDateTime.of(1987, 4, 12, 1, 0, 0, 0); System.out.println(localDateTime); System.out.println(localDateTime.plusHours(1));
執行上面的代碼就可以看到當1987-04-12 01:00:00增加1小時後,時間是1987-04-12 02:00:00。
這個也好理解,因為LocalDateTime並沒有包含時區,1987-04-12 02:00:00這個夏令時隻是中國的,並不是全球統一的,如果1987-04-12 02:00:00將直接變成1987-04-12 03:00:00放到中國以外的其他國傢就是錯誤的。
ZonedDateTime zonedDateTime = ZonedDateTime.of(1987, 4, 12, 1, 0, 0, 0, ZoneId.systemDefault()); System.out.println(zonedDateTime); System.out.println(zonedDateTime.plusHours(1));
執行上面的代碼可以看到當1987-04-12 01:00:00增加1小時後,時間變成瞭是1987-04-12 03:00:00。這個也就能說明問題瞭。
同時從打印結果也能看到時區自動從+08:00[Asia/Shanghai]變成瞭+09:00[Asia/Shanghai]
Instant
Instant表示時間軸上的一個瞬時時間,簡單來說就是表示自 1970-01-01T00:00:00Z 紀元以來的秒數、毫秒數等等
ZonedDateTime和Instant都能對應到時間軸上,所以它們兩個是可以相互轉化的。
Instant instant = zonedDateTime.toInstant(); ZonedDateTime zonedDateTime1 = instant.atZone(zonedDateTime.getZone());
其他一些常用的各種類型之間轉化的API
//ZonedDateTime 轉 Instant Instant instant = ZonedDateTime.now().toInstant(); //獲取UTC毫秒數 long epochMilli = instant.toEpochMilli(); //Instant 轉 ZonedDateTime ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault()); //字符串 轉 ZonedDateTime ZonedDateTime zonedDateTime2 = ZonedDateTime.parse(zonedDateTime.toString()); //基於UTC 偏移的毫秒數 int totalSeconds = zonedDateTime.getOffset().getTotalSeconds(); //Instant 轉 LocalDateTime LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); //LocalDateTime 轉 ZonedDateTime ZonedDateTime zonedDateTime1 = localDateTime.atZone(ZoneId.systemDefault()); ZoneRules zoneRules = ZoneId.systemDefault().getRules(); //判斷是否是夏令時時間 boolean daylightSavings = zoneRules.isDaylightSavings(instant); Calendar calendar = Calendar.getInstance(TimeZone.getDefault()); //Calendar 轉 Instant Instant instant1 = calendar.toInstant(); //Calendar 轉 ZonedDateTime Calendar now = Calendar.getInstance(); ZonedDateTime zdt = ZonedDateTime.ofInstant(now.toInstant(), ZoneId.systemDefault())); //Date 轉 Instant Date date = new Date(); Instant inst = date.toInstant(); // Instant 轉 Date Date newDate = Date.from(inst); //GregorianCalendar 轉 ZonedDateTime GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now()); TimeZone tz = cal.getTimeZone(); ZonedDateTime zdt1 = cal.toZonedDateTime(); //ZonedDateTime 轉 GregorianCalendar GregorianCalendar newCal = GregorianCalendar.from(zdt1); LocalDateTime ldt = zdt.toLocalDateTime(); LocalDate date2 = zdt.toLocalDate(); LocalTime time2 = zdt.toLocalTime();
更詳細的資料,還是看官方的文檔吧。https://docs.oracle.com/javase/tutorial/datetime/index.html
總結
到此這篇關於Java8中時間處理的文章就介紹到這瞭,更多相關Java8時間處理內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Java LocalDateTime常用操作方法
- Java8 Instant時間戳使用小記
- Java中常用時間的一些相關方法
- Java 8 Time Api 使用方法技巧
- Java8的DateTimeFormatter與SimpleDateFormat的區別詳解