How to add N weeks to a given date in C

1 Answer

0 votes
#include <stdio.h>
#include <time.h>

/**
 * Adds a specified number of weeks to a given struct tm date.
 * 
 * @param date  Pointer to struct tm representing the base date.
 * @param weeks Number of weeks to add (can also be negative to subtract).
 * @return      0 on success, -1 on failure (mktime error).
 */
int add_weeks_to_date(struct tm *date, int weeks) {
    if (date == NULL) {
        return -1;
    }

    // 1. Add the equivalent number of days (weeks * 7) to the day of the month.
    // mktime() will handle overflow automatically (e.g., day 35 of a month).
    date->tm_mday += weeks * 7;

    // 2. Set tm_isdst to 0 to prevent Daylight Saving Time (DST) shifts 
    // from altering the calendar date during normalization.
    date->tm_isdst = 0;

    // 3. mktime normalizes the struct tm fields (recalculating year, month, 
    // day of week, and day of year) and converts it back to a time_t.
    time_t normalized_time = mktime(date);
    if (normalized_time == (time_t)(-1)) {
        return -1; // Error during normalization
    }

    return 0;
}

int main(void) {
    // Initialize a sample date: November 8, 2026
    struct tm target_date = {0};
    target_date.tm_year = 2026 - 1900; // Years since 1900
    target_date.tm_mon  = 10;          // Month (0-11, so 10 = November)
    target_date.tm_mday = 8;           // Day of the month (1-31)
    target_date.tm_hour = 12;          // Noon, safely away from midnight DST shifts

    int weeks_to_add = 4;

    printf("Original date: %04d-%02d-%02d\n", 
           target_date.tm_year + 1900, 
           target_date.tm_mon + 1, 
           target_date.tm_mday);

    if (add_weeks_to_date(&target_date, weeks_to_add) == 0) {
        printf("After adding %d weeks: %04d-%02d-%02d\n", 
               weeks_to_add,
               target_date.tm_year + 1900, 
               target_date.tm_mon + 1, 
               target_date.tm_mday);
    } else {
        fprintf(stderr, "Failed to compute new date.\n");
    }

    return 0;
}


/*
run:

Original date: 2026-11-08
After adding 4 weeks: 2026-12-06

*/

 



answered 21 hours ago by avibootz
...