Converting a Month-Date-Year to the Day of the Week
I read this a long time ago in a book, and I've used it to amuse my friends
over the years, even raced one to come up with the answers first. It's
basically a parlor trick that is completely useless, since it's hard to
verify without a perpetual calendar (though such things are easily
obtainable).
General algorithm
- Pick a base year and find out (with a perpetual calendar, probably)
what day of the week January first was in that year. I use 1900, but
you can pick pretty much any year you want.
- Count the number of years since that year. Since there are 365 days in
a year, and 365 = 52 * 7 + 1, a month/day combination shifts forward
one day per year.
- Count the number of leap years (including the current year) since the
base year (include the base year, if applicable). Every leap year of
course adds one extra day. Note the rule for determining
whether a year is a leap year, below.
- Add in a "magic" number that offsets for the month within the year.
It's not really magic, but it can seem that way. What you do is assign
a number to January that corresponds to the day of the week it started
on in your base year. I want my answer to come out as a number between
0 and 6 (inclusive), with 0 indicating Sunday. Since 1900 began on a
Monday, I give a 1 to January. Then you can compute the "magic" values
for the remaining months by simply adding the number of days in the
current month (28 for February; we already took care of leap years in
step 3) to the number for the current month and computing the result
modulo 7. (See below if you don't know
modular arithmetic.) So my numbers are 1, 4, 4, 0, 2, 5, 0, 3, 6,
1, 4, 6.
- Add in the day of the month.
- If the date in question is in a leap year, but before February 29th, we
added in an extra day in step 3, so subtract one.
- Compute the modulus-7 value of the sum of the numbers in steps 2-6.
- You now have a value between 0 and 6, inclusive. 0 indicates Sunday, 1
indicates Monday, etc.
Yuck, huh? Well, here's a C program
that computes exactly that. It's really simple on a computer.
Doing it in your head
The real fun is when you can do this in your head and always get it right.
The general algorithm above works fine, except that for certain years, the
numbers get kind of big and hard to remember. So here's a modified
algorithm that should be easier to keep in your head. I'll assume that we
are going to use 1900 as the base year (should cover most birthdays, which
seems to be the popular request).
- Divide the last two digits of the year by 12 with integer division,
getting a quotient and a remainder. Come on now, you did this in grade
school - it's not hard. Add those two numbers, modulo 7.
- Divide the remainder found in step 1 (not the sum, the remainder from
the division) by 4 and get the quotient. (We don't need this
remainder.) Add it to the sum found in step 1 and again take the
modulus-7 result.
- Add in the value assigned to the desired month:
January | 1 | |
February | 4 | |
March | 4 |
April | 0 | |
May | 2 | |
June | 5 |
July | 0 | |
August | 3 | |
September | 6 |
October | 1 | |
November | 4 | |
December | 6 |
If you are in to math and recognize the three-digit patterns
of perfect squares and that helps you remember this step, use that.
Otherwise, just memorize those numbers or memorize how they were
created (see step 4 in the general algorithm).
Compute the modulus-7 result.
- Add in the day of the month and compute the modulus-7 result.
- If you are in a leap year but before February 29th, subtract one,
modulus 7.
And once again you've got a number between 0 and 6 inclusive, where 0
indicates Sunday, 1 indicates Monday, etc.
You can shift it to 1800 by changing the magic numbers for the months. That
year, 1 January was a Wednesday, so add 2 (modulo 7) to the numbers. 1 Jan
1700 was a Friday, but for dates prior to 14 Sep 1752, things get messy
anyway, since that was when the British government added days to the
calendar to account for the new information about the length of the year.
(14 Sep 1752 immediately followed 2 Sep 1752.)
So you think you've got it, huh?
All right, let's try it out. Compute the day of the week for a month, date,
and year. Then enter the values below and see how you did. You may enter
the year as a four-digit number or relative to 1900 (e.g. 97 will be assumed
to be 1997, 110 will be assumed to be 2010).
If you aren't sure, keep track of where you are at every step of the way.
It will be printed out on the answer page.