1. 介紹日期時間API

引入日期時間 API

Java 的創建者不喜歡 Date 和 Calendar 類的情況。他們在那個時代很好,但時代變了。並且需要一些簡單、強大和可靠的東西。隨著 Java 8 的發布(Calendar出現 15 年後),引入了Java Date Time API 。它是一組類,應該能夠解決處理時間的每一個可能的任務。

有太多的類,它們被分成幾個包:

該包是 Java 日期時間 API 的基礎包:它包含、、、、和 等java.time類。這些類的所有對像都是,這意味著它們在創建後不能更改。LocalDateLocalTimeLocalDateTimeInstantPeriodDurationimmutable

java.time.format包包含用於時間格式化的類,即將時間(和日期)轉換為字符串,反之亦然。例如,它包含替換類的通用DateTimeFormatterSimpleDateFormat

java.time.zone包包含用於處理時區的類。它包含諸如TimeZone和 之類的類ZonedDateTime。如果您正在為位於世界不同地區的客戶編寫服務器代碼,您將確實需要這些類。


2.LocalDate

我們將看到的 Date Time API 中的第一個也是最有用的類是類LocalDate。正如您可能從其名稱中猜到的那樣,此類旨在處理日期。

該類的對像在創建後不會改變,即該類LocalDate是不可變的。但是這個屬性增加了類的簡單性和可靠性。特別是當多個線程(執行線程)同時與這樣的對象交互時。

要創建新LocalDate對象,您需要使用其中一種靜態方法。這是主要的列表。

獲取當前日期

要獲取當前日期,您需要使用靜態now()方法。這比看起來容易得多:

LocalDate today = LocalDate.now();

其中today是一個LocalDate變量,是對類的LocalDate.now()靜態方法的調用。now()LocalDate

例子:

代碼 控制台輸出
LocalDate today = LocalDate.now();
System.out.println("Today = " + today);

Today = 2019-02-22

獲取特定時區的日期

該類LocalDate還有一種方法變體now(ZoneId),可讓您獲取特定時區的當前日期。

為此,我們需要另一個類——ZoneId類 (java.time.ZoneId)。它有一個of()方法可以返回一個ZoneId給定時區名稱的對象。

判斷當前上海日期,需要編寫如下代碼:

代碼 控制台輸出
ZoneId  timezone = ZoneId.of("Asia/Shanghai");
LocalDate today = LocalDate.now(timezone);
System.out.println("In Shanghai, now = " + today);


In Shanghai, now = 2019-02-22

您可以在 Internet 上找到所有時區名稱的列表。


3.獲取特定日期

要獲取LocalDate表示特定日期的對象,您需要使用靜態of()方法。這裡的一切也非常簡單明了:

LocalDate date = LocalDate.of(2019, Month.FEBRUARY, 22);

其中date是一個LocalDate變量,是對類的靜態方法的調用。LocalDate.of()of()LocalDate

這裡我們看到類FEBRUARY的常量Month(java.time.Month) 被用來指定二月作為月份。

您還可以用老式的方式指定月份——使用數字:

LocalDate date = LocalDate.of(2019, 2, 22);

二?而不是二月?這是否意味著月份再次從一開始編號?

是的,在 Java 創建近 20 年後,月份終於不再從零開始計數了。

例子:

代碼 控制台輸出
LocalDate today = LocalDate.of(2019, 2, 22);
System.out.println("Today = " + today);

Today = 2019-02-22

通過當天的索引獲取日期

還有另一種有趣的創建日期的方法:使用該ofYearDay方法,您可以僅根據年號和年中日期的索引獲取日期。這是一般外觀:

LocalDate date = LocalDate.ofYearDay(year, day);

哪裡year是年數,day是一年中第幾天的索引。

例子:

代碼 控制台輸出
LocalDate today = LocalDate.ofYearDay(2019, 100);
System.out.println("Today = " + today);

Today = 2019-04-10

2019 年的第 100 天是 4 月 10 日。

獲取 Unix 日期

您還記得Date對象總是將時間存儲為自 1970 年 1 月 1 日以來的毫秒數嗎?為了確保程序員不會錯過過去的美好時光,該類LocalDate獲得了一個ofEpochDay()方法,該方法返回從 1970 年 1 月 1 日開始計算的日期。這是一般外觀:

LocalDate date = LocalDate.ofEpochDay(day);

day自 1970 年 1 月 1 日以來經過的天數在哪裡。

例子:

代碼 控制台輸出
LocalDate today = LocalDate.ofEpochDay(1);
System.out.println("Today = " + today);

Today = 1970-01-02

4.獲取日期元素

無法更改LocalDate對象,但您可以獲得存儲日期的各個元素。LocalDate對象為此有幾種方法:

方法 描述
int getYear()
返回特定日期的年份
Month getMonth()
返回日期的月份:幾個常量之一
JANUARY, FEBRUARY, ...;
int getMonthValue()
返回日期所在月份的索引。一月 == 1。
int getDayOfMonth()
返回一個月中的第幾天的索引
int getDayOfYear()
從年初返回天的索引
DayOfWeek getDayOfWeek()
返回星期幾:幾個常量之一
MONDAY, TUESDAY, ...;
IsoEra getEra()
返回時代:(BCE當前時代之前)和CE(當前時代)

例子:

代碼 控制台輸出
LocalDate today = LocalDate.now();
System.out.println(today.getYear());
System.out.println(today.getMonth());
System.out.println(today.getMonthValue());
System.out.println(today.getDayOfMonth());
System.out.println(today.getDayOfWeek());

2019
FEBRUARY
2
22
FRIDAY

LocalDate5. 更改對像中的日期

該類LocalDate包含多個可讓您處理日期的方法。這些方法的實現類似於類的方法String它們不更改現有LocalDate對象,而是返回一個包含所需數據的新對象。

以下是該類的方法LocalDate

方法 描述
plusDays(int days)
將指定的天數添加到日期
plusWeeks(int weeks)
向日期添加週數
plusMonths(int months)
將月份添加到日期
plusYears(int years)
將年份添加到日期
minusDays(int days)
從日期中減去天數
minusWeeks(int weeks)
從日期中減去週數
minusMonths(int months)
從日期中減去月份
minusYears(int years)
從日期中減去年份

例子:

代碼 控制台輸出
LocalDate birthday = LocalDate.of(2019, 2, 28);
LocalDate nextBirthday = birthday.plusYears(1);
LocalDate firstBirthday = birthday.minusYears(30);

System.out.println(birthday);
System.out.println(nextBirthday);
System.out.println(firstBirthday);




2019-02-28
2020-02-28
1989-02-28

我們調用的whosebirthday object方法不會改變。相反,它的方法返回包含所需數據的新對象。