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范围内的年份,会输出该年份每个月最后一个周五的具体日期。
模块拆分
- 闰年判断
isleapyear():核心作用是确定2月的天数,不过原代码的闰年判断逻辑是错误的,正确规则应为:能被4整除但不能被100整除,或能被400整除的年份是闰年,原代码的判断条件写反了,修改时需要先修正这个问题。 - 星期计算
getWeekDay(int m, int d):基于改进版泽勒公式实现,输入0-11对应的月份、当月日期,返回值0-6对应星期,注意原代码的返回值映射为0是周五,和你给出的0=周日的规则不一致,修改时需要调整对齐。 - 核心计算
findLastFriday(int y):先初始化全年每个月的天数,之后遍历每个月,从当月最后一天开始向前逐天校验星期,直到找到符合要求的周五,记录日期后进入下一个月的计算。 - 输出与主函数:主函数负责接收用户输入的年份并做范围校验,校验通过后触发计算逻辑,最终打印每个月的计算结果。
修改适配方案
你只需要做以下调整就能实现获取任意指定星期的最后一个日期:
- 先修正闰年判断的逻辑错误
- 调整
getWeekDay的返回值,使其和你给出的0=周日、6=周六的规则对齐 - 给
findLastFriday方法新增一个targetWeek入参,把循环中的if (!getWeekDay(i, d))判断条件改为if (getWeekDay(i, d) == targetWeek)即可
内容的提问来源于stack exchange,提问作者FaruK
相关产品推荐
相关产品推荐

