[英]Get weeks between 2 dates with weeks crossing 2 months
我想得到 2 個日期之間的所有星期,每個月計算兩次跨越 2 個月的星期。 例如,在 2021 年的第 14 周同時舉辦了 3 月和 4 月,因此在這種情況下,我希望該周計算兩次(一次用於 3 月,一次用於 4 月)。 我查看並找到了計算兩個日期之間的周數的庫。 我想我可以獲得周數和月份數並形成一個獨特的數組,但這似乎有點過頭了。 有人有什么建議嗎?
跨越 2 個月的周算了兩次
下面的代碼允許僅使用標准LocalDate
class 及其方法isBefore()
、 plusWeeks()
、 plusDays()
來做到這一點。
請記住,星期幾和月份由java.time
package 中的枚舉表示。
我做了幾個假設:
public static void main(String[] args) {
System.out.println(getWeekCount(LocalDate.of(2022, 1, 1),
LocalDate.of(2022, 2, 1)));
System.out.println(getWeekCount(LocalDate.of(2022, 1, 1),
LocalDate.of(2022, 3, 1)));
}
public static int getWeekCount(LocalDate date1, LocalDate date2) {
int weekCount = 0;
LocalDate cur = date1;
LocalDate finish = date2;
// assumption: week starts with sunday
// assumption: chunk of week at the start and at the end have to be taken into account as well as full weeks
if (cur.getDayOfWeek() != DayOfWeek.SUNDAY) { // adjusting current date
LocalDate next = cur.plusDays(DayOfWeek.SUNDAY.ordinal() - cur.getDayOfWeek().ordinal() + 1);
weekCount += getWeeksIncrement(cur, next);
cur = next;
}
if (finish.getDayOfWeek() != DayOfWeek.SUNDAY) { // adjusting finish date
LocalDate previous = finish.minusDays(finish.getDayOfWeek().ordinal() + 1);
weekCount += getWeeksIncrement(previous, finish);
finish = previous;
}
while (cur.isBefore(finish) || cur.equals(finish)) {
LocalDate next = cur.plusWeeks(1);
weekCount += getWeeksIncrement(cur, next);
cur = next;
}
return weekCount;
}
public static int getWeeksIncrement(LocalDate cur, LocalDate next) {
return weekIsSharedBetweenTwoMonth(cur, next) ? 2 : 1;
}
public static boolean weekIsSharedBetweenTwoMonth(LocalDate cur, LocalDate next) {
return next.getMonth() != cur.getMonth() &&
next.withDayOfMonth(1).isAfter(cur);
}
Output
7 - weeks between: 2022-01-01 and 2022-02-01
12 - weeks between: 2022-01-01 and 2022-03-01
好吧,這可以通過結合使用 Java 日期和時間 API ( java.time
) 和 Java 流 API ( java.util.stream
) 來實現:
long weeksBetween(LocalDate start, LocalDate endInclusive) {
LocalDate normalizedStart = start.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
LocalDate normalizedEndExclusive = endInclusive.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
return Stream.iterate(normalizedStart, d -> d.plusWeeks(1))
.takeWhile(d -> d.isBefore(normalizedEndExclusive))
.mapToInt(d -> d.getMonthValue() == d.plusDays(6).getMonthValue() ? 1 : 2)
.sum();
}
這里發生的事情如下。
首先,日期被規范化,也就是說,它們被設置為一周的開始(根據 ISO 標准是星期一)。
然后我們遍歷每個星期的星期一,並檢查它的最后一天(星期日)是否在同一個月內。 如果是,則產生1
,否則產生2
。
最后,我們對所有產生的值求和。
請注意,我假設一周從星期一 (ISO) 開始。 該代碼還將開始日期和結束日期的一周視為完整日期。
您可以使用 java.time 獲取周數:
LocalDate date = LocalDate.of(year, month, day);
int weekOfYear = date.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
您沒有提到您使用的是哪個 java 版本。 java.time 是在 java 8 中引入的。還有其他解決方案可用於 pre-java 8。
基於以上,你應該能夠解決你的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.