Day of week function not working

77 views Asked by At

I'm trying to create a function where given a year where year > 1999 and it returns a value 0 through 6 where Sunday = 0, Monday = 1 ... Saturday = 6 that corresponds to the day of the week that the first day of November is on. Since I know November 1, 2000 is 3 (Wednesday) I use that as NOV1. I know I have to keep leap years in mind so I have an if statement that will help. I don't know why it doesn't work properly for years greater than 2100. Help!

public static int firstOfMonth(int year)
{
  int raw = year - 2000;
  int leapYears = raw / 4;
  int nonLeapYears = 0;
  if ( raw >= 100 )
  {
    nonLeapYears = raw / 100;
    leapYears = leapYears - ( nonLeapYears - ( nonLeapYears / 4 ) );
  }
  else
  {
    nonLeapYears = 0;
  }
  return ((( NOV1 + ( raw * 365 ) - leapYears) ) % 7 );
}

again, NOV1 = 3

2

There are 2 answers

4
Casey Rule On BEST ANSWER

The problem seems to occur because you are subtracting leap years in your return statement rather than adding them.


Part of the reason errors like this can occur and be so hard to notice is when the surrounding code becomes overly complicated. It's easier to see what was going wrong when you simplify the code.

For instance, this entire block of code:

int leapYears = raw / 4;
int nonLeapYears = 0;    
if ( raw >= 100 )
  {
    nonLeapYears = raw / 100;
    leapYears = leapYears - ( nonLeapYears - ( nonLeapYears / 4 ) );
  }
  else
  {
    nonLeapYears = 0;
  }

Can all be simplified to:

int leapYears = int(raw/4) - int(raw/100) + int(raw/400);

That's every fourth year minus years divisible by 100 except years also divisible by 400. Make sense? Once you have the number of leap years that have passed, calculating the number of days since Nov 1, 2000 should be as simple as:

365 * raw + leapYears;

You have to add as many extra days are there are leap years, since a leap year has 366 days. Therefore, your return statement should be:

return ( NOV1 + 365 * raw + leapYears ) % 7;

In the end, you should have something like this:

public static int firstOfMonth(int year)
{
    int raw = year - 2000;
    int leapYears = int(raw/4) - int(raw/100) + int(raw/400);
    return ( NOV1 + 365 * raw + leapYears ) % 7;
}
0
NerosE On

I think your code works up to year 2400. You need a check to see if the year is divisible by 400 - then it's a leap year...