This article will present the Lewis Carrol's algorithm to calculate the day of the week.
Lewis Carrol was a mathematician and logician at Oxford University. He is a wellknown name today for his children novels such as "Alice in Wonderland", published in 1871.
The name Lewis Carrol is a pseudonym, his real name was Charles Ludwidge Dodgson. The algorithm presented here was released in 1883.
Let's look at the algorithm next for calculating the day of week. Please note that this algorithm got inaccuracies for leap years and february, it is about 90-95% correct for all dates. In many cases it will give correct results for other dates. The algorithm presented here is for dates after September 12, 1752 due to changes in our calendar system at that date.
Construct a Number n consisting of four parts where
n = CCYYMMDD | CC = century, YY = year, MM = month , DD = day
For example, the date 18th of January, 2025 is written as
n = 202501818 , CC = 20, YY = 25, MM = 01, DD = 18
The calculation will sum up the contributions from the numbers into a sum S as :
S = Sum_cc + Sum_yy + Sum_mm + Sum_dd
The sum S is then taken the modulo of 7, where the number 0 means Sunday and number 6 means Saturday. The day and week is therefore the modulo 7 of S where starting from Sunday, the remainder from S mod 7 is the weekday, starting with index 0 for Monday.
Let's look at the different part sums next.
Sum_cc is calculated as the 3 subtracted by the century modulo 4 and this is multiplied by two. Sum_yy is the year divided by 12 plus the year modulo 12 and the year divided by 4. Sum_mm is defined as the month looked up in a lookup table of values shown in the source code. Sum_dd is just the date of the month.
The summmation looks like this:
private int DayOfWeekLevisCarrol(int date){
int century = date / 1_000_000;
int year = (date / 10_000) % 100;
int month = (date / 100) % 100;
int dayValue = (date % 100);
int[] monthValues = [0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 12];
int centuryValue = (3-(century % 4))*2;
int yearValue = (year/12) + (year % 12) + ((year % 12)/4);
int monthValue = monthValues[month-1];
var sumValues= (centuryValue+yearValue+monthValue+dayValue) % 7;
return sumValues;
}
This helper method shows the weekday presented as text:
public string WeekDayLevisCarrol(int date) => DayOfWeekLevisCarrol(date) switch {
0 => "Sunday",
1 => "Monday",
2 => "Tuesday",
3 => "Wednesday",
4 => "Thursday",
5 => "Friday",
6 => "Saturday",
_ => "Impossible"
};
A more compressed way of expressing this is the following:
/// <summary>
/// Calculates the day of the week using Lewis Carroll's method.
/// </summary>
/// <param name="date">The date in yyyymmdd format.</param>
/// <returns>The day of the week as an integer (0 for Sunday, 1 for Monday, etc.).</returns>
private int DayOfWeekLevisCarrolV2(int date) =>
((3 - (date / 1_000_000 % 4)) * 2 +
(date / 10_000 % 100 / 12) + (date / 10_000 % 100 % 12) + ((date / 10_000 % 100 % 12) / 4) +
new int[] { 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 12 }[(date / 100 % 100) - 1] +
(date % 100)) % 7;
Running the metod for today (I used 18th of January 2025):
void Main()
{
int todayDate = int.Parse(DateTime.Today.ToString("yyyyMMdd"));
string todayWeekdate = WeekDayLevisCarrol(todayDate);
Console.WriteLine($"Levis-Carrol's method calculated weekday for {DateTime.Today.ToShortDateString()} written as number {todayDate} is: {todayWeekdate}");
}
Output is:
Levis-Carrol's method calculated weekday for 18.01.2025 written as number 20250118 is: Saturday
As noted, this algorithm is about 90-95% correct since it is not precise in leap years and in February. There are more precise calculation algorithms today, the algorithm is to be considered a crude approach and more modern algorithms exists today.
In .NET, the calculation of the weekday is done inside the DateTime struct calculated from the start of Epoch at year 1 and there are precise calculations considering shifts in calendars and leap years, so of course you should use DayOfWeek of a DateTime in .NET.
But it is a fun trivia that the author of "Alice in Wonderland" was a also a noted mathematician and according to history, he calculated weekdays for dates in few seconds using this algorithm, often being correct.
No comments:
Post a Comment