
This article came out of a question I asked myself yesterday.
“Is there a year in which no month begins on Monday?”
At first glance, yes. A year can begin on any day of the week, the months also begin each time on different days of the week. Many options, most likely, there is not one such year.
So I thought for the first minute after I wondered. It should prove. Go through all the years, for example. Simple and fast way, but not interesting. Proving mathematically was a much more tempting idea, but I absolutely did not understand how to approach this. So I just started writing the duration of each month on paper.
It is worth mentioning that the discussion will go on about the
Gregorian calendar , according to which we have been living since 1918. However, part of the reasoning will be true for the
Julian .
In fact, this year does not exist. Let's figure out why.
')
Part 1. Months
First, remember how many days in each month:
Now let's see how many days in each month are more than four weeks.
In this place the next idea arises. If we add 7 days to the date, the day of the week will not change. Works modular arithmetic. From this it is easy to understand that if there are two days more in a month than in four weeks, then the first day of the next month will move by two days of the week relative to the first day of the current month. Anyway,
if in a month (28 + N) days, then the first day of the next month will move by N days relative to the day of the week of the first day of the current month.
For example, this year, January began on Tuesday, so February began on Friday. W + 3 = Fri.
How much is the day of the first day of a month shifted? To find this, one must sum the "surplus" days over four weeks in all previous months. The table shows shifts relative to the day of the week on the first of January. The first line for a non-leap year, the second for a leap year.
But this does not look very significant, and we know that a seven-day shift does not change the day of the week. Therefore, we now write to the table the remains of dividing the total shifts by 7.
Now it's another matter! It is clear how to determine the day of the week on the first day of any month if the day of the week is known on the first of January. You just need to add a shift for the month of interest. I know the pattern February-March-November from school, but I have not noticed others.
We received an answer to the question at the beginning of the article.
Since for both variants of the year in the table there are all shifts from 0 to 6, then in any year there is a month that starts on a certain day of the week.
But now you can ask other questions. For example, “in which years such a month is only one?” Or “in which years there are as many such months as possible?”. To do this, you must be able to determine the day of the week on the first of January of any year.
Part 2. Years
When I was learning to program, and this was in the 10th grade at PascalABC, one of the first serious tasks was to implement a procedure that prints a calendar for the year, which was passed as an argument. We had clues as to what functions to do. In general, it all came down to counting the days between two dates: the reference and the current, to determine the day of the week for the first of January of the desired year.
This approach worked, but the speed depended on how close the required year to the reference year was. It upset me, but I couldn’t think of something better then. Now the perfect moment has come to fully understand this.
Leap years in the Gregorian calendar are assigned as follows:
- the year whose number is a multiple of 400 is a leap year
- the rest of the year whose number is a multiple of 100 is non-leap
- the remaining years, whose number is a multiple of 4, are leap years
- the rest of the year - non-leap
From this description it can be seen that the leap cycle has a period of 400 years. But it is not clear whether such four-hundred-year cycles will begin on the same day of the week.
Note that the first of January from year to year is shifted by one or two days of the week, and we write
some code.bool is_leap_year(int year) { if ((year % 400) == 0) return true; if ((year % 100) == 0) return false; if ((year % 4) == 0) return true; return false; } void first_weekdays_table() { ofstream file("weekdays.txt", ios_base::out); int weekday = 3; for (int i = 1801; i <= 3000; ++i) { file << weekday; if ((i % 100) != 0) { file << " "; } else { file << endl; } weekday += is_leap_year(i) ? 2 : 1; weekday %= 7; } file.close(); }
The days of the week are displayed on the first of January of each year, from 1801 to 3000. Monday is designated as “0”, Tuesday as “1”, and so on. We represent everything in the form of a table of two complete four-hundred year cycles and two halves. Centuries go horizontally, along the vertical of the year in these centuries. In the cells at the intersection of the century and the year is written the day of the week on which this year began For example, the day of the week on which 1997 began was at the intersection of the “1900” column and the “97” row. This is Wednesday. Full version of the table:
part 1 ,
part 2 .


Two things can be immediately noticed in the table: four hundred-year cycles really begin on the same day of the week (2001, 2401 and 2801; Monday), and instead of 2000 there is "one thousand nine hundred and hundredth". Last done on purpose for further convenience. The first fact allows us to move on without obstacles.
In the Gregorian calendar, all four hundred-year cycles begin on Monday.
But the most interesting is covered in the full version of the table. You may find that every century within a four-hundred year cycle consists of a repeating twenty-eight-year cycle:
The first century begins with a cycle offset of 0, the second with an offset of 4, the third with an offset of 8, and the fourth with an offset of 12. It is for this that the table is presented in the form where there are hundredths of years and there are no zero. It is worth saying that in total there are 14 different versions of the year. In the twenty-eight-year cycle, once for each day of the week, there is a beginning of a leap year and three times the beginning of a non-leap year.
Now we can determine the day of the week for any date, without using reference dates. To do this, we need to understand which century within the four-hundred year cycle is the year and what count it is in this century. According to the table, we will determine the day of the week on January 1 of the year, and with the help of the first part of the article, the day of the week on a specific date of the required month. Instead of a thousand words
write some more code. int get_weekday(int year, int month, int day) { int weekdays[] = {0, 1, 2, 3, 5, 6, 0, 1, 3, 4, 5, 6, 1, 2, 3, 4, 6, 0, 1, 2, 4, 5, 6, 0, 2, 3, 4, 5}; int shift_not_leap[] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5}; int shift_leap[] = {0, 3, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6}; bool is_leap = is_leap_year(year); year -= 1; year %= 400; int century = year / 100; year %= 100; int index = (year + (4 * century)) % 28; int weekday = weekdays[index]; weekday += is_leap ? shift_leap[month - 1] : shift_not_leap[month - 1]; weekday += (day - 1); weekday %= 7; return weekday; }
Part 3. Results
With just two tables, you can determine the day of the week for any date without using reference dates.
The sequence of the days of the week on the first of January in the twenty-eight-year cycle:
And the table of days offsets of the week for the first day of each month for non-leap and leap years:
While writing the article, I found two similar topics on Habré:
one and
two times . The author of the first with the help of a special table shows how to find in the mind the day of the week for dates in the XX and XXI centuries. The table presented to them contains 56 numbers. The algorithm proposed in the article uses a table of days of the week and two tables of offsets containing (28 + 2 * 12) = 52 numbers that must be remembered. All source code is on
GitHub .
An interesting fact: from February 1 to February 13, 1918, no one was born in Soviet Russia.
Ask yourself questions on Sunday mornings =)