Search code examples
cmktime

Out of bounds on the wrong variable with mktime


I am trying to add a user input date to an existing time struct but I am getting an error I do not understand. The complier is telling me the weekday is out of bounds when I am trying to modify the month date. Code is posted below.

struct tm date;
int m, d, y, n;
char buffer[80];
printf("Enter a date in mm/dd/yyyy format.\n");
scanf("%d/%d/%d", &m, &d, &y);

date.tm_mday = d;
date.tm_mon = m;
date.tm_year = y - 1900;
mktime(&date);

printf("How many days would you like to advance this time?");
scanf("%d", &n);
date.tm_mday += n;
mktime(&date);
strftime(buffer, sizeof(buffer), "%c", &date);
printf("Your new date is %c", buffer);

Solution

  • Problems

    • .tm_mon expects the months since January 0-11.

      This usually means to subtract 1 from user's input. @dashboard

      // date.tm_mon = m;
      date.tm_mon = m - 1;
      

    • mktime(&date); reads all members aside from .tm_yday and .tm_wday and OP's only sets 3 of them. Best to initialize all members with {0} as we only known of 7 others and there might be more. @Jonathan Leffler

    • Code did not check the return value of mktime() for errors.

    • Use "%s" to print a string. This implies OP does not have a good compiler with warnings fully enable. Save time and enable all warnings with a good compiler.

      char buffer[80];
      printf("Your new date is %c", buffer);  // Bad specifier
      

    Put this all together.

    // struct tm date;
    struct tm date = {0}; // Initialize all
    int m, d, y, n;
    char buffer[80];
    
    printf("Enter a date in mm/dd/yyyy format.\n");
    if (scanf("%d/%d/%d", &m, &d, &y) != 3) {
      Handle_error();  
    }
    
    
    date.tm_mday = d;
    // date.tm_mon = m;
    date.tm_mon = m - 1;
    date.tm_year = y - 1900;
    date.tm_isdst = -1; // Set dst flag to: let mktime figure it out
    if (mktime(&date) == -1) {
      Handle_error();  
    }
    
    printf("How many days would you like to advance this time?");
    scanf("%d", &n);
    date.tm_mday += n;
    if (mktime(&date) == -1) {
      Handle_error();  
    }
    
    strftime(buffer, sizeof(buffer), "%c", &date);
    printf("Your new date is %s", buffer);