如何获取指定年月中,周几的日期(例如获取2月中所有周三的日期)

本次开发场景如下:

        用户的计划是排在周三的,但是用户的前端需要显示在周五上,所以理论上来讲,我只需获取用户周三是否有计划,如果有计划,则在查询中使用,DATE_ADD(日期, INTERVAL 2 DAY)函数返回周三的日期加上两天即可,但是事实上并没有那么简单,这里还需要考虑跨月的问题。
        例如2023-03-01是周五 则我需要查询2023-02-28周三是否有审核计划,而且我返回给前端的数据是截取出来的,例如2023-03-01,我在SQL中会截取到只剩下01这个天数返回给前端,2023-03是不会返回给前端的,这就造就了一个问题,例如我查询2月份的计划,那么2月28日是周三有审核计划,他就会加到2023-03-01并且截取01返回给我,但是我前端显示的是每月份的,所以如果返回给我01,那他默认会是在2月01这天,这天显然是周四,不符合我的逻辑,所以需要解决月初和月末的问题。
综上所述的两个跨月问题就是:

如果本月第一天是周四或者周五,则获取上个月最后一个周三的日期(具体的逻辑可以自己好好想想,看看日历这个容易理解)
如果本月最后一个周三加上两天之后大于本月最后一天,则不需要获取本月最后一个周三的日期

我们先来看最简单的代码,不考虑跨月的问题,例如:在2024年3月,获取3月中每个周三的日期(PS:代码中大量运用到了LocalDate类如果不熟练请看我这篇文章)

详解LocalDateicon-default.png?t=N7T8https://blog.csdn.net/jialuosi/article/details/133770363?spm=1001.2014.3001.5501

public static void main(String[] args) {
    //假定我需要获取2024年03月的,本周三的所有日期
    int year = 2024;
    int month = 03;
    //使用LocalData来获取本月的第一天
    LocalDate firstDayOfMonth = LocalDate.of(year, month, 1);
    //使用LocalData来获取本月的最后一天
    //日期.lengthOfMonth() : 获取日期所在月份的天数:
    LocalDate lastDayOfMonth = LocalDate.of(year, month, firstDayOfMonth.lengthOfMonth());
    //创建存放星期三日期的List
    List<LocalDate> wednesdayDates = new ArrayList<>();
    //临时变量 当天
    LocalDate currentDay = firstDayOfMonth;
    //如果 当天的日期小于本月最后一天  或者  当天等于本月最后一天 则执行循环
    while (currentDay.isBefore(lastDayOfMonth) || currentDay.isEqual(lastDayOfMonth)) {
        //日期.getDayOfWeek() : 获取星期几枚举值 返回值为DayOfWeek类型
        //DayOfWeek.WEDNESDAY : 星期三的枚举值
        if (currentDay.getDayOfWeek() == DayOfWeek.WEDNESDAY) {
            //如果当天的值为星期三 则添加到List中
            wednesdayDates.add(currentDay);
        }
        // 当天天数加一 重新开始循环
        currentDay = currentDay.plusDays(1);
    }
    System.out.println(wednesdayDates);
}

输出的List结果为:

[2024-03-06, 2024-03-13, 2024-03-20, 2024-03-27]

上面的代码非常简单,接下来我们看看考虑跨月的问题,先来看总代码,我把它抽成了一个函数,然后我们挨个解析

public static LocalDate[] getWednesdayDates(int year, int month) {
    LocalDate firstDayOfMonth = LocalDate.of(year, month, 1);
    LocalDate lastDayOfMonth = LocalDate.of(year, month, firstDayOfMonth.lengthOfMonth());
    List<LocalDate> wednesdayDates = new ArrayList<>();
    // 检查本月第一天是周四或周五
    if (firstDayOfMonth.getDayOfWeek() == DayOfWeek.THURSDAY || firstDayOfMonth.getDayOfWeek() == DayOfWeek.FRIDAY) {
        // 获取上个月最后一个周三的日期
        LocalDate lastWednesdayOfPreviousMonth = firstDayOfMonth.minusDays(1).with(DayOfWeek.WEDNESDAY);
        wednesdayDates.add(lastWednesdayOfPreviousMonth);
    }
    // 循环遍历本月的每一天,找到所有周三日期
    LocalDate currentDay = firstDayOfMonth;
    while (currentDay.isBefore(lastDayOfMonth) || currentDay.isEqual(lastDayOfMonth)) {
        if (currentDay.getDayOfWeek() == DayOfWeek.WEDNESDAY) {
            wednesdayDates.add(currentDay);
        }
        currentDay = currentDay.plusDays(1);
    }
    // 检查本月最后一个周三加两天后是否超过了本月最后一天
    LocalDate lastWednesdayOfMonth = lastDayOfMonth.with(DayOfWeek.WEDNESDAY);
    if (lastWednesdayOfMonth.plusDays(2).isAfter(lastDayOfMonth)) {
        wednesdayDates.remove(lastWednesdayOfMonth);
    }
    // 将List转换为数组
    LocalDate[] wednesdayArray = new LocalDate[wednesdayDates.size()];
    wednesdayArray = wednesdayDates.toArray(wednesdayArray);
    return wednesdayArray;
}

首先我们先解决月初的跨月问题:如果本月第一天是周四或者周五,则获取上个月最后一个周三的日期

if (firstDayOfMonth.getDayOfWeek() == DayOfWeek.THURSDAY || firstDayOfMonth.getDayOfWeek() == DayOfWeek.FRIDAY) {
    // 获取上个月最后一个周三的日期
    // firstDayOfMonth.minusDays(1):firstDayOfMonth是本月第一天 minusDays(1)是减去一天,则这个日期获取到的就是上个月的最后一天
    // with() 方法用于返回一个新的日期时间对象,with(DayOfWeek.WEDNESDAY)方法将日期调整为 当前日期所在周的周三 。
    // with(DayOfWeek.WEDNESDAY) :这个方法会找到与指定星期几(这里是周三)最接近的日期
    LocalDate lastWednesdayOfPreviousMonth = firstDayOfMonth.minusDays(1).with(DayOfWeek.WEDNESDAY);
    wednesdayDates.add(lastWednesdayOfPreviousMonth);
}

这个代码的主要就是 日期.with(DayOfWeek.WEDNESDAY) 这个方法,同样的,看月末

LocalDate lastWednesdayOfMonth = lastDayOfMonth.with(DayOfWeek.WEDNESDAY);
// 最后一天所在周的周三日期 加上两天后 如果大于最后一天 则在数组中去掉这个周三的日期
if (lastWednesdayOfMonth.plusDays(2).isAfter(lastDayOfMonth)) {
    wednesdayDates.remove(lastWednesdayOfMonth);
}

问题到这里差不多就解决了,我们来看看输出:
2024-02月是一个很好的例子,他的第一天是周五,所以要返回上个月最后一个周三的日期
而月末最后一个周三2024-02-28加两天正好跨月到了2024-03-01,所以28日也不应该输出

问题到这里就解决的差不多了,希望能有所收获


 

  • 31
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值