How to calculate the day of the week from a date... in your head
Mar 20Like the recipe for Greek fire, memorizing an algorithm to find the weekday name from just a date was something I used to know when I was younger, but forgot due to lack of use. I used to be able to churn the numbers in my brain (don't mind the smoke!) and come up with the correct answer in a minute or so. Every now and again I've wanted to re-discover that algorithm and learn to do the calculations in my head again, so recently I got down and did it.
It's actually tough to find "day of week from date" algorithms in online searches because most results will be for programming functions or Excel formulas that do the work for you instead of explaining how exactly they calculated it. What we want is a page explaining how we calculate it, not just how to get your program to output the right answer. You know... show your work!
Going by the general feel of what I remembered of the old algorithm I used to use, I found and discarded several algorithms because they required memorization of (seemingly) arbitrary codes, especially for the months. I didn't remember having to do this years ago, so they were out.
Eventually though, I came across this page: https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html
In it, there's a nice algorithm that boils everything down to one equation. Note that it only works for the Gregorian calendar!
W = (k + ⌊2.6m - 0.2⌋ - 2C + Y + ⌊Y / 4⌋ + ⌊C / 4⌋) mod 7
Where ⌊⌋ denotes the integer floor function.
k is day (1 to 31)
m is month (1 = March, ..., 10 = December, 11 = Jan, 12 = Feb) Treat Jan & Feb as months of the preceding year
C is century (1987 has C = 19)
Y is year (1987 has Y = 87 except Y = 86 for Jan & Feb)
W is week day (0 = Sunday, ..., 6 = Saturday)
This is a great starting point, but not very easy to calculate in your head, especially with that 2.6m - 0.2 bit. Who has time to deal with decimals?! So how to simplify this?
Well, we can break it up into four separate bits, each of which are either added or subtracted from the final amount on which we perform modulus 7:
This is just straight k, so no issues there.
The month term is ⌊2.6m - 0.2⌋ which is not very user friendly. Let's factor this up by multiplying both terms by 5, then dividing it all by 5.
⌊(13m - 1) / 5⌋
Multiplying by 13 isn't the easiest, but you can pretty much do it in your head by multiplying by 10 first, then adding 3 more. So if your month (m) value is 8, first multiply 8 x 10 for 80, then add 8 x 3, or 24, for 104. From there, subtracting one, then dividing by 5 is easy. 104 - 1 = 103, and since we know we're going to floor the result, just take the lowest multiple of 5 out of it, so 103 => 100, and 100 / 5 is 20.
The year term is Y + ⌊Y / 4⌋ which we can't really simplify at all. At least I don't see any way! So it's best to leave it as is.
Here's where it gets a little interesting. The century term is (usually) a negative value: -2C + ⌊C / 4⌋ It's not that difficult to calculate in your head as it's similar to the year term, just multiplying the first term by negative two instead. Is it possible to simplify this?
Well, if you start with input 17 (for 1700s) and check the output of this term, you'll get the following series: -30, -32, -34, -35, -37, -39, -41, -42, -44... A pattern? Kinda. But not really anything we could memorize or calculate easily in our heads. If you're like me, you find juggling negative numbers a pain. So leave this term as is... for now?
So now we have our new, updated equation:
W = (k + ⌊(13m - 1) / 5⌋ + Y + ⌊Y / 4⌋ - 2C + ⌊C / 4⌋) mod 7
Still not very head-calculation friendly! If we just put it in terms of "terms", we can look at the equation like this:
W = (k + m + y + c) mod 7
Where:
m = ⌊(13m - 1) / 5⌋
y = Y + ⌊Y / 4⌋
c = - 2C + ⌊C / 4⌋
Now's the time we take a good look at how the modulus operator works. A modulus simply means the remainder after a division operation. It's the amount left that doesn't go into the number after the operator. So when you think about it, all you're really doing with something like "mod 7" is just subtracting 7 from your number until you can't anymore. Say you start with a number like 33. Subtract 7 => 26. Subtract 7 => 19. Subtract 7 => 12. Subtract 7 => 5. So 33 modulus 7 is 5.
Therefore, if a modulus is just a series of subtractions, then if all the terms we have are just addition and subtraction, we can take the modulus of them individually without bothering to sum them all up! So the equation W = (k + m + y + c) mod 7 is functionally equivalent to W = (k mod 7 + m mod 7 + y mod 7 + c mod 7) mod 7.
Now we're cooking, because with any of the terms, we can just modulus 7 it to get a number much easier to deal with in our heads.
Perhaps the day of the month you're trying to find is the 30th. Well just modulus 7 that puppy and you only have to deal with 2 for the k term. Neat, right? Okay, lets put our equation to the test with a real date: August 24th, 1965
As before, here's our equation: W = (k + m + y + c) mod 7
The day is 24. 24 modulus 7 is 3, so 3 is our k term.
The month is August. Remember from the original equation that the months are... shifted. March is 1, April is 2, and so on until January = 11 and February = 12. So in this case, August is 6. Let's sub that into ⌊(13m - 1) / 5⌋.
(13 * 6 - 1) / 5 (Remember 6 x 10 = 60 and add 6 x 3 = 18, so 78)
(78 - 1) / 5
77 / 5 => 75 / 5 = 15
15 modulus 7 is 1, so our m term is 1.
The last two digits of the year are 65. Let's sub that into Y + ⌊Y / 4⌋
65 + ⌊65 / 4⌋
65 + 16 = 81
How can we do 81 modulus 7 easily in our heads? Well, remember that we're just subtracting 7 over and over, so multiples of 7 just speed up the work. In this case, just subtract 70 (10 x 7) from 81 to leave 11. 11 modulus 7 is 4, so our y term is 4.
The first two digits of the year, the century value, are 19. Let's sub that into - 2C + ⌊C / 4⌋
-2 x 19 + ⌊19 / 4⌋
-38 + 4
-34
How the heck do we get modulus 7 of a negative number? Well, remember that the modulus is the remainder after subtracting 7 over and over again, and if we subtract, or add, multiples of 7, it doesn't change the final output. So let's add 70 (10 x 7) to our negative number: -34 + 70 = 36. 36 modulus 7 is 1, so our c term is 1.
Here we go, now our equation is the very simple looking:
W = (3 + 1 + 4 + 1) mod 7
W = 9 mod 7
W = 2
If Sunday is 0, that means our day of the week for August 24th, 1965 is Tuesday. And double checking... that's correct!
Let's take another look at the trickiest part of the calculation, the negative values related to the century. I mentioned before that there's a pattern to the output from this term, starting from the 1700s: -30, -32, -34, -35, -37, -39, -41, -42, -44. It's important to note that all dates in the 1700s (except for January + Feb in 1700 which get calculated as if they were in 1699) result in the c term of -30. This term gets put to modulus 7 which results in (after adding 70) 5. What about the 1800s? Well, that results in 3. 1900s? 1. 2000s? 0. 2100s? 5... again?
If you suspect this might be a pattern, you're exactly correct. The resulting values for c after modulus 7 are (starting from 1700): 5, 3, 1, 0, 5, 3, 1, 0... over and over again. This seems like a simple pattern to get from an equation, so how can we do it?
First notice that all centuries that result in a c term of 0 are divisible by 4 (2000s, 2400s etc.) So if we take modulus 4 of the century value we get 0. Great! But... we also get values 1, 2, and 3 for the intervening years which we need to map to 5, 3 and 1 respectively.
Hrms, if we add 7, and then subtract twice those values, we get:
17 mod 4 = 1 => 7 - 2 * 1 => 7 - 2 = 5
18 mod 4 = 2 => 7 - 2 * 2 => 7 - 4 = 3
19 mod 4 = 3 => 7 - 2 * 3 => 7 - 6 = 1
Great! But just one more thing... We're adding 7 in this equation, and the final modulus is just going to subtract it again, so we can just drop it. Now it's far easier to get the century term: just take modulus 4 of the century, then multiply it by negative 2. That's: -2 * (C mod 4) In our August 24th, 1965 case, we would get:
-2 * (19 mod 4) = -2 * 3 = -6
Which results in:
W = (3 + 1 + 4 - 6) mod 7 (Notice how -6 is exactly the previous value of 1 but subtracting 7, this should give us the same answer!)
W = 2 mod 7
W = 2 (Woo hoo!)
This gives a final final equation of:
W = (k + ⌊(13m - 1) / 5⌋ + Y + ⌊Y / 4⌋ - 2 * (C mod 4)) mod 7
Again, we go through this equation, treating it like adding up four discreet terms we can all individually modulus 7:
W = (k + m + y + c) mod 7
As long as you remember the ways to get each term, and then modulus 7 each as you go along, the final value to calculate will always consist of very small, easy to deal with integers. For me personally, I find it's best to start with the month term which, at least to me, is the most mentally taxing to calculate. From there it's simpler to just remember the result of that term while you calculate the others.
Let me know what you think!
⇐ Version 1.54 of the Virtual Keyboard Interface Javascript Released |