JDK8日期類入門
關於jdk8的時間類的用法,網上有很多教程教你如何用,比如:
System.out.println(LocalDateTime.now());
可以獲取當前的時間,
2020-12-06T18:02:39.215
但我想從另一個角度來思考這些時間類。
首先,我想明確一個觀點:
JDK8中的日期類是什麼?
我認為其本質就是對這個世界上時間的一種抽象封裝
。
為什麼這麼說呢,耐心點看下去。
第一個問題,地球上的時間從哪來?
害。這不是屁話么,小學生都知道地球上的時間是通過地球繞太陽公轉來的,以本初子午線為0時區,將地球劃分為12個時區。比如北京就在東8區,也就是UTC/GMT+08:00
所以第一個概念就有了,那就是時區
,JDK8里稱為Zone
,對應的用來求指定時區的類是ZonedDateTime
,以下為代碼示例:
import java.time.ZoneId;
import java.time.ZonedDateTime;
/**
* @author Alin
* @desc //TODO
* @date 2020/12/6
*/
public class TestLocalDateTime {
public static void main(String[] args) {
final ZonedDateTime now = ZonedDateTime.now();
System.out.println(now);
final ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println(zonedDateTime.toString());
}
}
從結果可以看出,不同時區對應的時間不同,東京比上海快了一個小時:
2020-12-06T19:02:59.765+08:00[Asia/Shanghai]
2020-12-06T20:02:59.766+09:00[Asia/Tokyo]
當然,這個世界的時間設計不可能只有時區,以東8區舉例,
此時區內該如何計算時間呢?
JDK8提供了幾種方式,比如:
- LocalDateTime
- LocalDate
- Instant
代碼示例:
public class TestLocalDateTime {
@Test
void test2(){
System.out.println(LocalDateTime.now());
System.out.println(LocalDate.now());
final Instant now = Instant.now();
System.out.println(now);
System.out.println(now.toEpochMilli());
System.out.println(System.currentTimeMillis());
System.out.println(LocalTime.now());
}
}
2020-12-06T19:36:35.323
2020-12-06
2020-12-06T11:36:35.323Z
1607254595323
1607254595328
19:36:35.328
從結果看,LocalDateTime可以獲得當前時區的年月日時分秒,LocalDate則是年月日,Instant則可以獲取自1970-01-01T00:00:00Z到現在的毫秒數,LocalTime就是時分秒了,注意,此四類獲取的結果是不考慮時區
的,都是指默認時區。
從命名上看的也很明顯,Local指本地(本時區、系統默認時區),Date指日期,Time指時間。
按照邏輯推斷,其中必然有轉換關係
,知道了年月日時分秒,那肯定能單獨轉換為年月日或者時分秒吧,的確JDK8也做了封裝:
public class TestLocalDateTime {
@Test
void test3(){
final LocalDateTime localDateTime = LocalDateTime.now();
final LocalDate localDate = LocalDate.now();
final LocalTime localTime = LocalTime.now();
final Instant instant = Instant.now();
final LocalDate toLocalDate = localDateTime.toLocalDate();
final LocalTime toLocalTime = localDateTime.toLocalTime();
final long milli = localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli();
}
}
我們這個世界還需要哪些時間單位呢?
比如,年、月、周、日,對應的類如Year
、Month
、DayOfWeek
、MonthDay
,被設計用來增強代碼的可讀性和可靠性。
時間也是有範圍的,比如幾個小時/持續了幾秒/天/月等:
Duration
表示以秒和納秒為基準的時長。例如,「10.3秒」。
Period
表示以年、月、日衡量的時長。例如,「1年5個月零13天」。
另外,該如何格式化日期呢,這個JDk8也有封裝,最常用的DateTimeFormatter
就可以做到:
public class TestLocalDateTime {
@Test
void test4(){
final LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
}
還有一個很方便的工具類TemporalAdjusters
,代碼如下:
public class TestLocalDateTime {
@Test
void test5(){
final LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);
final LocalDateTime with = localDateTime.with(TemporalAdjusters.lastDayOfMonth());
System.out.println(with);
}
}
可以方便的計算諸如本月的最後一天等等問題,具體可自查api:
2020-12-06T20:07:26.181
2020-12-31T20:07:26.181