user199707
user199707

Reputation: 15

Creating a C program that determines week day of 1st date of given month in 2021

I've seen many questions similar to mine but haven't found anything that helps. I want to determine the day of the week of 1st given month. example: week day of March 01, 2021 or August 01, 2021. Only the month is asked from the user and it is given that Jan 01, 2021 is a Friday. This is my code so far:

#include <stdio.h>

char* MonthName(int m){

    switch(m){
        case 1: 
            return "January";
        case 2: 
            return "February";
        case 3: 
            return "March";
        case 4: 
            return "April";
        case 5: 
            return "May";
        case 6: 
            return "June";
        case 7: 
            return "July";
        case 8: 
            return "August";
        case 9: 
            return "September";
        case 10: 
            return "October";
        case 11: 
            return "November";
        case 12: 
            return "December";
        default:
            return 0;
    }
}

int MonthDays(int m){
    switch(m){
        case 1: 
            return (31);
        case 2: 
            return (28);
        case 3: 
            return (31);
        case 4: 
            return (30);
        case 5: 
            return (31);
        case 6: 
            return (30);
        case 7: 
            return (31);
        case 8: 
            return (31);
        case 9: 
            return (30);
        case 10: 
            return (31);
        case 11: 
            return (30);
        case 12: 
            return (31);
    }
}

char* WeekDay(){
    int m, d, x;
  
    x += 365;
    x += MonthDays(m);

    d = x%7;
    
    switch(d){
    //because the Jan 1 is a friday
    case 0:
        return "Friday";
    case 1:
        return "Saturday";
    case 2:
        return "Sunday";
    case 3:
        return "Monday";
    case 4:
        return "Tuesday";
    case 5:
        return "Wednesday";
    case 6:
        return "Thursday";
    
    }
}


int main(){
    int m; 
    char d;

    printf("Choose a month number from 1-12: ");
    scanf("%d", &m);

    printf("The day of %s 01, 2021 is %s\n", MonthName(m), WeekDay(d));
}

I know my codes are a little long and messy, but I'm new to C programming and I don't want anything advanced since there aren't really any errors anymore. I'm hoping not to have to modify any of the codes/switches, just the formula because I really can't figure out how to get the day of the week (see function WeekDay(), specifically the one with variables x and d). It prints a week day but it's not the correct week day. I want to incorporate the MonthDays function, as well and most of the other answers on questions similar to mine doesn't use the number of days in a month.

Any help/advice would be appreciated. Thank you!

Upvotes: 0

Views: 1039

Answers (2)

Zoso
Zoso

Reputation: 3465

Apart from the suggestions that the other answer has already provided, here's what is missing in your WeekDay() function.

You need to essentially sum up the days from the 1st of January and then % 7 to get at the answer.

So, first, changing your WeekDay()'s signature to

char* WeekDay(int m){

to actually accept the month number that is read in from the user.

Taking an example of 1st of February, that's 31 days since the start of January i.e. the number of days in the previous month. Extending this logic to the subsequent months, it boils down to simply adding up the number of days in all the previous months. So,

int d, x = 0;

for(int i = 2; i <= m; ++i) {
    x += MonthDays(i - 1);
}

d = x%7;

Note that x is initialized to 0. Coming to the for loop, it's as mentioned, summing over the days in the previous months. Note that the starting index of the loop is 2 to avoid adding any days for January (in case the value of passed in m was 1).

Coming to other functions, the MonthName() function doesn't return a value in case m doesn't match with any of the cases. Return some default value (return NULL or something). You could possibly simplify these cases by just having arrays as:

char* days[] = {"Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday"};

and similarly char* monthName[] = .... and int numDaysInMonth[] = .... and that would just leave you to sanitize the user input m at one single place and check if it's within the range 1-12 and then access the array accordingly. Remember to take care of the 0-indexed arrays, so int daysInJan = numDaysInMonth[0] and not numDaysInMonth[1].

EDIT: Here's the link to the complete working program. And I'm sharing the program here as per the things mentioned in the latter part of the answer. It might be a matter of convenience mostly at the end of the day but here it goes:

#include <stdio.h>

int validMonth(int m) {
    return m >= 1 && m <= 12;
}

char const* MonthName(int m){
    static char const* months[] = {
        NULL, /*For convenience,
         start with NULL for avoiding 0-indexing the months*/
        "January", "February", "March", "April", "May", "June", "July",
        "August", "Septemeber", "October", "Novemeber",  "December"
    };
    return months[m];
}

char const* WeekDay(int m){
    static char const* days[] = {
        /*Starting with the day for 1st January
         NOTE: Here 0 means same as Friday, so no need
         to add a dummy value at 0-index
        */
        "Friday", "Saturday", "Sunday", "Monday",
        "Tuesday", "Wednesday", "Thursday",
    };

    static const int numDaysinMonth[] = {
        /*For convenience start with -1 at the 0-index
        to avoid 0-indexing the months*/
        -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
    };
    
    int x = 0;
  
    for(int i = 2; i <= m; ++i) {
        x += numDaysinMonth[i - 1];
    }
    return days[x % 7];
}


int main(){
    int m; 
    do {
        printf("Choose a month number from 1-12: ");
        scanf("%d", &m);
        if(validMonth(m) != 1) {
            printf("%d doesn't map to any calendar month\n", m);
        } else {
            printf("The day of %s 01, 2021 is %s\n", MonthName(m), WeekDay(m));
        }
    } while (m != 12);
}

Upvotes: 1

MikeCAT
MikeCAT

Reputation: 75062

In your function WeekDay, arguments are ignored and some calculation is done with the uninitialized local variable (with indeterminate value) x, invoking undefined behavior.

Instead of this:

char* WeekDay(){
    int m, d, x;

It seems the x should be an argument like this:

char* WeekDay(int x){
    int m, d;

Also the d, which is passed to WeekDay from main, is not initialized. You should initialize that with proper value before passing, or the argument should be changed to some other proper thing.

Upvotes: 2

Related Questions