Tuan Nguyen
Tuan Nguyen

Reputation: 197

Program for Date calculator in C

I'm trying to write a date calculator in C program with the range from 1/1/1902 to 12/31/2299, I've follow the algorithm from http://en.wikipedia.org/wiki/Calculating_the_day_of_the_week with the century table,month table and day table, but when I tried to print out, this is what I have

Enter Year, Month and Day as YYYY,M,DD
1982 4 24
Saturday1982 ,6, 24, is  6

Instead of saying 1982 4 24 is a Saturday

What is wrong in the program I wrote? The placement of the switch cases?

#include <stdio.h>

int main (void)
{
    // insert code here...
    int day,month,year;

    printf("Enter Year, Month and Day as YYYY,M,DD\n");

    scanf("%4d%d%2d", &year, &month, &day);

    if (year >= 1901 && year <= 2299 &&
        month >= 1 && month <= 12 &&
        day >= 0 && day <= 31)
    {
        int century = year/100;

        /* making a century table for calculation*/

        switch(century)
        {
            case 19:
                century=0;
                break;
            case 20:
                century=6;
                break;
            case 21:
                century=4;
                break;
            case 22:
                century=2;
                break;
        }

        int last2_of_year= year % 100;

        /* Last 2 digits of the year entered*/

        int last2_div_4 =  last2_of_year/4;

        switch (month)
        {
            case 1:
                month=0;
                break;

            case 2:
                month=3;
                break;
            case 3:
                month=3;
                break;
            case 4:
                month=6;
                break;
            case 5:
                month=1;
                break;
            case 6:
                month=4;
                break;
            case 7:
                month=6;
                break;
            case 8:
                month=2;
                break;
            case 9:
                month=5;
                break;
            case 10:
                month=0;
                break;
            case 11:
                month=3;
                break;
            case 12:
                month=5;
                break;
         }


        int total_num = (century+ last2_of_year +day +month +last2_div_4)%7;

        switch (total_num) 
        {
            case 0:
            printf("Sunday");
                break;
            case 1:
            printf("Monday");
                break;
            case 2:
            printf("Tuesday");
                break;
            case 3:
            printf("Wednesday");
                break;
            case 4:
            printf("Thursday");
                break;
            case 5:
            printf("Friday");
                break;
            case 6:
            printf("Saturday");
                break;
        }

        printf("%d ,%d, %d, is a %d", year,month,day,total_num);
        }
        else
        {
            printf("invalid\n");
        }



    return 0;

    }

Upvotes: 1

Views: 10270

Answers (2)

sarnold
sarnold

Reputation: 104040

Looks like @QuantumMechanic found the root cause of the problem, but I'd like to suggest a few changes:

    int century = year/100;

    /* making a century table for calculation*/

    switch(century)
    {
        case 19:
            century=0;
            break;

I'm very leery of using a single variable to represent two different things. Here, century represents both the user-input human-readable century and an offset to the first day of the week for the century. Two variables would give clearer code, and allow you to re-use the century information later, should the need arise.

Second, using a case statement to store offsets for the months feels a little ... overdone:

    switch (month)
    {
        case 1:
            month=0;
            break;

        case 2:
            month=3;
            break;
        case 3:
            month=3;
            break;

This could instead be handled with an array lookup:

int leap_month[] = [-1, 6, 2, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5];
int norm_month[] = [-1, 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5];

if (leap_year)
    month_offset = leap_month[month];
else
    month_offset = norm_month[month];

The -1 is just to allow referring to the table with human-friendly indexes (Jan == 1). Feel free to remove it and use leap_month[month-1] or similar if you find that easier.

Upvotes: 1

QuantumMechanic
QuantumMechanic

Reputation: 13946

You say:

printf("%d ,%d, %d, is a %d", year,month,day,total_num);

That's going to print

L, M, N, is a P

where L, M, N, and P are numbers.

You need that printf() before the name-of-days switch and need to remove the final %d and the total_num from the printf. Then that printf will print

L, M, N, is a

and the printfs in the name-of-days switch will print out the name of the day on the same line, giving you

L, M, N, is a XXXXXXXXXXX

Edited to address comment:

Look at your program for output statements.

The first output statement encountered are the printf calls in the name-of-days switch that prints out the day names. So when your program runs given the input you mention, the first thing that will be printed out is

Saturday

Then after the name-of-days switch the next printf is

printf("%d ,%d, %d, is a %d", year,month,day,total_num);

Since year is 1982, month is 4, day is 24, and total_num is 6, that printf will output

1982, 4, 24, is a 6

on the same line as the previous Saturday output, which means the entire output is

Saturday1982, 4, 24, is a 6

Upvotes: 2

Related Questions