Reputation: 197
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
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
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 printf
s 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