C语言如何仅通过年份和周数获取对应周内的所有日期?
C语言实现按年、周获取对应7天日期数组的方案
实现逻辑
- 依赖标准库
time.h完成日期计算,采用国际通用的ISO周规则(周一为一周起始,每年首周为包含1月4日的周),和你给出的示例逻辑完全匹配 - 核心流程:定位指定周的周一日期 -> 循环生成连续7天的
DD/MM格式字符串 -> 拼装为字符串数组返回 - 增加了非法输入校验、内存分配失败处理逻辑,避免崩溃和内存泄漏
完整可运行代码
#include <stdio.h> #include <stdlib.h> #include <time.h> char** get_dates_from_year_and_week(int year, int week) { // 周数合法范围校验,ISO周一年最多53周 if (week < 1 || week > 53) return NULL; // 分配7个字符串指针的数组空间 char** dates = (char**)malloc(sizeof(char*) * 7); if (!dates) return NULL; // 初始化目标年份1月1日的时间结构体 struct tm tm_start = {0}; tm_start.tm_year = year - 1900; // time.h的tm_year为1900年起的偏移值 tm_start.tm_mon = 0; // 月份从0开始计数,0对应1月 tm_start.tm_mday = 1; tm_start.tm_isdst = -1; // 自动适配夏令时规则 // 转换为时间戳 time_t time_start = mktime(&tm_start); if (time_start == -1) { free(dates); return NULL; } // 计算1月1日的星期偏移,适配ISO周规则(周一为周首日) // tm_wday取值0=周日,1=周一...6=周六,转换为ISO规则:1=周一,7=周日 int wday = tm_start.tm_wday; int iso_wday = wday == 0 ? 7 : wday; // 计算当年第一个ISO周周一的时间戳 time_t first_monday; if (iso_wday <= 4) { // 1月1日属于当年第一周,直接偏移到当周周一 first_monday = time_start + (1 - iso_wday) * 86400; } else { // 1月1日属于上一年最后一周,偏移到下一周周一 first_monday = time_start + (8 - iso_wday) * 86400; } // 计算目标周周一的时间戳 time_t target_monday = first_monday + (week - 1) * 7 * 86400; // 校验目标周是否属于输入的年份,避免输入周数超过当年最大周数 struct tm* check_tm = localtime(&target_monday); if (check_tm->tm_year + 1900 != year) { free(dates); return NULL; } // 循环生成7天的日期字符串 for (int i = 0; i < 7; i++) { time_t cur_time = target_monday + i * 86400; struct tm* cur_tm = localtime(&cur_time); // 每个日期字符串分配6字节:"DD/MM"占5字符 + 结束符'\0'占1字节 dates[i] = (char*)malloc(6 * sizeof(char)); if (!dates[i]) { // 分配失败释放已申请的内存,避免泄漏 for (int j = 0; j < i; j++) { free(dates[j]); } free(dates); return NULL; } // 格式化日期,自动补前导零 strftime(dates[i], 6, "%d/%m", cur_tm); } return dates; } // 测试用例 int main() { char** res = get_dates_from_year_and_week(2021, 45); if (res) { printf("2021年第45周日期:\n"); for (int i = 0; i < 7; i++) { printf("%s\n", res[i]); free(res[i]); // 使用完释放单个字符串内存 } free(res); // 释放外层数组内存 } return 0; }
运行输出
2021年第45周日期: 08/11 09/11 10/11 11/11 12/11 13/11 14/11
和你给出的示例完全一致。
注意事项
- 内存释放必须按顺序执行:先遍历释放每个日期字符串,再释放外层的字符串数组,否则会出现内存泄漏
- 如果需要适配周日为周首日的规则,只需要调整星期偏移的计算逻辑即可
- 代码默认使用系统本地时区,如需UTC时间,把所有
localtime调用替换为gmtime即可
内容的提问来源于stack exchange,提问作者pluto9800
相关产品推荐
相关产品推荐

