前面我們處理的時候都是基於本地,根本就沒有考慮時區的問題,同時前面所提及的相關日期時間類也不包含時區信息。
時區是按照一定的規則將區域劃分成的標準時間相同的區間。 java.time.ZoneId
表示的就是時區ID,每個特定
的 ZoneId
對象都有一個地區ID標識,一旦得到一個 ZoneId 對象,你就可以將它與 LocalDate
、LocalDateTime
或者是 Instant
對象整合起來,構造爲一個 ZonedDateTime
實例,它代表了相對於指定時區的日期時間點。
地區ID都格式爲“{區域}/{城市}”,這些地區集合的設定都由英特網編號分配機構(IANA)的時區數據庫提供。
我們所使用的一般都是:Asia/Shanghai
Set<String> allId = ZoneId.getAvailableZoneIds(); // 獲取所有可用的ZoneID
for (String string : allId) {
System.out.println(string);
}
通過上圖我們對 ZonedDateTime
的組成部分有了清晰的瞭解,也可以明白 LocaleDate
、LocalTime
、 LocalDateTime
以及 ZoneId
之間的差異。
ZoneId romeZone = ZoneId.of("Europe/Rome");
LocalDate date = LocalDate.of(2014, Month.MARCH, 18); // 2014-03-18
ZonedDateTime zdt1 = date.atStartOfDay(romeZone); // 2014-03-18T00:00+01:00[Europe/Rome]
LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45); // 2014-03-18T13:45
ZonedDateTime zdt2 = dateTime.atZone(romeZone); // 2014-03-18T13:45+01:00[Europe/Rome]
LocalDateTime dateTimeLocal =LocalDateTime.now(); // 2019-08-10T11:26:21.161
Instant instant = Instant.now();
ZonedDateTime zdt3 = instant.atZone(romeZone); // 2019-08-10T05:26:21.162+02:00[Europe/Rome]
通過 ZoneId
,你還可以將 LocalDateTime
轉換爲 Instant
:
LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45);
Instant instantFromDateTime = dateTime.toInstant(romeZone);
我們也可以通過反向的方式得到 LocalDateTime
對象:
Instant instant = Instant.now();
LocalDateTime timeFromInstant = LocalDateTime.ofInstant(instant, romeZone);
注意事項:ZoneId
是一個抽象類,其自身提供了許多靜態方法來構造 ZoneId
實例,其只有一個實現類 ZoneOffset
其對ZoneId
進行了相應的拓展。
拓展:
ISO-8601日曆系統是世界文明日曆系統的事實標準。但是,Java 8中另外還提供了4種其他的日曆系統。這些日曆系統中的每一個都有一個對應的日誌類,分別是 ThaiBuddhistDate 、MinguoDate 、 JapaneseDate 以及 HijrahDate 。更多詳細信息可參考《Java 8 實戰》