user3304499
user3304499

Reputation: 25

My C program that uses Zeller's algorithm is very buggy on leap years, not sure why?

The program is supposed to return what day of the week it is for the entered date. One of the dates that doesn't work is 01012000. Nothing is returned at all. But on some other leap years the first day of March can be calculated. Also sometimes seemingly random dates don't work. I'm not sure how to fix this. Also I'm supposed to write the part that calculates "daynumber" and then call on it later so I'm not sure if I'm doing that right.

Sorry for the beginner questions, this is my first ever C program.

#include<stdio.h>
#include<math.h>
int main()
{
int day, month, year, lastday, dayname, daynumber, input, d;

//Determine the last day of user specified month

printf("Enter date: ddmmyyyy:\n");
scanf("%d", &input);

day = input/1000000;
month = (input/10000) % 100;
year = input % 10000;

if (month == 1 || month == 3 || month == 5 || month == 7 || 
    month == 8 || month == 10 || month == 12)
    lastday = 31;
else if (month == 4 || month == 6 || month == 9 || month == 11)
    lastday = 30;
else if ((year%4 == 0 && year%100 !=0) || year%400 == 0)
    lastday = 29;
else
    lastday = 28;

//Verify the date

if (year < 0)
    return 1;
if (month < 1 || month > 12)
    return 2;
if (day < 1 || day > lastday)
    return 3;

//Algorithm

{

int m, d, y, c, daynumber;

if (month > 3)
    m = month - 2;
else
    m = month + 10;

if (m == 11 || m == 12)
    year = year - 1;
else
    year = year;

d = day;
y = year % 100;
c = year / 100;

daynumber = (((13*m - 1)/5) + d + y + (y/4) + (c/4) - 2*c) % 7;

if (daynumber == 0)
    printf("Sunday\n");
if (daynumber == 1)
    printf("Monday\n");
if (daynumber == 2)
    printf("Tuesday\n");
if (daynumber == 3)
    printf("Wednesday\n");
if (daynumber == 4)
    printf("Thursday\n");
if (daynumber == 5)
    printf("Friday\n");
if (daynumber == 6)
    printf("Saturday\n");

}

}

Upvotes: 2

Views: 1059

Answers (3)

Henrik
Henrik

Reputation: 23324

This

(((13*m - 1)/5) + d + y + (y/4) + (c/4) - 2*c)

can probably be negative. The result of % 7 would then still be negative and nothing is printed.

Just add daynumber = (daynumber + 7) % 7; after the line

daynumber = (((13*m - 1)/5) + d + y + (y/4) + (c/4) - 2*c) % 7;

Upvotes: 1

David Ranieri
David Ranieri

Reputation: 41046

I can't see your bug, but there is no need to scan the whole number and divide, use:

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

Using Sakamoto's algorithm you can do the same in few lines:

#include <stdio.h>

static int wday(int d, int m, int y)
{
    static int offset[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};

    y -= m < 3;
    return (y + y / 4 - y / 100 + y / 400 + offset[m - 1] + d) % 7;
}

int main(void)
{
    const char *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
    int d, m, y;

    printf("Enter date [ddmmyyyy]: ");
    scanf("%2d%2d%4d", &d, &m, &y);
    printf("%s\n", days[wday(d, m, y)]);
    return 0;
}

Upvotes: 1

Rahul
Rahul

Reputation: 3519

You are using:

 printf("Enter date: ddmmyyyy:\n");
 scanf("%d", &input);

Here you are storing the input as a int. If sizeof(int) is 2 byte, its range would be between -32,768 to 32,767 and your input would be out of the range. For this you should use long int.

Upvotes: 0

Related Questions