Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 1 of 1
  1. #1
    Regular Coder Krupski's Avatar
    Join Date
    Dec 2010
    Location
    United States of America
    Posts
    505
    Thanks
    39
    Thanked 47 Times in 46 Posts

    Zeller's Congruence

    Hi all,

    If you need it... Zeller's Congruence is an algorithm that will calculate the day of the week, given any day, month and year. Want to know what day you were born? Want to know what day December 25, 0000 was? Zeller will tell you!

    Here's the bare algorithm in Javascript:

    Code:
    /***
    * h = calculated day
    * q = day (q for day??? don't ask me... ask Dr. Zeller....)
    * m = month
    * y = year
    * note: calculations must be in integers - do not use floats or it will fail.
    *
    *      /    |(m+1)*26|       | y |       | y |   | y |    \
    * h = | q + |--------| + y + |---| + 6 * |---| + |---| - 1 | mod 7
    *      \    |   10   |       | 4 |       |100|   |400|    /
    *
    ***/
    function zeller(month, day, year) /* returns 0-6 where 0=sunday, 1=monday, etc....*/
    {
        if (month < 3) { month += 12; year -= 1; }
        var h = (day + parseInt(((month + 1) * 26) / 10) + year + parseInt(year / 4) + 6 * parseInt(year / 100) + parseInt(year / 400) - 1) % 7;
        return h;
    }
    Here's the same thing, in a ready to run self contained HTML document so you can test and play with it (note: The demo does NOT check for valid day, month and year input. Illegal dates return meaningless data):

    Code:
    <html>
    <head>
    <title>Zeller's Congruence</title>
    <script type="text/javascript">
    
    /***
    *
    *      /    |(m+1)*26|       | y |       | y |   | y |    \
    * h = | q + |--------| + y + |---| + 6 * |---| + |---| - 1 | mod 7
    *      \    |   10   |       | 4 |       |100|   |400|    /
    *
    ***/
    function zeller(month, day, year) /* returns 0-6 where 0=sunday, 1=monday, etc....*/
    {
        if (month < 3) { month += 12; year -= 1; }
        var h = (day + parseInt(((month + 1) * 26) / 10) + year + parseInt(year / 4) + 6 * parseInt(year / 100) + parseInt(year / 400) - 1) % 7;
        return h;
    }
    
    
    function demo(month, day, year)
    {
        var mons = ['January','February','March','April','May','June','July','August','September','October','November','December'];
        var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
        return mons[month-1] + ' ' + day + ', ' + year + ' = ' + days[zeller(month, day, year)];
    }
    
    </script>
    </head>
    <body style="font-size:14px;background:#bbddff;">
    
    <div style="padding:10.0em;">
    <p>Zeller's Congruence Demo</p>
    <p><textarea style="font-family:sans-serif;width:5em;height:1.5em;" id="month"></textarea>&nbsp;Enter the Month</p>
    <p><textarea style="font-family:sans-serif;width:5em;height:1.5em;" id="day"></textarea>&nbsp;Enter the Day</p>
    <p><textarea style="font-family:sans-serif;width:5em;height:1.5em;" id="year"></textarea>&nbsp;Enter the Year</p>
    <p><input type="button" value="Submit" onclick="doDemo();" /></p>
    <p id="result">----------</p>
    </div>
    
    <script type="text/javascript">
    function doDemo()
    {
        var m = parseInt(document.getElementById('month').value);
        var d = parseInt(document.getElementById('day').value);
        var y = parseInt(document.getElementById('year').value);
        document.getElementById('result').innerHTML = demo(m,d,y);
    }
    </script>
    </body>
    </html>
    Here's the program in C - with some basic input range checking and a cute "tense" function (today was / is / will be):

    Code:
    // zeller.c - zeller's congruence
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <time.h>
    
    #undef BUFSIZ
    #define BUFSIZ 1024
    
    int getnum(FILE *);
    
    int main(void)
    {
        const char *day_name[7] = {
            "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
        };
    
        const char *month_name[12] = {
            "January", "February", "March", "April", "May", "June", "July",
            "August", "September", "October", "November", "December"
        };
    
        time_t now;
        struct tm *ts;
        char buf[BUFSIZ];
        char tense[BUFSIZ];
    
        int count;
        int month = -1, day = -1, year = -1;
        int curmonth, curday, curyear;
    
        long int today, anyday;
    
        time(&now);
        ts = localtime(&now);
    
        strftime(buf, sizeof(buf), "%m", ts);
        curmonth = atoi(buf);
    
        strftime(buf, sizeof(buf), "%d", ts);
        curday = atoi(buf);
    
        strftime(buf, sizeof(buf), "%Y", ts);
        curyear = atoi(buf);
    
        today = (curyear * 365) + (curmonth * 12) + curday;
    
        fprintf(stdout, "\n");
    
        count = 3;
        while ((month < 1 || month > 12) && (count--)) {
            fprintf(stdout, "Enter the month: ");
            month = getnum(stdin);
            if (!count) { return 1; }
        }
    
        count = 3;
        while ((day < 1 || day > 31) && (count--)) {
            fprintf(stdout, "Enter the day  : ");
            day = getnum(stdin);
            if (!count) { return 1; }
        }
    
        count = 3;
        while ((year < 0) && (count--)) {
            fprintf(stdout, "Enter the year : ");
            year = getnum(stdin);
            if (!count) { return 1; }
        }
    
        anyday = (year * 365) + (month * 12) + day;
    
        if (today > anyday) { strcpy(tense, "was"); }
        if (today == anyday) { strcpy(tense, "is"); }
        if (today < anyday) { strcpy(tense, "will be"); }
    
        if (month < 3) { month += 12; year -= 1; }
    
        int dow =
            (((day + (((month + 1) * 26) / 10) + year + (year / 4) +
               (6 * (year / 100)) + (year / 400)) - 1) % 7);
    
        if (month > 12) { month -= 12; year += 1; }
    
        month -= 1;        // make index zero based
    
        fprintf(stdout, "\n%s %d, %04d %s a %s\n\n", month_name[month], day, year, tense, day_name[dow]);
    
        return 0;
    }
    
    int getnum(FILE * fp)
    {
        char buf[BUFSIZ];
        int len;
        double dnum;
    
        buf[0] = 0;
        fgets(buf, BUFSIZ, fp);
    
        len = strlen(buf);
    
        while (len >= 0) {
            if (buf[len] <= 32) { buf[len] = 0; len--; }
            else { break; }
        }
    
        len++; buf[len] = 0;
        dnum = atof(buf);
        return (int)((dnum < 0) ? (dnum - 0.5) : (dnum + 0.5));
    
    }
    Finally, to read up on Zeller's Congruence, check this LINK

    Hope someone can use it.
    Last edited by Krupski; 01-16-2011 at 06:53 AM.
    "Anything that is complex is not useful and anything that is useful is simple. This has been my whole life's motto." -- Mikhail T. Kalashnikov


 

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •