Correctness of Sakamoto's algorithm to find the day of week

Viewed 43996

I am using Sakamoto's algorithm to find out the day of week from a given date. Can anybody tell me the correctness of this algorithm? I just want this from 2000 to 2099.

The algorithm from Wikipedia is given for reference.

int dow(int y, int m, int d)
{
   static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
   y -= m < 3;
   return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}
4 Answers

This might not be a complete answer like some mentioned above, But just would like to add one thing regarding this array : 0 3 2 5 0 3 5 1 4 6 2 4

Consider months beginning from March and ending at February just like others said:

  1. March
  2. April
  3. May
  4. June
  5. July
  6. August
  7. September
  8. October
  9. November
  10. December
  11. January
  12. February

Writing January to December from above numbering style :

So consider this as an array : int t[] = {11,12,1,2,3,4,5,6,7,8,9,10};

Now for all elements in array just do : (2.6*m - 0.2) mod 7 parse the result as integer and you will get this: 0 3 2 5 0 3 5 1 4 6 2 4

int dayOfWeek(int d, int m, int y){
  // Months Array
  int t[] = {11,12,1,2,3,4,5,6,7,8,9,10};

  // Convert months array
  for (int i = 0; i < 12; i++){
    int ans = t[i] * 2.6 - 0.2;
    t[i] = ans % 7;
  }

  // Continue Algo
  if(m<3)
    y -= 1;

  int day = (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
  return day;
}

this : + y/4 - y/100 + y/400 is related to leap year. The algo to check for leap year is :

  1. Perfectly Divisible by 400 -> true
  2. IF perfectly divisible by 100 but not by 400 -> False
  3. Divisible by 4 -> True

perform checks on above order. Maybe that is why they subtracted y/100 and added y/4 & y/400. Yeah silly logic

I know this might not be the answer, But this might help to those who find it difficult to remember/understand stuff, yeah! not all of us have high IQ levels of understanding stuff and sadly some of us can't remember stuff too, lol.

For Gregorian Calendar

int dayToWeekG(int d,int m,int y){
    int i;
    int t[12]={0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
            //{0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
    y-=m<3;
    i=(y+y/4-y/100+y/400 +t[m-1]+d)%7;
    return i;
}

Explanation:

  • See the commented array for
 t[] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};

and compare it with a calendar of a whole year (run cal 2to generate calendar in terminal in linux/unix) notice the starting day of the week of the day for each month.

  • Every normal year shifting one day of the week and leap year shifting two days of the week. as (365%7)=1 and (366%7)=2
 i= y+y/4-y/100+y/400
  • But we are should not calculate the extra day if y is a leap year for month 0 and 1
y-=m<3
  • but by this way we are also removing the extra day from non-leap years too. so we will fill up the gap by subtracting 1 day for every month after February.

    int t[12]={0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};

Related