Java 中的四捨五入日期
一、簡介
在某些情況下,當我們在 Java 中處理日期時,我們可能必須將它們四捨五入到某個單位,例如小時、天或月。它提供了諸如聚合數據以進行分析和報告以及允許指定顯示資訊的詳細程度等優點。
在本教程中,我們將學習如何使用java.util.Date
以及LocalDateTime
和ZonedDateTime
對日期進行舍入。
2. 基本舍入
在基本舍入方法中,我們可以截斷 Java 中任何日期的時間部分。具體來說,這需要使所有時間元素等於零。我們可以這樣做:
Date roundToDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
roundToDay()
方法採用Date
物件作為參數。然後,我們使用Calender
類別中的setTime()
方法,並使用它來使用set()
方法將小時、分鐘、秒和毫秒四捨五入到一天的開始。
3. 四捨五入到最接近的單位
我們可以選擇使舍入方法保持不變,以使日期與小時、天或月等單位的捨入相匹配,如下所示:
Date roundToNearestUnit(Date date, int unit) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
switch (unit) {
case Calendar.HOUR:
int minute = calendar.get(Calendar.MINUTE);
if (minute >= 0 && minute < 15) {
calendar.set(Calendar.MINUTE, 0);
} else if (minute >= 15 && minute < 45) {
calendar.set(Calendar.MINUTE, 30);
} else {
calendar.set(Calendar.MINUTE, 0);
calendar.add(Calendar.HOUR_OF_DAY, 1);
}
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
break;
case Calendar.DAY_OF_MONTH:
int hour = calendar.get(Calendar.HOUR_OF_DAY);
if (hour >= 12) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
break;
case Calendar.MONTH:
int day = calendar.get(Calendar.DAY_OF_MONTH);
if (day >= 15) {
calendar.add(Calendar.MONTH, 1);
}
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
break;
}
return calendar.getTime();
}
在這裡,我們有一個roundToNearestUnit()
方法,它需要傳入一個Date
和一個int
單位,該方法旨在將輸入日期四捨五入為指定的時間單位。
為此,程式碼建立Calendar
的實例並將其設定為輸入日期。我們將檢索並調整分鐘、小時或天組件,以允許日期四捨五入到最近的 30 分鐘間隔、天或月,具體取決於選擇的單位( Calendar.HOUR
、 Calendar.DAY_OF_MONTH
或Calendar
. MONTH
) .
此外,我們確保秒和毫秒也歸零。根據定義的時間單位進行上述修改後,程式碼傳回從產生的Calendar
實體派生的新Date
。
4. 使用**LocalDateTime
**進行舍入
LocalDateTime
是 Java 中的一個新類,它使我們能夠在不同層級上舍入日期,從而為處理日期和時間提供更新的解決方案。以下是使用LocalDateTime
舍入日期的兩種方法:
LocalDateTime roundToStartOfMonth(LocalDateTime dateTime) {
return dateTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
}
在上面的方法roundToStartOfMonth()
中,我們將月份中的某一天設為 1,以將給定的LocalDateTime
舍入到月初,並在午夜重置所有時間組件(0 小時、0 分鐘、0 秒和0納秒)。
我們也可以使用LocalDateTime
將給定日期舍入到週末,如下所示:
LocalDateTime roundToEndOfWeek(LocalDateTime dateTime) {
return dateTime.with(TemporalAdjusters.next(DayOfWeek.SATURDAY))
.withHour(23)
.withMinute(59)
.withSecond(59)
.withNano(999);
}
RoundToEndOfWeek
() 方法利用TemporalAdjusters.next()
函數將LocalDateTime
舍入到下一個星期六的末尾,該函數查找下一個星期六並設定其時間組成部分,例如 23 小時、59 分鐘、59 秒和 999 奈秒。
5. 使用**ZonedDateTime
**進行舍入
ZonedDateTime
類別可以在存在時區的情況下對日期進行四捨五入。以下是使用 ZonedDateTime 對日期進行舍入的兩種方法:
ZonedDateTime roundToStartOfMonth(ZonedDateTime dateTime) {
return dateTime.withDayOfMonth(1)
.withHour(0)
.withMinute(0)
.withSecond(0)
.with(ChronoField.MILLI_OF_SECOND, 0)
.with(ChronoField.MICRO_OF_SECOND, 0)
.with(ChronoField.NANO_OF_SECOND, 0);
}
上面的方法roundToStartOfMonth()
將ZonedDateTime
當作輸入並傳回一個新的ZonedDateTime
。具體來說,它返回相同的日期和時間,但時間部分設定為月初的午夜 ( 00:00:00.000
)。
要將輸入Date
四捨五入到本週結束,我們看以下範例:
public static ZonedDateTime roundToEndOfWeek(ZonedDateTime dateTime) {
return dateTime.with(TemporalAdjusters.next(DayOfWeek.SATURDAY))
.withHour(23)
.withMinute(59)
.withSecond(59)
.with(ChronoField.MILLI_OF_SECOND, 999)
.with(ChronoField.MICRO_OF_SECOND, 999)
.with(ChronoField.NANO_OF_SECOND, 999);
}
在roundToEndOfWeek()
方法中,我們先使用TemporalAdjusters
來尋找下一個星期六,然後將時間設定為 ( 23:59:59.999999999
)。
六,結論
總之,在 Java 中處理基於時間的資料舍入日期是最重要的任務之一。在本教程中,我們了解了將日期舍入到不同單位和精度等級的一些方法,例如截斷和自訂舍入方法。
請注意,每個日期都應考慮時間變化,尤其是國際上使用的應用程式。
與往常一樣,本文的完整程式碼範例可以 在 GitHub 上找到。