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.

  1. function dayOfWeek($date)
  2. {
  3. $total = 0;
  4. $date = explode('/', $date);
  5.  
  6. if ( $date[0] 7 ) {
  7. $total = $total % 7;
  8. }
  9.  
  10. // extract year
  11. $year = $date[0] % 100;
  12. // divide by 12, add this to remainder, add number of 4's in the remainder
  13. $year = (((int)($year/12)) + ($year%12) + ((int)(($year%12)/4)));
  14. // add the year to the total
  15. $total = $centry + $year;
  16.  
  17. // if total is more than seven then divide by 7 and take remainder
  18. if ( $total >= 7 ) {
  19. $total = $total % 7;
  20. }
  21.  
  22. // extract month
  23. $month = $date[1];
  24. // pick month from table
  25. $monthTable = array(0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5);
  26. $month = $monthTable[(int)$month - 1];
  27. // add month to total
  28. $total = $total + $month;
  29.  
  30. // extract day
  31. $day = $date[2];
  32.  
  33. // if the year is a leap year, and the month is January or February then minus 1.
  34. if ( $date[0]%4==0 ) {
  35. if ( $date[0]%100 == 0 ) {
  36. if ( $date[0]%400 == 0 ) {
  37. if ( $date[1] == 1 || $date[1] == 2 ) {
  38. $day = $day - 1;
  39. }
  40. }
  41. } else {
  42. if ( $date[1] == 1 || $date[1] == 2 ) {
  43. $day = $day-1;
  44. }
  45. }
  46. }
  47.  
  48. // add to total
  49. $total = $total + $day;
  50.  
  51. // if total is more than seven then divide by 7 and take remainder
  52. if ( $total >= 7 ) {
  53. $total = $total % 7;
  54. }
  55.  
  56. // convert day number into day
  57. $days = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
  58. return $days[$total];
  59. }

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

  1. echo dayOfWeek('1979/07/13');
  2. echo ' ';
  3. echo dayOfWeek('2008/05/12');
  4. echo ' ';
  5. 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.