java中有比较好的方式去获取某个月中星期几所对应的日期吗?
请教下大家,有一个需求是根据月份,去找出这个月星期几所对应的日期是哪几天?例如给出2020年12月,找出所有周六,那么结果要返回 5、12、19、26这几天,我目前的思路是找出某个月符合条件的第一个日期,然后不断加7天,去判断,不过这样子看上去比较耿直,java8中有没有更好一些的方式或者api提供呢?
回答
加7天的方式来说,是比较耿直的,但是这也是很顺畅并且正确的思路嘛,就算有java8
封装好的一些api,它本质的实现逻辑肯定也还是逃不过这个天数的加减嘛,毕竟加减总比挨着挨着比要好点噻
话说回来,那我开始看到这里,我首先就想到了笨办法,挨着挨着比嘛。
(注:不过在列出我的代码前,我想额外提一点,我建议呢,这个方法的入参最好还是要加个年吧,毕竟2019的12月里的周六,和2020年的12月的周六,那肯定是不一样的。所以我下面给出的方法,入参都是年+月)
那思路就很简单啦,我们直接根据输入的年和月
- 构造出咱们的
YearMonth
(这个可是java8
新增的年月的时间类,整挺好) - 根据
YearMonth
的lengthOfMonth()
可以快速得到这个月多少天 - 依据这个月多少天,利用
IntStream.rangeClosed()
方法构造一个这个月所有天的数字流IntStream
,再用mapToObject()
方法转换成Stream<LocalDate>
Stream<LocalDate>
挨着挨着判断是否等于周六,最后collector(Collectors.toList())
完成
public static List<LocalDate> querySaturday(int year, Month month) { YearMonth yearMonth = YearMonth.of(year, month);
return IntStream.rangeClosed(1, yearMonth.lengthOfMonth())
.mapToObj(day -> LocalDate.of(year, month, day))
.filter(day -> day.getDayOfWeek() == DayOfWeek.SATURDAY)
.collect(Collectors.toList());
}
总之也还算比较简单,不过就是有点费空间,毕竟中间有很多不要的LocalDate
被new
出来了
那回到题主最早想的加减法方式,当然我们肯定不会自己去加减,不过思路其实和上面一样,肯定也是要构建一个流的,不过加减法的说法那是我们程序员最底层的思维方式,但是放在理解java8
的很多api
设计上,咱们需要的是声明式的思维,告诉api
你想要什么,而不是告诉它怎么去实现,这样起码来说找方法你会想到一些关键词,也就是说其实我最开始也是不知道具体到底有没有api
,一旦你多了解了一些java8
的api
设计,不说怎么设计,起码它这个起名你就摸到点门道~
那关键词是什么么?是next
,下一个,虽然最开始我不知道到底有没有api
,但是我的思路是:
构造一个流,这个流的创建是基于下一个周六,这样的模式创建的流里都是周六,然后依据个数简单截断,再依据月份进行过滤,最终得到答案
那为啥我会想到是next
呢?在调整时间上api
是咱们的TemporalAdjuster
接口掌管,一个TemporalAdjuster
接口实现就是一种调整时间的方式,它很多的实现类都在已经为你写好的工具类TemporalAdjusters
中,对,多了个s
,这里面的静态构造方法名,你打开一看就明白了
尽都是些很直抒胸臆的方法命名,一看你就知道它在做啥。什么first
,last
,previous
,那我也就立马发现这个方法,恰好就叫next
,传参就是DayOfWeek
,
DayOfWeek
是啥?就是周一到周六的枚举啊,官方的
安排的明明白白,那就简单了,我们找到了如何获取下一个周六的方法,那我们只需要首先获取这个年月的第一个周六,然后依照TemporalAdjusters.next
方法就可以构造出所有都是周六的流了
那我们怎么获取这个年月的第一个周六呢?还记得刚才说的么?那就找找first
开头的方法呗,巧了,还真有一个firstInMonth
,传参也是DayOfWeek
,这不就简单了么,所以我们可以直接完整代码了
public static List<LocalDate> querySaturday(int year, Month month) { YearMonth yearMonth = YearMonth.of(year, month);
LocalDate firstSaturday = LocalDate.now().with(yearMonth).with(TemporalAdjusters.firstInMonth(DayOfWeek.SATURDAY));
return Stream.iterate(firstSaturday, localDate -> localDate.with(TemporalAdjusters.next(DayOfWeek.SATURDAY)))
.limit(4)
.filter(localDate -> localDate.getMonth() == month)
.collect(Collectors.toList());
}
差不多就是这样叭,拜了个拜~
以上是 java中有比较好的方式去获取某个月中星期几所对应的日期吗? 的全部内容, 来源链接: utcz.com/a/71469.html