Java™ 教程(Date-Time)
Date-Time
Java SE 8發行版中引入的Date-Time包ofollow,noindex" target="_blank">java.time
提供了全面的日期和時間模型,是在JSR 310:Date and Time API
下開發的,儘管java.time
基於國際標準化組織(ISO)日曆系統,但也支援常用的全球日曆。
此課程介紹了使用基於ISO的類來表示日期和時間以及操作日期和時間值的基本原理。
概述
時間似乎是一個簡單的主題,即便是便宜的手錶也能提供合理準確的日期和時間,但是,通過仔細研究,你會發現微妙的複雜性和許多影響你理解時間的因素。例如,在1月31日新增一個月的結果對於閏年而言與其他年份不同,時區也增加了複雜性,例如,一個國家可能會在短時間內進出夏令時,或者一年多次進入夏令時,或者可能在某一年內完全跳過夏令時。
Date-Time API使用ISO-8601
中定義的日曆系統作為預設日曆,此日曆基於公曆系統,並在全球範圍內用作表示日期和時間的事實標準。Date-Time API中的核心類有LocalDateTime
、ZonedDateTime
和OffsetDateTime
等,所有這些都使用ISO日曆系統。如果你想使用其他日曆系統,例如Hijrah或Thai Buddhist,java.time.chrono
包允許你使用其中一個預定義的日曆系統,或者你可以建立自己的。
Date-Time API使用Unicode公共語言環境資料儲存庫(CLDR) ,這個儲存庫支援全世界的語言,幷包含全世界最大的可用語言環境資料集合,此儲存庫中的資訊已本地化為數百種語言。Date-Time API還使用時區資料庫(TZDB) ,該資料庫提供了自1970年以來全球每個時區變化的資訊,以及自引入該概念以來的主要時區的歷史記錄。
Date-Time設計原則
Date-Time API是使用幾個設計原則開發的。
明確
API中的方法定義明確,其行為清晰且預期,例如,使用null
引數值呼叫Date-Time方法通常會觸發NullPointerException
。
流暢
Date-Time API提供了流暢的介面,使程式碼易於閱讀,因為大多數方法不允許具有null
值的引數並且不返回null
值,所以可以將方法呼叫連結在一起,並且可以快速理解生成的程式碼,例如:
LocalDate today = LocalDate.now(); LocalDate payday = today.with(TemporalAdjusters.lastDayOfMonth()).minusDays(2);
不可變
Date-Time API中的大多數類建立的物件不可變,這意味著在建立物件後,它不能被修改,要更改不可變物件的值,必須將新物件構造為原始物件的修改副本。這也意味著根據定義,Date-Time API是執行緒安全的。這會影響API,因為用於建立日期或時間物件的大多數方法都以for
、from
或with
作為字首,而不是建構函式,並且沒有set
方法,例如:
LocalDate dateOfBirth = LocalDate.of(2012, Month.MAY, 14); LocalDate firstBirthday = dateOfBirth.plusYears(1);
可擴充套件
Date-Time API儘可能是可擴充套件的,例如,你可以定義自己的時間調整器和查詢,或構建自己的日曆系統。
Date-Time包
Date-Time API由主包java.time
和四個子包組成:
java.time
- 用於表示日期和時間的核心API,它包括日期、時間、日期和時間組合、時區、時刻,持續時間和時鐘的類,這些類基於ISO-8601中定義的日曆系統,並且是不可變的和執行緒安全的。
java.time.chrono
- 用於表示除預設ISO-8601之外的日曆系統的API,你還可以定義自己的日曆系統,本教程未詳細介紹此包。
java.time.format
- 用於格式化和解析日期和時間的類。
java.time.temporal
-
擴充套件API,主要用於編寫框架和庫,允許日期和時間類之間的互操作、查詢和調整,欄位(
TemporalField
和ChronoField
)和單元(TemporalUnit
和ChronoUnit
)在此包中定義。
java.time.zone
-
支援時區、時區偏移和時區規則的類,如果使用時區,大多數開發人員只需要使用
ZonedDateTime
、ZoneId
或ZoneOffset
。
方法命名約定
Date-Time API在一組豐富的類中提供了一組豐富的方法,儘可能在類之間使方法名一致,例如,許多類提供了一個now
方法,用於捕獲與該類相關的當前時刻的日期或時間值,from
方法允許從一個類轉換到另一個類。
關於方法名稱字首也有標準化,由於Date-Time API中的大多數類都是不可變的,因此API不包含set
方法(建立後,無法更改不可變物件的值,set
方法的不可變等價是with
),下表列出了常用的字首:
字首 | 方法型別 | 使用 |
---|---|---|
of
|
靜態工廠 | 建立一個例項,其中工廠主要驗證輸入引數,而不是轉換它們。 |
from
|
靜態工廠 | 將輸入引數轉換為目標類的例項,這可能涉及從輸入中丟失資訊。 |
parse
|
靜態工廠 | 解析輸入字串以生成目標類的例項。 |
format
|
例項 | 使用指定的格式化程式來格式化時間物件中的值以生成字串。 |
get
|
例項 | 返回目標物件狀態的一部分。 |
is
|
例項 | 查詢目標物件的狀態。 |
with
|
例項 |
返回更改了一個元素的目標物件的副本; 這是JavaBean上 set
方法的不可變等價物。 |
plus
|
例項 | 返回新增時間量的目標物件的副本。 |
minus
|
例項 | 返回減去時間量的目標物件的副本。 |
to
|
例項 | 將此物件轉換為另一種型別。 |
at
|
例項 | 將此物件與另一個物件組合。 |