|
The method given on that site for computing the component that comes from the last 2 digits of the year can be made a lot easier for mental calculation. I'll give some known improvements below, and then offer one of my own that is noticeably simpler. In the following, let Y = the last two digits of the year (e.g., 18 for 2018), and let N be the value we are trying to be compute. We only actually need N mod 7, but I'm going to leave out the reduction mod 7 in the equations to reduce clutter. The simplest way to compute N is simply: N = Y + Y//4
I'll use Python3-like arithmetic and pseudocode in this comment, so "//" is integer division (with x for times to avoid accidental italics).To keep the numbers smaller during mental calculation, people have developed alternatives. The one given in that link is this: N = Y // 12
N += Y % 12
N += (Y % 12) // 4
An interesting alternative, called the "odd+11" method, is given on the Wikipedia article [1]: if odd(Y): Y += 11
Y = Y // 2
if odd(Y): Y += 11
N = -Y
For the last step there, N = -Y, it will usually be easier and clearer to reduce Y mod 7 before doing that N = -Y. Also, given Y, sometimes the simplest way to get -Y mod 7 is to just note what you have to add to Y to get to a multiple of 7. For example, if when you get to that step Y = 20, note that adding 1 to Y gives a multiple of 7, so -20 mod 7 = 1.Anyway, here's my method. It keeps the numbers smaller--if you reduce mod 7 aggressively never more than 12--at the cost of slightly more branches in the logic. Let the last two digits of the year be T and U, so Y = 10 T + U. N = 2 x T
if odd(T): N += 3
N += U
if odd(T):
N += (U+2)//4
else:
N += U//4
That if...else is taking into account the number of leap years that have occurred in the current decade (not including the year T0). When doing mental calculation, it is probably easier just to remember that if T is odd, at 1 if U >= 2 and add another 1 if U >= 6, and if T is even same except at 4 and 8.Here are examples, using some years from the link, with parenthetical explanations for some of the numbers: 2018: T=1, U=8. 2x1(T) + 3(T is odd) + 8(U) + 2(U>=2,6) = 1 mod 7. 1929: T=2, U=9. 2x2(T) + 9(U) + 2(U>=4,8) = 1 mod 7. 1999: T=9, U=9. 2x2(T%7) + 3(T is odd) + 2(U%7) + 2(U>=2,6) = 4 mod 7. Note that I reduced U and T mod 7 inline when using them. You can do this as long as when checking odd/even you use the original T, and when adding in the leap year correction you use the original U. E.g., for 99, you could compute it like it was 22, except you have to add the 3 for odd T, and use 9 for the U>=2,6 check. 1982: T=8, U=2. 2x1(T%7) + 2(U) = 4 mod 7. 1969: T=6, U=9. 2x(-1)(T%7) + 2(U%7) + 2(U>=4,8) = 2 mod 7. Some might find changing the leap year handling to this a little easier instead of just remembering the 2,6 or 4,8 +1 points. Change the if...else to this: N += U//4
if odd(T) and N%4 >= 2: N += 1
E.g., compute the leap year adjustment with U//4 regardless of whether T is odd or even, and if U is in {2, 3, 6, 7} and T is odd, add one more.[1] https://en.wikipedia.org/wiki/Doomsday_rule#The_%22odd_+_11%... |
The basic idea is to compute the year day for the "0th" day of the month, then add the day of the month. For example, today, October 13th is the 286th day of the year, because October 0th is the 273rd day of the day, so 13 days past that is the 286th.
The simplest way, short of memorizing the 0th day of each month directly (or the 1st day...if you are going to take this approach might as well do the 1st, not the 0th), is to memorize how far off the actual 0th day is from what the 0th would be if all months were exactly 30 days.
Those differences are, for the 12 months:
If F[m] refers to the the m'th entry in that list, 1 <= m <= 12, then the 0th day for month m is 30(m-1) + F[m]. E.g., for October, m = 10, so 30x(10-1) + F[10] = 30x9+3 = 273.If it is a leap year, add one more day for dates after February 29.
The F table has enough structure that it is not unreasonable to just memorize it.
For m >= 4, F[m] = (6x(m-4))//10. If you round toward -∞ instead of 0 when dividing, that works for m >= 3. It's probably harder to remember this than to just remember the table.
Let M[m] = the month factor from the Doomsday algorithm:
Then F[m] = -(M[m] + 2 x m + 2) mod 7. Just remember that -1 <= F[m] <= 4, so you can pick the right range when reducing mod 7.For example, let's do July 20th, 1969, the day of the first Moon landing. July is the 7th month, and the month factor for that in the Doomsday algorithm is 11, so we have F[7] = -(11 + 2x7 + 2) = 1 mod 7, so F[m] = 1, and July 0th is 30x(7-1)+1 = 181, and so July 20th is the 201st day of the year.
BTW, if you find F[] easier to memorize than M[], you reverse the formula given above for computing F from M, to go the other way.
M[m] = -(F[m] + 2 x m + 2) mod 7.
While I'm here, one more Doomsday observation.
If a given year, Y, has year number N, then the next year with the same year number is:
• Y+6 if Y%4 == 0 or 1
• Y+11 if Y%4 == 2
• Y+5 if Y%4 == 3
(but only if that does not cross a century boundary).
The day of weeks within a century go on a 28 year cycle. Within any 28 consecutive years in a century, each of the 7 possible year number values occurs 4 times, once on a year with Y%4 == 0, once on a Y%4 == 1 year, and so on.
If you start with Y%4 == 0 year, the gaps between consecutive years with the same year number are 6, 11, 6, 5, which brings you back to the Y%4 == 0 year for the next 28 year cycle. You visit the years in the order 0, 2, 1, 3 mod 4 stepping this way.
If you memorize this pattern, it is easier to answer questions about when years or dates with specific properties happen. For example, let's say you want to know when there will next be a Friday the 13th in October.
Assuming that there will be another one this century, so using the century factor of 2 (for 20xx), you can work out that in this century Friday October 13 occurs when the year number is 0. Such a year was 2000, and 00 is a Y%4 == 0 year, so Friday October 13th occurs in 2000, 2000+6=2006, 2006+11=2017, 2017+6=2023, and then 2023+5 brings is to the 2028, the next 28 year cycle. So the next Friday October 13 is 2023.
BTW, the first Y in a century with year number N and with Y%4 == 0 is (3xN%7)x4.
If you don't care about starting from a Y%4 == 0 year, then it is easiest probably to just memorize the first year with year number 0, 1, 2, ..., 6 in a century:
and then add multiples of 28 to get to where you want to be. E.g., if you were trying to find the first time your birthday falls on a Thursday after 2040, and figured out you need year number 4, that table would tell you 2009 is such a year, and the 28 year cycles would tell you 2037, 2065, and 2093 are other such years, so you'd probably go to 2037 and work forward from there. 36 is a 1%4 year, so the next with the same year number is 2043, and you are done!