首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >下一个星期五是一个月中的第一个星期五、第二个星期五还是第三个星期五。

下一个星期五是一个月中的第一个星期五、第二个星期五还是第三个星期五。
EN

Stack Overflow用户
提问于 2021-10-17 14:50:14
回答 3查看 180关注 0票数 1

我需要找到下一个n个星期五,但不包括第4个和可能第5个星期五,即我想得到下一个n个星期五,即每个月的第1、第2或第3。我已经找到了一种在下一个星期五(例如下10个星期五)进行流动的方法:

代码语言:javascript
复制
LocalDate now = LocalDate.now();
Stream.iterate(now , localDate -> localDate.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)))
     .skip(1) // skip today 
     .limit(10)
     .forEach(System.out::println);

输出:

代码语言:javascript
复制
2021-10-22
2021-10-29
2021-11-05
2021-11-12
2021-11-19
2021-11-26
2021-12-03
2021-12-10
2021-12-17
2021-12-24

但我需要排除例如2021-10-22 & 2021-10-29,因为它们是10月4日和5日。同样的,2021-11-26 & 2021-12-24因为他们不是第一,第二或第三个星期五。

我已经搜索过了,并找到了一些方法来计算一个月的第九个星期五,例如这个。

代码语言:javascript
复制
public static LocalDate nthFridayOfMonth(LocalDate localDate, int week) {
    return localDate.with(TemporalAdjusters.dayOfWeekInMonth(week, DayOfWeek.FRIDAY));
}

返回给定日期的第九个星期五。

如果给定的LocalDate是一个月中的第一个、第二个或第三个星期五,那么如何修改该方法以返回布尔值?或者用这个方法来实现另一个方法来完成我所需要的?

理想情况下,我希望使用上面的流,并使用一个方法,该方法作为过滤器返回一个布尔值:

代码语言:javascript
复制
LocalDate now = LocalDate.now();
Stream.iterate(now , localDate -> localDate.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)))
     .skip(1) // skip today 
     .filter(d -> is1st2ndOr3rdFriday(d))   
     .limit(10)
     .forEach(System.out::println);

要获得

代码语言:javascript
复制
2021-11-05
2021-11-12
2021-11-19
2021-12-03
2021-12-10
2021-12-17
2022-01-07
2022-01-14
2022-01-21
2022-02-04

欣赏有关如何实现筛选方法boolean is1st2ndOr3rdFriday(LocalDate d) {}的任何帮助

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-10-17 15:01:41

您可以获得本地日期的ALIGNED_WEEK_OF_MONTH时态字段,并检查它是否为≤3。

代码语言:javascript
复制
Stream.iterate(now , localDate -> localDate.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)))
    .skip(1) // skip today
    .filter(x -> x.get(ChronoField.ALIGNED_WEEK_OF_MONTH) <= 3)
    .limit(10)
    .forEach(System.out::println);
票数 6
EN

Stack Overflow用户

发布于 2021-10-26 19:46:32

另一种选择:迭代月份

为了变化,这里有一个不同的想法。我正在创建一个月流,并明确地从每个月的前3个星期五开始。

代码语言:javascript
复制
    LocalDate today = LocalDate.now(ZoneId.systemDefault());
    YearMonth thisMonth = YearMonth.from(today);
    List<LocalDate> fridays = Stream.iterate(thisMonth, ym -> ym.plusMonths(1))
            .flatMap(ym -> Stream.of(fridayOfMonth(ym, 1), fridayOfMonth(ym, 2), fridayOfMonth(ym, 3)))
            .filter(date -> date.isAfter(today))
            .limit(10)
            .collect(Collectors.toList());
    System.out.println(fridays);

今天运行时输出:

2021-11-05,2021-11-12,2021-11-19,2021-12-03,2021-12-10,2021-12-17,2022-01-07,2022-01-14,2022-01-21,2022-02-04

我用下列辅助方法找出了一个月的第九个星期五:

代码语言:javascript
复制
private static LocalDate fridayOfMonth(YearMonth ym, int no) {
    return ym.atDay(15).with(DayOfWeek.FRIDAY).with(ChronoField.ALIGNED_WEEK_OF_MONTH, no);
}

A变体:仍然是为了变化,下面是创建一个月前三个星期五的流的不同方法:

代码语言:javascript
复制
    List<LocalDate> fridays = Stream.iterate(thisMonth, ym -> ym.plusMonths(1))
            .flatMap(MyClass::firstThreeFridays)
            .filter(date -> date.isAfter(today))
            .limit(10)
            .collect(Collectors.toList());

这次我的辅助方法是这样的:

代码语言:javascript
复制
private static Stream<LocalDate> firstThreeFridays(YearMonth ym) {
    LocalDate firstFriday = ym.atDay(1).with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY));
    return Stream.of(firstFriday, firstFriday.plusWeeks(1), firstFriday.plusWeeks(2));
}

结果和以前一样。

(迭代几个月的想法也出现在巴兹尔·伯克( Basil Bourque)的一个现已删除的答案中。)

票数 2
EN

Stack Overflow用户

发布于 2021-10-17 15:20:56

另一种解决方案:您可以GroupBy您的日期(到Map>),然后对于每个月键,如果有超过3个日期,删除它,并返回结果:

代码语言:javascript
复制
public static void main(String[] args) {
    // initialize your date here:
    LocalDate now = LocalDate.now();
    // Grouping Dates By Month 
    Map<Month, List<LocalDate>> map = Stream
            .iterate(LocalDate.of(now.getYear(), now.getMonth(), 1),
                    localDate -> localDate.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)))
            .limit(20).collect(Collectors.groupingBy(element -> element.getMonth()));
    // delete the 4 or 5 fridays
    map.forEach((k, v) -> {
        if (v.size() > 3)
            v.removeIf(e -> e.isBefore(now) || v.indexOf(e) > 2);
    });
    // print results sorted
    Stream.of(map.values()).flatMap(e -> e.stream()).flatMap(List::stream).sorted().limit(10)
            .forEach(System.out::println);
}

输出

2021-11-05

2021-11-12

2021-11-19

2021-12-03

2021-12-10

2021-12-17

2022-01-07

2022-01-14

2022-01-21

2022-02-04

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69605486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档