深入了解Java 8 新特性-日期時間API之LocalDateTime類
注意
本文編寫的單元測試是基于java11,具體的版本號是:11.0.19
關于LocalDateTime
LocalDateTime 是 Java 8 中引入的一個新的日期時間 API,它表示一個沒有時區(qū)的日期時間對象,是不可變且線程安全的。LocalDateTime 通常用于需要同時表示日期和時間,但不涉及時區(qū)的場景。
LocalDateTime、LocalDate和LocalTime都是Java中用于表示日期和時間的數(shù)據(jù)類型,但它們在功能和使用上有一些重要的區(qū)別。
與LocalDate的區(qū)別
功能:
- LocalDateTime:是一個不可變的日期時間對象,包含日期和時間信息,通常被視為年-月-日-時-分-秒。它也可以訪問其他日期和時間字段,例如一年中的某天、一周中的某天和一周中的某周。時間以納秒精度表示。LocalDateTime是不可變的,提供了各種方法來操作和提取日期和時間值,并且是線程安全的。
- LocalDate:也是一個不可變的日期時間對象,但只包含日期信息,通常被視為年-月-日。它不包含時間信息。LocalDate提供了方法來操作和提取日期值,但不包括時間信息。同樣,它是不可變的,并且是線程安全的。
使用場景:
- 如果需要同時處理日期和時間信息,LocalDateTime更為適用。
- 如果只需要操作日期,不需要時間信息,LocalDate可能更合適。
與LocalTime的區(qū)別
功能:
- LocalDateTime表示日期和時間,不包含時區(qū)信息。它是一個不可變類,提供了一系列方法來獲取、設置和操作年、月、日、時、分、秒等日期和時間的不同部分,以及進行比較、格式化、解析等操作。LocalDateTime是LocalDate和LocalTime的組合,可以用于存儲和操作具體的日期和時間。
- LocalTime表示時間,不包含日期和時區(qū)信息。它也是不可變類,提供了一系列方法來獲取、設置和操作時、分、秒等時間的不同部分,以及進行比較、格式化等操作。LocalTime可以用于存儲和操作每天的固定時間點,如午夜、中午等。
使用場景
- 如果需要同時處理日期和時間信息,LocalDateTime更為適用。
- 如果只需要操作時間,不需要日期信息,LocalTime可能更合適。
核心方法
LocalDateTime#now()
LocalDateTime#now() 用于獲取當前的日期和時間,不包含時區(qū)信息。
@Test
public void test() {
LocalDateTime now = LocalDateTime.now();
String format = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(format);//當前日期和時間:2023-11-27 11:23:54
}
LocalDateTime#of(...)、LocalDateTime#ofInstant(...)、LocalDateTime#ofEpochSecond(...)
- LocalDateTime#of():這個方法用于創(chuàng)建一個具有特定日期和時間的LocalDateTime對象。它接受年、月、日、時、分、秒作為參數(shù),返回一個對應的LocalDateTime實例。使用場景包括需要創(chuàng)建一個特定的日期和時間對象,例如生日、紀念日等。
- LocalDateTime#ofInstant():這個方法用于使用Instant和時區(qū)ID創(chuàng)建LocalDateTime的實例。它將兩個參數(shù)傳遞給方法,一個是Instant類型,表示傳遞給創(chuàng)建localdatetime的瞬間,另一個是ZoneId類型,代表用于創(chuàng)建偏移量的時區(qū)。該方法返回一個對應的LocalDateTime實例。使用場景包括需要將一個瞬時轉(zhuǎn)化為本地日期和時間,例如在處理與時間相關的數(shù)據(jù)時,需要將UTC時間轉(zhuǎn)換為本地時間。
- LocalDateTime#ofEpochSecond():這個方法用于根據(jù)秒數(shù)和納秒數(shù)創(chuàng)建一個LocalDateTime對象。它接受秒數(shù)和納秒數(shù)作為參數(shù),返回一個對應的LocalDateTime實例。使用場景包括需要將秒數(shù)和納秒數(shù)轉(zhuǎn)化為日期和時間對象,例如在處理時間戳等數(shù)據(jù)時,需要將秒數(shù)和納秒數(shù)轉(zhuǎn)換為日期和時間對象。
@Test
public void test2() {
LocalDateTime localDateTime = LocalDateTime.of(2023, 11, 27, 11, 27, 56);
System.out.println(localDateTime);//輸出結(jié)果:2023-11-27T11:27:56
LocalDate localDate = LocalDate.of(2023, 11, 27);
LocalTime localTime = LocalTime.of(11, 27, 56);
LocalDateTime localDateTime1 = LocalDateTime.of(localDate, localTime);
System.out.println(localDateTime1);//輸出結(jié)果:2023-11-27T11:27:56
LocalDateTime localDateTime2 = LocalDateTime.ofInstant(Instant.ofEpochSecond(61), ZoneId.systemDefault());
System.out.println(localDateTime2);//輸出結(jié)果:1970-01-01T08:01:01
LocalDateTime localDateTime3 = LocalDateTime.ofEpochSecond(61, 0, ZoneOffset.ofHours(8));
System.out.println(localDateTime3);//輸出結(jié)果:1970-01-01T08:01:01
}
LocalDateTime#from(...)
LocalDateTime#from(...)用于從給定的日期時間對象中創(chuàng)建一個新的LocalDateTime實例。這個方法接受一個Object類型的參數(shù),這個對象需要是以下類型之一:
- ZonedDateTime
- OffsetDateTime
- Instant
- LocalDate
- LocalTime
- YearMonth
- MonthDay
- YearWeek
- Year
- Month
- DayOfWeek
- WeekOfMonth
- WeekOfYear
- DayOfYear
- MonthDayOfYear
- YearMonthDayOfYear
當給定的日期時間對象為以上所列出的類型之一時,LocalDateTime#from(...)方法會嘗試從中提取日期和時間信息,并創(chuàng)建一個新的LocalDateTime實例。如果給定的對象無法轉(zhuǎn)換為LocalDateTime,那么這個方法會拋出一個DateTimeException異常。
這個方法的使用場景通常是在需要將一個日期時間對象轉(zhuǎn)換為LocalDateTime,以便進行后續(xù)的日期和時間運算或處理。例如,你可能從數(shù)據(jù)庫中獲取了一個日期時間戳,然后你需要將這個日期時間戳轉(zhuǎn)換為LocalDateTime,以便進行進一步的計算或處理?;蛘?,你可能需要從一個具有特定時區(qū)的日期時間對象中創(chuàng)建一個沒有時區(qū)的LocalDateTime。
@Test
public void test3() {
LocalDateTime localDateTime = LocalDateTime.parse("2023-11-2711:36:56", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime from = LocalDateTime.from(localDateTime);
System.out.println(from);//輸出結(jié)果:2023-11-2711:36:56
}
LocalDateTime#parse(...)
LocalDateTime#parse(...) 用于將字符串解析為 LocalDateTime 對象的函數(shù)。該方法使用一個字符串作為輸入,并根據(jù)該字符串的內(nèi)容創(chuàng)建一個新的 LocalDateTime 對象。
在使用該方法時,該字符串必須符合 ISO 8601 格式,例如 "2019-01-01T12:00:00",另外還需要注意時區(qū)的問題。如果字符串中沒有指定時區(qū)信息,那么解析出來的 LocalDateTime 對象將是本地時區(qū)的時間。如果需要指定時區(qū),可以使用 ZoneId 類的 of 方法來創(chuàng)建時區(qū)對象,然后使用 LocalDateTime.atZone 方法將 LocalDateTime 對象轉(zhuǎn)換為 ZonedDateTime 對象,最后再使用 ZonedDateTime.toLocalDateTime 方法將其轉(zhuǎn)換為指定時區(qū)的 LocalDateTime 對象。
@Test
public void test4() {
LocalDateTime localDateTime = LocalDateTime.parse("2023-11-2711:36:56", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(localDateTime);//輸出結(jié)果:2023-11-2711:36:56
}
LocalDateTime#isSupported(...)
LocalDateTime#isSupported() 用于檢查是否支持特定的單位或字段。該方法接受一個參數(shù),可以是 TemporalUnit 或 TemporalField 對象,用于指定要檢查的單位或字段。如果支持,方法將返回 true;如果不支持,方法將返回 false。
使用場景:
- 需要對日期時間進行特定單位或字段的操作時:如果需要在代碼中使用 LocalDateTime 對象進行日期時間操作,并需要確保所使用的字段或單位是受支持的,可以使用 LocalDateTime#isSupported() 方法進行檢查。例如,在執(zhí)行加減運算之前,可以使用該方法檢查是否支持特定的時間單位。
- 需要進行日期時間格式驗證時:在使用 LocalDateTime 對象處理日期時間數(shù)據(jù)時,可能需要對輸入數(shù)據(jù)進行格式驗證。通過調(diào)用 LocalDateTime#isSupported() 方法并傳遞相應的單位或字段參數(shù),可以驗證輸入數(shù)據(jù)是否符合要求。例如,可以檢查日期時間字符串是否包含不合法的字段或單位。
@Test
public void test5() {
LocalDateTime now = LocalDateTime.now();
boolean supported = now.isSupported(ChronoUnit.YEARS);
boolean supported1 = now.isSupported(ChronoField.DAY_OF_YEAR);
System.out.println(supported);//輸出結(jié)果:true
System.out.println(supported1);//輸出結(jié)果:true
}
LocalDateTime#range(...)
LocalDateTime#range(...) 用于獲取LocalDateTime對象指定字段的有效值范圍,返回值是一個ValueRange對象,range對象表示字段的最小和最大有效值。此日期時間用于提高返回范圍的準確性。如果由于不支持該字段或其他原因而無法返回范圍,則會引發(fā)異常。
@Test
public void test6() {
LocalDateTime now = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
ValueRange range = now.range(ChronoField.DAY_OF_MONTH);
long maximum = range.getMaximum();
long minimum = range.getMinimum();
System.out.println(maximum);//輸出結(jié)果:29
System.out.println(minimum);//輸出結(jié)果:1
LocalDateTime now2 = LocalDateTime.of(2023, 2, 1, 12, 18, 56);
ValueRange range2 = now2.range(ChronoField.DAY_OF_MONTH);
long maximum2 = range2.getMaximum();
long minimum2 = range2.getMinimum();
System.out.println(maximum2);//輸出結(jié)果:28
System.out.println(minimum2);//輸出結(jié)果:1
}
LocalDateTime#get(...)、LocalDateTime#getLong(...)、LocalDateTime#getYear(...)、LocalDateTime#getMonthValue(...)、LocalDateTime#getMonth(...)、LocalDateTime#getDayOfMonth(...)、LocalDateTime#getDayOfYear(...)、LocalDateTime#getDayOfWeek(...)、LocalDateTime#getHour(...)、LocalDateTime#getMinute(...)、LocalDateTime#getSecond(...)、LocalDateTime#getNano(...)
- LocalDateTime#get(TemporalField):此方法獲取給定時間字段的值。參數(shù)可以是年、月、日、時、分、秒或納秒等。它通常用于對日期和時間進行精細操作或計算。
- LocalDateTime#getLong(TemporalField):此方法獲取給定時間字段的長整型值。它的使用場景與get方法類似,但返回值是長整型的。
- LocalDateTime#getYear():此方法返回當前日期的年份。它通常用于進行年份相關的計算或處理。
- LocalDateTime#getMonthValue():此方法返回當前月份的值,以整數(shù)形式表示。它通常用于處理或操作月份信息。
- LocalDateTime#getMonth():此方法返回當前月份的Text,如"January"、"February"等。它主要用于獲取月份的全稱。
- LocalDateTime#getDayOfMonth():此方法返回當前日期的日,以整數(shù)形式表示。它通常用于處理或操作具體的日期信息。
- LocalDateTime#getDayOfYear():此方法返回當前日期是一年中的第幾天,以整數(shù)形式表示。它主要用于計算或處理一年中的日期信息。
- LocalDateTime#getDayOfWeek():此方法返回當前日期是星期幾,以Text形式表示,如"Monday"、"Tuesday"等。它主要用于獲取星期的全稱。
- LocalDateTime#getHour():此方法返回當前時間的時,以整數(shù)形式表示。它通常用于處理或操作具體的小時信息。
- LocalDateTime#getMinute():此方法返回當前時間的分,以整數(shù)形式表示。它通常用于處理或操作具體的分鐘信息。
- LocalDateTime#getSecond():此方法返回當前時間的秒,以整數(shù)形式表示。它通常用于處理或操作具體的秒信息。
- LocalDateTime#getNano():此方法返回當前時間的納秒,以整數(shù)形式表示。它主要用于獲取納秒級別的精度信息。
@Test
public void test7() {
LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
int year = localDateTime.get(ChronoField.YEAR);
System.out.println(year);//輸出結(jié)果:2020
int month = localDateTime.get(ChronoField.MONTH_OF_YEAR);
System.out.println(month);//輸出結(jié)果:2
long yearLong = localDateTime.getLong(ChronoField.YEAR);
System.out.println(yearLong);//輸出結(jié)果:2020
long monthLong = localDateTime.getLong(ChronoField.MONTH_OF_YEAR);
System.out.println(monthLong);//輸出結(jié)果:2
int year1 = localDateTime.getYear();
System.out.println(year1);//輸出結(jié)果:2020
int monthValue = localDateTime.getMonthValue();
System.out.println(monthValue);//輸出結(jié)果:2
int dayOfMonth = localDateTime.getDayOfMonth();
System.out.println(dayOfMonth);//輸出結(jié)果:1
int dayOfYear = localDateTime.getDayOfYear();
System.out.println(dayOfYear);//輸出結(jié)果:32
DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
int dayOfWeekValue = dayOfWeek.getValue();
System.out.println(dayOfWeekValue);//輸出結(jié)果:6
int hour = localDateTime.getHour();
System.out.println(hour);//輸出結(jié)果:12
int minute = localDateTime.getMinute();
System.out.println(minute);//輸出結(jié)果:18
int second = localDateTime.getSecond();
System.out.println(second);//輸出結(jié)果:56
}
LocalDateTime#toLocalDate(...)、LocalDateTime#toLocalTime(...)
- toLocalDate() 方法:該方法用于從 LocalDateTime 對象中獲取 LocalDate 對象。它返回一個 LocalDate 實例,表示此 LocalDateTime 對象的日期部分。
- toLocalTime() 方法:該方法用于從 LocalDateTime 對象中獲取 LocalTime 對象。它返回一個 LocalTime 實例,表示此 LocalDateTime 對象的時間部分。
@Test
public void test8() {
LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
LocalDate localDate = localDateTime.toLocalDate();
LocalTime localTime = localDateTime.toLocalTime();
System.out.println(localDate);//輸出結(jié)果:2020-02-01
System.out.println(localTime);//輸出結(jié)果:12:18:56
}
LocalDateTime#with(...)、LocalDateTime#withYear(...)、LocalDateTime#withMonth(...)、LocalDateTime#withDayOfMonth(...)、LocalDateTime#withDayOfYear(...)、LocalDateTime#withHour(...)、LocalDateTime#withMinute(...)、LocalDateTime#withSecond(...)、LocalDateTime#withNano(...)
上述這些方法可以在不改變?nèi)掌诤蜁r間的其他部分的情況下,對日期和時間的特定部分進行修改和操作。具體來說:
- LocalDateTime#with():該方法用于使用 TemporalAdjuster 調(diào)整此日期時間,并在調(diào)整后返回調(diào)整后的日期時間的副本。使用指定的調(diào)整器策略對象進行調(diào)整。
- LocalDateTime#withYear():該方法用于獲取此 LocalDateTime 的副本,并將年份更改為作為該方法的參數(shù)傳遞的年份。此 LocalDateTime 的其余值保持不變。年份的值范圍可以從 MIN_YEAR 到 MAX_YEAR。
- LocalDateTime#withMonth():該方法用于獲取此 LocalDateTime 的副本,并將月份更改為作為該方法的參數(shù)傳遞的月份。此 LocalDateTime 的其余值保持不變。月份的值范圍從 1 到 12。
- LocalDateTime#withDayOfMonth():該方法用于獲取此 LocalDateTime 的副本,并將日更改為作為該方法的參數(shù)傳遞的日。此 LocalDateTime 的其余值保持不變。日的值范圍從 1 到月份的天數(shù)。
- LocalDateTime#withDayOfYear():該方法用于獲取此 LocalDateTime 的副本,并將一年中的日子更改為作為該方法的參數(shù)傳遞的日子。此 LocalDateTime 的其余值保持不變。天的值范圍從 1 到 365 或 366(取決于年份是否為閏年)。
- LocalDateTime#withHour():該方法用于獲取此 LocalDateTime 的副本,并將小時更改為作為該方法的參數(shù)傳遞的小時。此 LocalDateTime 的其余值保持不變。小時的值范圍從 0 到 23。
- LocalDateTime#withMinute():該方法用于獲取此 LocalDateTime 的副本,并將分鐘更改為作為該方法的參數(shù)傳遞的分鐘。此 LocalDateTime 的其余值保持不變。分鐘的值的范圍從 0 到 59。
- LocalDateTime#withSecond():該方法用于獲取此 LocalDateTime 的副本,并將秒更改為作為該方法的參數(shù)傳遞的秒。此 LocalDateTime 的其余值保持不變。秒的值范圍從 0 到 59(或 60,如果該秒是閏秒)。
- LocalDateTime#withNano():該方法用于獲取此 LocalDateTime 的副本,并將納秒更改為作為該方法的參數(shù)傳遞的納秒。此 LocalDateTime 的其余值保持不變。納秒的值范圍從 0 到 999,999,999。
@Test
public void test9() {
LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
TemporalAdjuster temporalAdjuster = item -> item.plus(1, ChronoUnit.HOURS);
LocalDateTime localDateTime1 = localDateTime.with(temporalAdjuster);
System.out.println(localDateTime1);//輸出結(jié)果:2020-02-01T13:18:56
LocalDateTime localDateTime2 = localDateTime.with(ChronoField.HOUR_OF_DAY, 1);
System.out.println(localDateTime2);//輸出結(jié)果:2020-02-01T01:18:56
LocalDateTime localDateTime3 = localDateTime.withYear(2023);
System.out.println(localDateTime3);//輸出結(jié)果:2023-02-01T12:18:56
LocalDateTime localDateTime4 = localDateTime.withMonth(1);
System.out.println(localDateTime4);//輸出結(jié)果:2020-01-01T12:18:56
LocalDateTime localDateTime5 = localDateTime.withDayOfMonth(10);
System.out.println(localDateTime5);//輸出結(jié)果:2020-02-10T12:18:56
LocalDateTime localDateTime6 = localDateTime.withHour(18);
System.out.println(localDateTime6);//輸出結(jié)果:2020-02-01T18:18:56
LocalDateTime localDateTime7 = localDateTime.withMinute(30);
System.out.println(localDateTime7);//輸出結(jié)果:2020-02-01T12:30:56
LocalDateTime localDateTime8 = localDateTime.withSecond(59);
System.out.println(localDateTime8);//輸出結(jié)果:2020-02-01T12:18:59
}
LocalDateTime#truncatedTo(...)
LocalDateTime#truncatedTo()用于將當前LocalDateTime對象的時間部分截斷到給定的時間單位。
功能作用:
- 截斷日期時間:通過調(diào)用LocalDateTime#truncatedTo()方法,可以將當前LocalDateTime對象的時間部分截斷到給定的時間單位,例如分鐘、小時、天等。截斷后的LocalDateTime對象將不再包含被截斷單位之前的時間信息。
- 提供靈活的時間操作:使用LocalDateTime#truncatedTo()方法可以根據(jù)具體需求將日期時間截斷到不同的時間單位,從而實現(xiàn)靈活的時間操作。例如,可以將日期時間截斷到分鐘級別,然后進行加減運算,以實現(xiàn)精確到分鐘的日期時間計算。
使用場景:
- 需要截斷日期時間時:在一些特定的應用場景中,可能需要對日期時間進行截斷操作。例如,在進行統(tǒng)計或數(shù)據(jù)分析時,可能只需要日期時間中的某一部分信息,而不需要保留完整的時間信息。在這種情況下,可以使用LocalDateTime#truncatedTo()方法將日期時間截斷到所需的時間單位。
- 需要進行時間運算時:在進行時間運算時,如計算兩個日期時間之間的差值或進行日期的加減運算等,可以將日期時間截斷到分鐘或小時級別,以避免因毫秒級的時間差異而產(chǎn)生誤差。例如,可以使用LocalDateTime#truncatedTo()方法將日期時間截斷到分鐘級別,然后進行加減運算,以實現(xiàn)精確到分鐘的日期時間計算。
@Test
public void test10() {
LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
LocalDateTime localDateTime1 = localDateTime.truncatedTo(ChronoUnit.DAYS);
System.out.println(localDateTime1);//輸出結(jié)果:2020-02-01T00:00
}
LocalDateTime#plus(...)、LocalDateTime#plusYears(...)、LocalDateTime#plusMonths(...)、LocalDateTime#plusWeeks(...)、LocalDateTime#plusDays(...)、LocalDateTime#plusHours(...)、LocalDateTime#plusMinutes(...)、LocalDateTime#plusSeconds(...)、LocalDateTime#plusNanos(...)
上述方法,主要用于在現(xiàn)有的日期時間對象上增加指定的時間單位或量。
具體如下:
- LocalDateTime#plus(long amount, TemporalUnit unit):增加給定數(shù)量的單位到當前的日期時間對象。參數(shù)amount表示要增加的數(shù)量,參數(shù)unit表示要增加的時間單位,例如DAYS、WEEKS、MONTHS等。
- LocalDateTime#plusYears(long years):在當前日期時間對象上增加指定的年份數(shù)。參數(shù)years表示要增加的年份數(shù),可以為負數(shù)。
- LocalDateTime#plusMonths(long months):在當前日期時間對象上增加指定的月份數(shù)。參數(shù)months表示要增加的月份數(shù),可以為負數(shù)。
- LocalDateTime#plusWeeks(long weeks):在當前日期時間對象上增加指定的周數(shù)。參數(shù)weeks表示要增加的周數(shù),可以為負數(shù)。
- LocalDateTime#plusDays(long days):在當前日期時間對象上增加指定的天數(shù)。參數(shù)days表示要增加的天數(shù),可以為負數(shù)。
- LocalDateTime#plusHours(long hours):在當前日期時間對象上增加指定的小時數(shù)。參數(shù)hours表示要增加的小時數(shù),可以為負數(shù)。
- LocalDateTime#plusMinutes(long minutes):在當前日期時間對象上增加指定的分鐘數(shù)。參數(shù)minutes表示要增加的分鐘數(shù),可以為負數(shù)。
- LocalDateTime#plusSeconds(long seconds):在當前日期時間對象上增加指定的秒數(shù)。參數(shù)seconds表示要增加的秒數(shù),可以為負數(shù)。
- LocalDateTime#plusNanos(long nanos):在當前日期時間對象上增加指定的納秒數(shù)。參數(shù)nanos表示要增加的納秒數(shù),可以為負數(shù)。
使用場景:
- 日期時間的計算和運算:可以通過調(diào)用這些方法來對日期時間進行計算和運算。例如,可以使用LocalDateTime#plusYears()方法來計算未來某一年的日期時間,或者使用LocalDateTime#plusDays()方法來計算未來某一天的日期時間。
- 定時器和定時任務:這些方法可以與Java中的定時器類(如java.util.Timer)結(jié)合使用,以實現(xiàn)定時任務或定時觸發(fā)某些操作。例如,可以使用LocalDateTime#now()方法獲取當前日期時間,然后將其作為定時器的觸發(fā)時間。
- 時間的調(diào)整和格式化:可以使用這些方法來對日期時間進行調(diào)整和格式化。例如,可以使用LocalDateTime#plusHours()方法來將當前時間向前移動幾個小時,或者使用LocalDateTime#format()方法將日期時間格式化為特定的字符串格式。
- 日歷和日程安排:這些方法可以用于日歷和日程安排應用中。例如,可以使用LocalDateTime#plusMonths()方法來計算下個月的日期時間,或者使用LocalDateTime#plusWeeks()方法來計算未來一周的日期時間。
@Test
public void test11() {
LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
LocalDateTime localDateTime1 = localDateTime.plus(Period.ofDays(3));
LocalDateTime localDateTime2 = localDateTime.plus(3, ChronoUnit.DAYS);
System.out.println(localDateTime1);//輸出結(jié)果:2020-02-04T12:18:56
System.out.println(localDateTime2);//輸出結(jié)果:2020-02-04T12:18:56
LocalDateTime localDateTime3 = localDateTime.plusYears(1);
System.out.println(localDateTime3);//輸出結(jié)果:2021-02-01T12:18:56
LocalDateTime localDateTime4 = localDateTime.plusMonths(1);
System.out.println(localDateTime4);//輸出結(jié)果:2020-03-01T12:18:56
LocalDateTime localDateTime5 = localDateTime.plusWeeks(1);
System.out.println(localDateTime5);//輸出結(jié)果:2020-02-08T12:18:56
LocalDateTime localDateTime6 = localDateTime.plusDays(10);
System.out.println(localDateTime6);//輸出結(jié)果:2020-02-11T12:18:56
LocalDateTime localDateTime7 = localDateTime.plusHours(3);
System.out.println(localDateTime7);//輸出結(jié)果:2020-02-01T15:18:56
LocalDateTime localDateTime8 = localDateTime.plusMinutes(12);
System.out.println(localDateTime8);//輸出結(jié)果:2020-02-01T12:30:56
LocalDateTime localDateTime9 = localDateTime.plusSeconds(4);
System.out.println(localDateTime9);//輸出結(jié)果:2020-02-01T12:19
}
LocalDateTime#minus(...)、LocalDateTime#minusYears(...)、LocalDateTime#minusMonths(...)、LocalDateTime#minusWeeks(...)、LocalDateTime#minusDays(...)、LocalDateTime#minusHours(...)、LocalDateTime#minusMinutes(...)、LocalDateTime#minusSeconds(...)、LocalDateTime#minusNanos(...)
上述這些方法,用于對日期和時間的減法操作,需要注意的是,這些方法的計算結(jié)果值超過限制時可能會拋出DateTimeException異常。
具體如下:
- LocalDateTime#minus():該方法用于在當前LocalDateTime對象中減去指定的時間間隔。它接受一個TemporalAmount參數(shù),表示要減去的金額。返回值是此日期時間的副本,減去指定的金額。使用場景:在進行日期時間的減法操作時,可以使用該方法來減去指定的時間間隔。
- LocalDateTime#minusYears():該方法用于從此日期時間對象中減去給定的年份并返回LocalDateTime。它接受一個long類型的參數(shù),表示要減去的年份數(shù)。返回值是保存從該LocalDateTime減去給定年份的值的LocalDateTime。使用場景:在進行日期時間的減法操作時,可以使用該方法來減去指定的年份數(shù)。
- LocalDateTime#minusMonths():該方法用于從此日期時間對象中減去給定的月份并返回LocalDateTime。它接受一個long類型的參數(shù),表示要減去的月份數(shù)。返回值是保存從該LocalDateTime減去給定月份的值的LocalDateTime。使用場景:在進行日期時間的減法操作時,可以使用該方法來減去指定的月份數(shù)。
- LocalDateTime#minusWeeks():該方法用于從此日期時間對象中減去給定的周數(shù)并返回LocalDateTime。它接受一個long類型的參數(shù),表示要減去的周數(shù)數(shù)。返回值是保存從該LocalDateTime減去給定周數(shù)的值的LocalDateTime。使用場景:在進行日期時間的減法操作時,可以使用該方法來減去指定的周數(shù)數(shù)。
- LocalDateTime#minusDays():該方法用于從此日期時間對象中減去給定的天數(shù)并返回LocalDateTime。它接受一個long類型的參數(shù),表示要減去的天數(shù)數(shù)。返回值是保存從該LocalDateTime減去給定天數(shù)的值的LocalDateTime。使用場景:在進行日期時間的減法操作時,可以使用該方法來減去指定的天數(shù)數(shù)。
- LocalDateTime#minusHours():該方法用于從此日期時間對象中減去給定的小時數(shù)并返回LocalDateTime。它接受一個long類型的參數(shù),表示要減去的小時數(shù)。返回值是保存從該LocalDateTime減去給定小時數(shù)的值的LocalDateTime。使用場景:在進行日期時間的減法操作時,可以使用該方法來減去指定的小時數(shù)。
- LocalDateTime#minusMinutes():該方法用于從此日期時間對象中減去給定的分鐘數(shù)并返回LocalDateTime。它接受一個long類型的參數(shù),表示要減去的分鐘數(shù)。返回值是保存從該LocalDateTime減去給定分鐘數(shù)的值的LocalDateTime。使用場景:在進行日期時間的減法操作時,可以使用該方法來減去指定的分鐘數(shù)。
- LocalDateTime#minusSeconds():該方法用于從此日期時間對象中減去給定的秒數(shù)并返回LocalDateTime。它接受一個long類型的參數(shù),表示要減去的秒數(shù)。返回值是保存從該LocalDateTime減去給定秒數(shù)的值的LocalDateTime。使用場景:在進行日期時間的減法操作時,可以使用該方法來減去指定的秒數(shù)。
- LocalDateTime#minusNanos():該方法用于從此日期時間對象中減去給定的納秒數(shù)并返回LocalDateTime。它接受一個long類型的參數(shù),表示要減去的納秒數(shù)。返回值是保存從該LocalDateTime減去給定納秒數(shù)的值的LocalDateTime。使用場景:在進行高精度日期時間的減法操作時,可以使用該方法來減去指定的納秒數(shù)。
@Test
public void test12() {
LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
LocalDateTime localDateTime1 = localDateTime.minus(Period.ofDays(3));
LocalDateTime localDateTime2 = localDateTime.minus(3, ChronoUnit.DAYS);
System.out.println(localDateTime1);//輸出結(jié)果:2020-01-29T12:18:56
System.out.println(localDateTime2);//輸出結(jié)果:2020-01-29T12:18:56
LocalDateTime localDateTime3 = localDateTime.minusYears(1);
System.out.println(localDateTime3);//輸出結(jié)果:2019-02-01T12:18:56
LocalDateTime localDateTime4 = localDateTime.minusMonths(1);
System.out.println(localDateTime4);//輸出結(jié)果:2020-01-01T12:18:56
LocalDateTime localDateTime5 = localDateTime.minusWeeks(1);
System.out.println(localDateTime5);//2020-01-25T12:18:56
LocalDateTime localDateTime6 = localDateTime.minusDays(10);
System.out.println(localDateTime6);//輸出結(jié)果:2020-01-22T12:18:56
LocalDateTime localDateTime7 = localDateTime.minusHours(3);
System.out.println(localDateTime7);//輸出結(jié)果:2020-02-01T09:18:56
LocalDateTime localDateTime8 = localDateTime.minusMinutes(12);
System.out.println(localDateTime8);//輸出結(jié)果:2020-02-01T12:06:56
LocalDateTime localDateTime9 = localDateTime.minusSeconds(4);
System.out.println(localDateTime9);//輸出結(jié)果:2020-02-01T12:18:52
}
LocalDateTime#query(...)
LocalDateTime#query()接受一個TemporalQuery作為參數(shù),用于查詢此LocalDateTime。查詢的結(jié)果會根據(jù)傳遞的查詢邏輯來決定。通常在需要基于特定的查詢邏輯處理日期和時間的情況下使用。傳遞給查詢方法的邏輯是通過TemporalQuery對象定義的。因此,這個方法在使用時需要結(jié)合具體的查詢需求和TemporalQuery的實現(xiàn)來使用。
@Test
public void test13() {
LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
TemporalQuery<Integer> temporalQuery = item -> item.get(ChronoField.YEAR);
Integer year = localDateTime.query(temporalQuery);
System.out.println(year);//輸出結(jié)果:2020
}
LocalDateTime#until(...)
LocalDateTime#until() 方法用于計算兩個 LocalDateTime 對象之間的時間量,并以指定的 TemporalUnit 為單位返回結(jié)果。這個方法返回一個整數(shù),表示兩個 LocalDateTime 對象之間完整的時間單位數(shù)。
功能作用:
- 計算時間差:LocalDateTime#until() 方法可以計算兩個 LocalDateTime 對象之間的時間差。通過調(diào)用該方法并傳遞一個 TemporalUnit 參數(shù),可以獲取兩個日期時間之間的差距,單位可以是秒、分鐘、小時、天等。
- 提供靈活的時間計算:使用 LocalDateTime#until() 方法可以根據(jù)具體需求計算不同時間單位之間的差值。這使得開發(fā)者能夠根據(jù)實際需求進行精確到秒、分鐘、小時或天的時間計算,以滿足不同的業(yè)務需求。
使用場景:
- 需要計算時間差時:在一些特定的應用場景中,可能需要對兩個日期時間之間的時間差進行計算。例如,在記錄用戶活動日志時,需要計算用戶兩次操作之間的時間差,以便對用戶行為進行分析。在這種情況下,可以使用 LocalDateTime#until() 方法來獲取準確的時間差值。
- 需要進行時間運算時:除了計算時間差,LocalDateTime#until() 方法還可以用于時間運算。例如,可以使用該方法計算兩個日期之間的天數(shù),然后根據(jù)計算結(jié)果進行相應的操作。這可以幫助開發(fā)者在處理日期時間時提高計算的準確性和靈活性。
@Test
public void test14() {
LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
long until = localDateTime.until(LocalDateTime.of(2023, 2, 1, 12, 30, 56), ChronoUnit.YEARS);
System.out.println(until);//輸出結(jié)果:3
}
LocalDateTime#format(...)
LocalDateTime#format(...)用于將當前 LocalDateTime 對象格式化為指定的日期時間字符串。
@Test
public void test15() {
LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
String format = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(format);//輸出結(jié)果:2020-02-01 12:18:56
}
LocalDateTime#atOffset(...)
LocalDateTime#atOffset() 主要是用于合并當前LocalDateTime對象與給定的偏移量。具體來說,該方法創(chuàng)建并返回一個 OffsetDateTime 對象,該對象將保存將當前LocalDateTime 與給定偏移量合并后的值。主要在需要對LocalDateTime對象進行偏移量調(diào)整的情況下使用。例如,如果你需要根據(jù)當前的LocalDateTime創(chuàng)建一個在特定偏移量(如一小時,一天)后的日期時間,就可以通過使用LocalDateTime#atOffset()方法來實現(xiàn)。這個方法的使用非常靈活,你可以根據(jù)需要選擇不同的偏移量進行合并,得到的 OffsetDateTime 對象可以用于進一步的日期時間計算或展示等操作。
@Test
public void test16() {
LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
OffsetDateTime offsetDateTime = localDateTime.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime);//輸出結(jié)果:2020-02-01T12:18:56+08:00
}
LocalDateTime#atZone(...)
LocalDateTime#atZone()用于將給定的LocalDateTime對象合并到給定的時區(qū),從而創(chuàng)建一個ZonedDateTime對象。該方法是一個非靜態(tài)方法,只能通過類對象訪問。通過該方法,可以將在不同時區(qū)存儲的日期時間數(shù)據(jù)統(tǒng)一到一個時區(qū)中進行處理和比較。
使用場景:
- 需要處理跨時區(qū)的日期時間數(shù)據(jù)時:在一些特定的應用場景中,可能需要對來自不同時區(qū)的日期時間數(shù)據(jù)進行處理和比較。例如,在跨國公司中,可能需要將不同地區(qū)的日期時間數(shù)據(jù)統(tǒng)一到一個時區(qū)中進行統(tǒng)計分析。在這種情況下,可以使用LocalDateTime#atZone()方法將LocalDateTime對象轉(zhuǎn)換為ZonedDateTime對象,以便進行跨時區(qū)的日期時間操作。
- 需要確保日期時間數(shù)據(jù)的一致性時:在一些需要確保日期時間數(shù)據(jù)一致性的場景中,也可以使用LocalDateTime#atZone()方法。例如,在金融交易中,確保交易時間的準確性非常重要。通過使用該方法,可以將不同地區(qū)的日期時間數(shù)據(jù)轉(zhuǎn)換為相同的時區(qū),以確保交易時間的一致性。
@Test
public void test17() {
LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
System.out.println(zonedDateTime);//輸出結(jié)果:2020-02-01T12:18:56+08:00[Asia/Shanghai]
}
LocalDateTime#compareTo(...)、LocalDateTime#isAfter(...)、LocalDateTime#isBefore(...)、LocalDateTime#isEqual(...)
- compareTo(...):此方法用于比較當前LocalDateTime實例和其他日期時間的大小關系。它返回一個整數(shù),如果當前實例大于、小于或等于給定的日期時間,則返回正整數(shù)、負整數(shù)或零。這個方法通常用于排序或比較日期時間的大小。
- isAfter(...):此方法用于檢查作為參數(shù)傳遞的日期是否在此LocalDateTime實例之后。它返回一個布爾值,如果給定的日期時間小于當前實例,則返回false,否則返回true。這個方法通常用于判斷某個日期時間是否在當前時間之后。
- isBefore(...):此方法的功能與isAfter()相反,用于檢查作為參數(shù)傳遞的日期是否在此LocalDateTime實例之前。返回值與isAfter()相同,如果給定的日期時間大于當前實例,則返回false,否則返回true。這個方法通常用于判斷某個日期時間是否在當前時間之前。
- isEqual(...):此方法用于檢查作為參數(shù)傳遞的日期是否與當前LocalDateTime實例相等。它返回一個布爾值,如果兩個實例的時間值完全相等,則返回true,否則返回false。這個方法通常用于比較兩個日期時間是否完全相同。
@Test
public void test18() {
LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
LocalDateTime localDateTime2 = LocalDateTime.of(2023, 2, 1, 12, 18, 56);
int compareTo = localDateTime2.compareTo(localDateTime);
System.out.println(compareTo);//輸出結(jié)果:3
boolean before = localDateTime2.isBefore(localDateTime);
System.out.println(before);//輸出結(jié)果:false
boolean after = localDateTime2.isAfter(localDateTime);
System.out.println(after);//輸出結(jié)果:true
boolean equal = localDateTime2.isEqual(localDateTime);
System.out.println(equal);//輸出結(jié)果:false
}
使用LocalDateTime的注意事項
在使用 LocalDateTime 時,有一些注意事項需要特別注意,了解這些限制和注意事項可以確保正確有效地使用它:
- 時區(qū)問題:LocalDateTime 不包含時區(qū)信息,這可能會導致在處理具有時區(qū)差異的日期和時間時出現(xiàn)問題。
- 精度問題:LocalDateTime 精度到秒,不包含毫秒,這可能在某些需要更高精度的情況下會限制其使用。
- 不可變對象:LocalDateTime 是一個不可變對象,這意味著對 LocalDateTime 對象的任何修改操作都會生成一個新的實例返回,而不會改變原來的對象。這使得多線程操作中無需考慮線程安全問題,因為本身 API 層面就不支持修改。
- 空指針異常:在使用 LocalDateTime 的 get 方法訪問年、月、日等信息時,需要注意空指針異常的問題??梢允褂?isPresent() 方法來檢查是否存在值。
- 日期/時間格式化:LocalDateTime 沒有提供內(nèi)置的格式化方法,因此在使用時需要注意格式化問題??梢允褂?DateTimeFormatter 類來進行日期/時間格式化。
- 與其它日期/時間類型的轉(zhuǎn)換:在使用 LocalDateTime 時,可能需要將其與其它日期/時間類型進行轉(zhuǎn)換,如 LocalDate、LocalTime、ZonedDateTime 等。在進行轉(zhuǎn)換時,需要注意時區(qū)、精度等差異,以避免可能的問題。
- 時區(qū)處理:雖然 LocalDateTime 不包含時區(qū)信息,但在某些情況下可能需要考慮時區(qū)的影響。例如,在將 LocalDateTime 轉(zhuǎn)換為 ZonedDateTime 時,需要提供時區(qū)信息。
- 時間戳的獲取和比較:LocalDateTime 可以用于獲取當前時間戳(以毫秒為單位)以及進行時間戳的比較。在進行時間戳比較時,需要注意時區(qū)、精度等差異。
- 與數(shù)據(jù)庫中的日期/時間類型的轉(zhuǎn)換:在將 LocalDateTime 與數(shù)據(jù)庫中的日期/時間類型進行轉(zhuǎn)換時,需要注意數(shù)據(jù)庫中日期/時間的格式和類型,以及可能的時區(qū)差異。