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

如何在纯C语言中根据年份和ISO周数计算对应日期

Pure C Standard Library Implementation for ISO Week to Date Conversion

Got it, here's a robust, pure C solution that uses only the standard C library (<time.h> and <stdbool.h>) to convert an ISO year and week number to the corresponding calendar date—fully handling edge cases where the ISO week falls in the previous or next calendar year.

Key ISO Week Rules Recap

  • ISO weeks start on Monday and end on Sunday.
  • ISO Week 1 is the first week of the ISO year that contains at least 4 days of the calendar year (equivalent to the week containing January 4th of the ISO year).
  • The ISO year may differ from the calendar year: e.g., ISO 2019 Week 1 starts on December 31, 2018 (calendar year 2018, but ISO year 2019).

Implementation Code

#include <time.h>
#include <stdbool.h>

/**
 * Converts an ISO year and week number to the corresponding calendar date (Monday of the target week).
 * @param iso_year The ISO year (e.g., 2019)
 * @param iso_week The ISO week number (1-53)
 * @param day Output: day of the month (1-31)
 * @param month Output: month (1-12)
 * @param year Output: actual calendar year (may differ from iso_year)
 * @return true on success, false on invalid input or conversion error
 */
bool iso_week_to_date(int iso_year, int iso_week, int *day, int *month, int *year) {
    // Validate input week range
    if (iso_week < 1 || iso_week > 53) {
        return false;
    }

    // Initialize tm structure for January 4th of the ISO year
    struct tm tm_date = {0};
    tm_date.tm_year = iso_year - 1900;  // tm_year counts years since 1900
    tm_date.tm_mon = 0;                 // 0 corresponds to January
    tm_date.tm_mday = 4;
    tm_date.tm_isdst = -1;              // Let system auto-detect daylight saving time

    // Convert to time_t to resolve the full date structure
    time_t time_val = mktime(&tm_date);
    if (time_val == (time_t)-1) {
        return false;
    }

    // Convert tm_wday (0=Sunday, 1=Monday, ...6=Saturday) to ISO weekday (1=Monday, ...7=Sunday)
    int iso_weekday = (tm_date.tm_wday == 0) ? 7 : tm_date.tm_wday;

    // Calculate days to subtract from Jan 4th to get to the Monday of ISO Week 1
    int days_to_monday = 5 - iso_weekday;  // Simplified from 4 - (iso_weekday - 1)
    tm_date.tm_mday += days_to_monday;

    // Re-resolve the date after adjusting to ISO Week 1 Monday (handles year/month rollover)
    time_val = mktime(&tm_date);
    if (time_val == (time_t)-1) {
        return false;
    }

    // Add (week_num -1) weeks to reach the target week's Monday
    tm_date.tm_mday += (iso_week - 1) * 7;
    time_val = mktime(&tm_date);
    if (time_val == (time_t)-1) {
        return false;
    }

    // Extract human-readable date values
    *day = tm_date.tm_mday;
    *month = tm_date.tm_mon + 1;  // Convert from 0-based to 1-based month
    *year = tm_date.tm_year + 1900;

    return true;
}

// Example usage
#include <stdio.h>

int main() {
    int day, month, year;
    if (iso_week_to_date(2019, 1, &day, &month, &year)) {
        printf("ISO 2019 Week 1 starts on: %04d-%02d-%02d\n", year, month, day);
        // Output: 2018-12-31
    }

    if (iso_week_to_date(2020, 53, &day, &month, &year)) {
        printf("ISO 2020 Week 53 starts on: %04d-%02d-%02d\n", year, month, day);
        // Output: 2020-12-28
    }

    if (iso_week_to_date(2021, 1, &day, &month, &year)) {
        printf("ISO 2021 Week 1 starts on: %04d-%02d-%02d\n", year, month, day);
        // Output: 2021-01-04
    }

    return 0;
}

How It Works

  1. Input Validation: Checks if the ISO week number falls within the valid range (1-53).
  2. January 4th Anchor: Uses January 4th of the ISO year as a fixed point—this date is guaranteed to be part of ISO Week 1 per ISO standards.
  3. Adjust to ISO Week 1 Monday: Converts the anchor date's weekday to ISO format, then calculates how many days to subtract to reach the Monday of ISO Week 1. The mktime function automatically handles month/year rollovers (e.g., shifting to December of the previous year).
  4. Calculate Target Week: Adds (iso_week -1) *7 days to the ISO Week 1 Monday to get the Monday of the target week. mktime again handles any necessary date adjustments.
  5. Extract Date Values: Converts the struct tm fields (which use 0-based months and years since 1900) to human-readable 1-based months and full calendar years.

Notes

  • The function returns the Monday of the target ISO week. To get other days in the week, simply add 0-6 days to the tm_mday field before the final mktime call (e.g., add 3 for Thursday).
  • tm_isdst = -1 ensures the system correctly handles daylight saving time adjustments for your local timezone. For UTC-only calculations, you can modify the logic to use gmtime instead of relying on mktime's local timezone handling.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:14:25