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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 02:36:05