Krupski
01-16-2011, 06:43 AM
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! :D
Here's the bare algorithm in Javascript:
/***
* 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):
<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> Enter the Month</p>
<p><textarea style="font-family:sans-serif;width:5em;height:1.5em;" id="day"></textarea> Enter the Day</p>
<p><textarea style="font-family:sans-serif;width:5em;height:1.5em;" id="year"></textarea> 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):
// 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;
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 [B]LINK (http://en.wikipedia.org/wiki/Zeller%27s_congruence)
Hope someone can use it.
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! :D
Here's the bare algorithm in Javascript:
/***
* 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):
<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> Enter the Month</p>
<p><textarea style="font-family:sans-serif;width:5em;height:1.5em;" id="day"></textarea> Enter the Day</p>
<p><textarea style="font-family:sans-serif;width:5em;height:1.5em;" id="year"></textarea> 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):
// 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;
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 [B]LINK (http://en.wikipedia.org/wiki/Zeller%27s_congruence)
Hope someone can use it.