You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java实现指定日期当月第N个星期几检测及后续6个月计算

Java检测当月第N个星期几&计算后续月份对应日期

嘿,这个问题我太熟了!Java 8之后引入的java.time包(JSR-310标准)是处理日期时间的绝佳工具,比旧的Date/Calendar类靠谱多了,咱们用它来一步步解决你的问题~

一、先搞定:检测给定日期是否是当月第一个星期一

你之前踩坑的ChronoField.ALIGNED_WEEK_OF_MONTH确实容易搞混——它是按当月第一天所在的“对齐周”来计数的,不是按“第几个出现的星期几”算的,难怪会出问题!咱们换个更直观的方式,用TemporalAdjusters工具类来实现:

核心思路

  1. 把输入的日期字符串转成LocalDate对象(这是java.time里表示本地日期的核心类)
  2. 获取该日期对应的星期几(比如DayOfWeek.MONDAY)
  3. 调用TemporalAdjusters.firstInMonth()获取当月第一个该星期几的日期
  4. 对比原日期和这个日期,相等就说明是当月第一个目标星期几

代码示例

import java.time.LocalDate;
import java.time.DayOfWeek;
import java.time.temporal.TemporalAdjusters;

public class FirstDayChecker {
    public static boolean isFirstOccurrenceInMonth(LocalDate date) {
        DayOfWeek targetDay = date.getDayOfWeek();
        // 获取当月第一个目标星期几
        LocalDate firstInMonth = date.with(TemporalAdjusters.firstInMonth(targetDay));
        return date.equals(firstInMonth);
    }

    public static void main(String[] args) {
        LocalDate testDate = LocalDate.parse("2018-03-05");
        boolean isFirstMonday = isFirstOccurrenceInMonth(testDate);
        System.out.println(isFirstMonday); // 输出true,2018-03-05确实是3月第一个周一
    }
}

二、再解决:计算后续6个月的当月第N个相同星期几

确认原日期是当月第一个星期一后,咱们要生成接下来6个月里,每个月的第一个星期一(也就是和原日期同“第N个星期几”的日期)。这里用TemporalAdjusters.dayOfWeekInMonth()方法直接获取指定月份的第N个目标星期几,非常省心。

核心思路

  1. 确定目标星期几(比如原日期的DayOfWeek.MONDAY)和对应的N值(这里是1,因为是第一个)
  2. 循环6次,每次把当前日期往后推1个月
  3. 对每个新月份,调用dayOfWeekInMonth(nth, targetDay)获取目标日期,存入结果列表

完整代码示例

import java.time.LocalDate;
import java.time.DayOfWeek;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;

public class SubsequentDatesCalculator {
    public static void main(String[] args) {
        LocalDate startDate = LocalDate.parse("2018-03-05");
        
        // 先验证原日期是否是当月第一个星期一
        DayOfWeek targetDay = startDate.getDayOfWeek();
        LocalDate firstInMonth = startDate.with(TemporalAdjusters.firstInMonth(targetDay));
        if (!startDate.equals(firstInMonth)) {
            System.out.println("输入日期不是当月第一个" + targetDay.getDisplayName(java.time.format.TextStyle.FULL, java.util.Locale.CHINESE));
            return;
        }
        int nth = 1; // 这里因为是第一个,所以N=1;如果是其他第N个,可通过计算得到
        
        // 生成后续6个月的目标日期
        List<LocalDate> resultDates = new ArrayList<>();
        LocalDate currentMonthDate = startDate;
        for (int i = 0; i < 6; i++) {
            // 往后推1个月
            currentMonthDate = currentMonthDate.plusMonths(1);
            // 获取当月第N个目标星期几
            LocalDate targetDate = currentMonthDate.with(TemporalAdjusters.dayOfWeekInMonth(nth, targetDay));
            resultDates.add(targetDate);
        }
        
        // 打印结果,和你预期的完全一致!
        System.out.println(resultDates);
        // 输出:[2018-04-02, 2018-05-07, 2018-06-04, 2018-07-02, 2018-08-06, 2018-09-03]
    }
}

补充:如果是第N个星期几(非第一个)怎么算?

如果原日期是当月第2个、第3个星期几,计算N值的方式也很简单:

// 计算原日期是当月第几个目标星期几
int nth = (startDate.getDayOfMonth() - firstInMonth.getDayOfMonth()) / 7 + 1;

比如原日期是3月12号(第二个周一),(12-5)/7 +1 = 1+1=2,就能得到N=2,再用dayOfWeekInMonth(2, DayOfWeek.MONDAY)就能获取每个月的第二个周一啦。

内容的提问来源于stack exchange,提问作者Basil Bourque

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:18:03