Day Of The Week Algorithm By Lewis Carroll In PHP

12th May 2008 - 4 minutes read time

Lewis Carroll devised a mechanism to work out the day of the week given a particular date and was published in Science in 1887. Here is a PHP function that works out the day of the week given the date that uses the same mechanism that Lewis Carroll devised. The mechanism isn't very complicated, but rather than explain it twice I have just put a lot of comments in the code to indicate what is happening.

function dayOfWeek($date)
{
 $total = 0;
 $date = explode('/', $date);
 
 if ( $date[0]  7 ) {
  $total = $total % 7;
 }
 
 // extract year
 $year = $date[0] % 100;
 // divide by 12, add this to remainder, add number of 4's in the remainder
 $year = (((int)($year/12)) + ($year%12) + ((int)(($year%12)/4)));
 // add the year to the total
 $total = $centry + $year;
 
 // if total is more than seven then divide by 7 and take remainder
 if ( $total >= 7 ) {
  $total = $total % 7;
 }
 
 // extract month
 $month = $date[1];
 // pick month from table
 $monthTable = array(0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5);
 $month = $monthTable[(int)$month - 1];
 // add month to total
 $total = $total + $month;
 
 // extract day
 $day = $date[2];
 
// if the year is a leap year, and the month is January or February then minus 1.
 if ( $date[0]%4==0 ) {
  if ( $date[0]%100 == 0 ) {
   if ( $date[0]%400 == 0 ) {
    if ( $date[1] == 1 || $date[1] == 2 ) {
     $day = $day - 1;
    }
   }
  } else {
   if ( $date[1] == 1 || $date[1] == 2 ) {
    $day = $day-1;
   }
  }
 }
 
 // add to total
 $total = $total + $day;
 
 // if total is more than seven then divide by 7 and take remainder
 if ( $total >= 7 ) {
  $total = $total % 7;
 }
 
 // convert day number into day
 $days = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
 return $days[$total];
}

Use the function by giving it a date in the format of YYYY/MM/DD. Here are a couple of examples.

echo dayOfWeek('1979/07/13');
echo ' ';
echo dayOfWeek('2008/05/12');
echo ' ';
echo dayOfWeek('1640/02/06');
Prints out:
Wednesday Monday Thursday

The month table is taken from an example page by the University of Sydney. This page is also useful if you want to know how the algorithm works in detail.

Note that if the date is prior to 1752 then you need to subtract the number by 18. This is because the Gregorian calendar was modified in 1752 by dropping the days between September 3 and 13. However, not all countries participated in this update.

Comments

Permalink
This script wont recognize dayOfWeek('2008/02/03') ... for some reason, February 3rd 2008 is answering a blank date. You have to correct lines 29 and 63 to be ">= 7" and not just ">7" /d

David Cuartielles (Sat, 04/04/2009 - 17:17)

Permalink
Very true. I have added the fix you found to the script. Thanks!

Add new comment

The content of this field is kept private and will not be shown publicly.