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

C++实现获取任意月份指定最后星期几 无第三方依赖实现咨询

问题描述

我正在开发代码用于解析cron格式,梳理完各类语法后,卡在了'L'操作符上,特别是'3L'语法,其作用是获取当月的最后一个星期三(例如2021年9月的最后一个星期三为29日),数字对应的星期规则如下:

0 = Sunday
1 = Monday
.
.
6 = Saturday

我在网上搜索后未找到可用的解决方案,且不想使用任何第三方库。我找到了一段可以计算每个月最后一个周五的代码,希望对其进行修改,使其可以获取任意月份我指定的最后一个星期几。

补充代码

#include <iostream>
using namespace std;

class lastFriday
{
    int lastDay[12];  //存储所有月份的最后一天
    int year; //存储输入的年份
    string m[12];  //存储12个月份的名称
    bool isleap;  //标记输入年份是否为闰年
 private:
    //判断闰年的函数
    void isleapyear()
    {
        if ((year % 4))
        {
            if (year % 100)
                isleap = true;
            else if ((year % 400))
                isleap = true;
        }
    }

    //输出每个月最后一个周五的日期
    void display()
    {
        for (int x = 0; x < 12; x++)
            cout << m[x] << lastDay[x] << endl;
    }

    //计算指定月日对应的星期
    int getWeekDay(int m, int d)
    {
        int y = year;

        int f = y + d + 3 * m - 1;
        m++;
        if (m < 3)
            y--;
        else
            f -= int(.4 * m + 2.3);

        f += int(y / 4) - int((y / 100 + 7) * 0.75);
        f %= 7;

        return f;
    }
 public:
    //初始化12个月份的名称
    lastFriday()
    {
        m[0] = "JANUARY:   "; m[1] = "FEBRUARY:  "; m[2] = "MARCH:     "; m[3] = "APRIL:     ";
        m[4] = "MAY:       "; m[5] = "JUNE:      "; m[6] = "JULY:      "; m[7] = "AUGUST:    ";
        m[8] = "SEPTEMBER: "; m[9] = "OCTOBER:   "; m[10] = "NOVEMBER:  "; m[11] = "DECEMBER:  ";
    }

    //计算每个月最后一个周五的核心函数
    void findLastFriday(int y)
    {
        year = y;

        //判断年份是否为闰年
        isleapyear();

        //闰年2月有29天,平年28天,初始化每个月的天数
        int days[] = { 31, isleap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int d;

        //遍历12个月计算最后一个周五的日期
        for (int i = 0; i < 12; i++)
        {
            d = days[i];
            //从当月最后一天开始倒推,直到找到周五
            while (true)
            {
                if (!getWeekDay(i, d))
                    break;
                d--;
            }
            lastDay[i] = d;
        }

        //输出结果
        display();
    }
};

int main()
{
    int year;  //存储用户输入的年份
    lastFriday LF;

    cout << "Enter the year in the range 1970 to 2037 : ";
    cin >> year;

    //校验年份范围
    if (year>2037|year<1970)
    {
        cout << "Not available for this year";
    }
    else
    {
        LF.findLastFriday(year);
    }

    return 0;
}
代码逻辑解释

整体流程

这段代码是面向对象实现的日期计算工具,输入1970-2037范围内的年份,会输出该年份每个月最后一个周五的具体日期。

模块拆分

  1. 闰年判断isleapyear():核心作用是确定2月的天数,不过原代码的闰年判断逻辑是错误的,正确规则应为:能被4整除但不能被100整除,或能被400整除的年份是闰年,原代码的判断条件写反了,修改时需要先修正这个问题。
  2. 星期计算getWeekDay(int m, int d):基于改进版泽勒公式实现,输入0-11对应的月份、当月日期,返回值0-6对应星期,注意原代码的返回值映射为0是周五,和你给出的0=周日的规则不一致,修改时需要调整对齐。
  3. 核心计算findLastFriday(int y):先初始化全年每个月的天数,之后遍历每个月,从当月最后一天开始向前逐天校验星期,直到找到符合要求的周五,记录日期后进入下一个月的计算。
  4. 输出与主函数:主函数负责接收用户输入的年份并做范围校验,校验通过后触发计算逻辑,最终打印每个月的计算结果。
修改适配方案

你只需要做以下调整就能实现获取任意指定星期的最后一个日期:

  1. 先修正闰年判断的逻辑错误
  2. 调整getWeekDay的返回值,使其和你给出的0=周日、6=周六的规则对齐
  3. 给findLastFriday方法新增一个targetWeek入参,把循环中的if (!getWeekDay(i, d))判断条件改为if (getWeekDay(i, d) == targetWeek)即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 02:21:00