我試圖找出兩個日期之間有多少個月。我的代碼現在是這樣的
ChronoUnit.MONTHS.between(d1, d2)
問題是結果很長。例如,如果日期僅在幾天內不同,我應該得到類似 0.34 而不是 0 的結果。
另外我需要我的代碼來說明日歷,我不能假設每個月有 31 天。
Diff between 1999-05-12 and 1999-08-24
Assuming all months have 31 days for simplicity
result = (19/31 31/31 31/31 24/31) = 2.793
According to the calendar we replace the 31s with the correct number of days for that specific year and month
uj5u.com熱心網友回復:
這是我的解決方案:
public static double monthsBetween(LocalDate start, LocalDate end) {
if (start.isAfter(end)) throw new IllegalArgumentException("Start must be before end!");
var lastDayOfStartMonth = start.with(TemporalAdjusters.lastDayOfMonth());
var firstDayOfEndMonth = end.with(TemporalAdjusters.firstDayOfMonth());
var startMonthLength = (double)start.lengthOfMonth();
var endMonthLength = (double)end.lengthOfMonth();
if (lastDayOfStartMonth.isAfter(firstDayOfEndMonth)) { // same month
return ChronoUnit.DAYS.between(start, end) / startMonthLength;
}
long months = ChronoUnit.MONTHS.between(lastDayOfStartMonth, firstDayOfEndMonth);
double startFraction = ChronoUnit.DAYS.between(start, lastDayOfStartMonth.plusDays(1)) / startMonthLength;
double endFraction = ChronoUnit.DAYS.between(firstDayOfEndMonth, end) / endMonthLength;
return months startFraction endFraction;
}
這個想法是您使用時間調整器找到 ' 月的最后一天start( lastDayOfStartMonth) 和end' 月的第一天 ( )。firstDayOfEndMonth這兩個日期非常重要。您想要的數字是以下各項的總和:
start和之間的月份的小數lastDayOfStartMonthlastDayOfStartMonth和之間的整個月數firstDayOfEndMonth。firstDayOfEndMonth和之間的月份的小數end。
然后是兩個日期在同一個月內的邊緣情況,這很容易處理。
通過使用這個定義,任何兩個月的第一天之間的月數總是一個整數這個很好的性質得以保持。
請注意,在第一次計算中,您必須將一天添加到lastDayOfStartMonth,因為ChronoUnit.between將上限視為獨占,但我們實際上希望將其計為一天。
uj5u.com熱心網友回復:
要解決此問題,您需要考慮以下情況:
日期屬于同一年和月;
日期屬于不同的年份和/或月份;
日期無效。
當日期屬于同一年和月時,結果將是兩個日期之間的天數之差除以該月的天數,可以使用LocalDate.lengthOfMonth().
在一般情況下,日期范圍可以分為三個部分:
- 在給定日期范圍的開頭和結尾處的兩個小數部分(當兩個資料屬于同一年/月時,可以使用最簡單情況的方法對兩者進行評估)
- 整個部分,我們可以用
ChronoUnit.MONTHS.between()它來計算。
以下是實作的樣子(d1- 包含,d2- 獨占):
public static double getFractionalMonthDiff(LocalDate d1, LocalDate d2) {
if (d1.isAfter(d2)) throw new IllegalArgumentException(); // or return a value like -1
if (d1.getYear() == d2.getYear() && d1.getMonth() == d2.getMonth()) { // dates belong to same month and year
return getFractionalPartOfMonth(d2.getDayOfMonth() - d1.getDayOfMonth(), d1.lengthOfMonth());
}
int monthLen1 = d1.lengthOfMonth();
return getFractionalPartOfMonth(monthLen1 - (d1.getDayOfMonth() - 1), monthLen1) // from the given day of month of the First Date d1 Inclusive to the Last day of month
getFractionalPartOfMonth(d2.getDayOfMonth() - 1, d2.lengthOfMonth()) // from the First day of month to given day of month of the Second Date d2 Exclusive (for that reason 1 day was subtracted, and similarly on the previous line 1 day was added)
ChronoUnit.MONTHS.between(d1.withDayOfMonth(monthLen1), d2.withDayOfMonth(1));
}
public static double getFractionalPartOfMonth(int daysInterval, int monthLength) {
return daysInterval / (double) monthLength;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/512108.html
標籤:爪哇斯卡拉日期约会时间
