java 获取缺少每月31日的每周的日期

nzkunb0c  于 2022-12-25  发布在  Java
关注(0)|答案(2)|浏览(207)

我计算每周的同一天:

import java.time.LocalDate;
import java.util.List;
import java.util.ArrayList;
        
class HelloWorld {
    public static void main(String[] args) {
        LocalDate startLocalDate = LocalDate.parse("2023-01-03");
        LocalDate endLocalDate = startLocalDate.withDayOfMonth(startLocalDate.getMonth().length(startLocalDate.isLeapYear()));
        int startDayOfWeek = startLocalDate.getDayOfWeek().getValue();
        List<LocalDate> listOfDays = new ArrayList<LocalDate>();
            for (LocalDate date = startLocalDate; date.isBefore(endLocalDate); date = date.plusDays(1)) {
            if (date.getDayOfWeek().getValue() == startDayOfWeek) {
                listOfDays .add(date);
            }
        }
        System.out.println(listOfDays);
    }
}

我得到:

[2023-01-03, 2023-01-10, 2023-01-17, 2023-01-24]

但我期望得到的是

[2023-01-03, 2023-01-10, 2023-01-17, 2023-01-24, 2023-01-31]

31号不见了。

gmol1639

gmol16391#

Answer by rzwitserloot是正确的和聪明的。

此外,仅供参考,流使这样的工作变得更容易。
LocalDate#datesUntil方法生成LocalDate对象的Stream,我们可以过滤这些对象以匹配我们想要的星期几。

LocalDate start = LocalDate.parse( "2023-01-03" );
DayOfWeek dayOfWeek = start.getDayOfWeek();
LocalDate stop = start.withDayOfMonth( 1 ).plusMonths( 1 ); // Using Half-Open approach, running up to but not including first day of following month. End date is *exclusive* while the start date is *inclusive*. 

List < LocalDate > datesInSameMonthWithSameDayOfWeek =
        start
                .datesUntil( stop )
                .filter(
                        date -> date.getDayOfWeek().equals( dayOfWeek )
                )
                .toList()
;

看这个code run at Ideone.com
[二〇二三年一月三日、二〇二三年一月十日、二〇二三年一月十七日、二〇二三年一月二十四日、二〇二三年一月三十一日]
我们 * 可能 * 通过使用另一个datesUntil方法获取step参数来获得一些效率,但是我不会为这样少量的数据而烦恼。

dkqlctbz

dkqlctbz2#

栅栏错误。循环的“结束条件”为:
如果date变量在endDate之前不再,请立即停止。
for (init; cond; incr) code;
等同于:

init;
while (cond) {
  code;
  incr;
}

这意味着,一旦datefor增量(date = date.plusDays(1))更新,新日期将立即用条件(是否仍然在endDate之前)进行检查,如果条件不成立,循环将立即中止。
因此,您的代码将在1月31日执行,并当场中止循环,它永远不会得到处理。
假设您想要的条件不是date.isBefore(endDate),而是!date.isAfter(endLocalDate),以确保处理了1月31日 IS
或者,保持其原样,但编辑终止日期。这样可以简化终止日期的计算:

LocalDate endLocalDate = startLocalDate.withDayOfMonth(1).plusMonths(1);

现在endLocalDate是feb1st,这意味着jan31st仍在处理,然后feb1st导致循环停止。

相关问题