Hello I made a software that generates HTML calendar. I followed Method 1 algorithm from wiki http://www.wikihow.com/Calculate-the-Day-of-the-Week to get exact day of the week in current day for a year. But problem is that there is a bug when it goes from year 2099 to 2100 then in year 2100 it is about one day behind.
My question is... is that algorithm correct? Should it be a day back behind in year 2100? I have no time to wait 85 years to figure this out :( Also I tried Easter Sunday algorithm and it also generates Sunday on the day it should be Sunday by Day of the week algorithm so I am not sure who has the right, if me or the two correctly generating algorithms.
Here are next years what are buggy in my opinion:
Testing years 0 to 2200
Incorrect day from year to year: 99/100
Incorrect day from year to year: 199/200
Incorrect day from year to year: 299/300
Incorrect day from year to year: 499/500
Incorrect day from year to year: 599/600
Incorrect day from year to year: 699/700
Incorrect day from year to year: 899/900
Incorrect day from year to year: 999/1000
Incorrect day from year to year: 1099/1100
Incorrect day from year to year: 1299/1300
Incorrect day from year to year: 1399/1400
Incorrect day from year to year: 1499/1500
Incorrect day from year to year: 1699/1700
Incorrect day from year to year: 1799/1800
Incorrect day from year to year: 1899/1900
Incorrect day from year to year: 2099/2100
*EDIT
Here is algorithm to get Easter Sunday:
int c = year/100;
int n = year - 19*(int)(year/19);
int k = (c - 17)/25;
int i = c - (int)(c/4) - (int)((c - k)/3) + 19*n + 15;
i -= 30*(int)(i/30);
i -= (int)(i/28)*(1 - (int)(i/28)*(int)(29/(i + 1))*(int)((21 - n)/11));
int j = year + (int)(year/4) + i + 2 - c + (int)(c/4);
j -= 7*(int)(j/7);
int l = i - j;
int m = 3 + (int)((l + 40)/44); //Your month when is Easter Sunday
int d = l + 28 - 31*(int)(m/4); //Your day when is Easter Sunday
Here is algorithm to get day of the week in a Year Month Day
int [] CENTURY_TABLE = {0, 5, 3, 1};
int [] MONTH_TABLE = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
boolean leap = false;
int t1 = (day + MONTH_TABLE[month - 1]) % 7;
int m1 = year % 100;
int t2 = (m1 % 7) + (m1/4) + CENTURY_TABLE[((int)(year/100)) % CENTURY_TABLE.length] - (leap && (month == 1 || month == 2) ? 1 : 0);
if(t2 == -1){
t2 = 6;
}
int d = (t1 + t2) % 7; //0 - Saturday, 1 - Sunday, 2 - Monday... 6 - Friday
*FIX
Change "leap" summary in Day of Week algorithm to
leap = year % 4 == 0 && (year % 100 == 0 ? year % 400 == 0 : true) //This fixed my problem <3
答案 0 :(得分:1)
I think your program is affected by leap years: https://en.wikipedia.org/wiki/Leap_year
You have a problem on all years dividable through 100 but not 400.
Edit after select as solution:
The code works without problems. I slightly changed for a test and got no error:
@Test
public void dayTest()
{
for (int y = 2099; y <=2100; y++)
{
int day = easterSundayDay(y);
int month = easterSundayMonth(y);
assertTrue("Wrong year: " + day + "."+ month + "."+ y + " is day: " + dayOfWeek(day, month, y), 1 ==dayOfWeek(day, month, y));
}
}
public int easterSundayDay(int year)
{
int c = year/100;
int n = year - 19*(int)(year/19);
int k = (c - 17)/25;
int i = c - (int)(c/4) - (int)((c - k)/3) + 19*n + 15;
i -= 30*(int)(i/30);
i -= (int)(i/28)*(1 - (int)(i/28)*(int)(29/(i + 1))*(int)((21 - n)/11));
int j = year + (int)(year/4) + i + 2 - c + (int)(c/4);
j -= 7*(int)(j/7);
int l = i - j;
int m = 3 + (int)((l + 40)/44); //Your month when is Easter Sunday
int d = l + 28 - 31*(int)(m/4);
return d;
}
public int easterSundayMonth(int year)
{
int c = year/100;
int n = year - 19*(int)(year/19);
int k = (c - 17)/25;
int i = c - (int)(c/4) - (int)((c - k)/3) + 19*n + 15;
i -= 30*(int)(i/30);
i -= (int)(i/28)*(1 - (int)(i/28)*(int)(29/(i + 1))*(int)((21 - n)/11));
int j = year + (int)(year/4) + i + 2 - c + (int)(c/4);
j -= 7*(int)(j/7);
int l = i - j;
int m = 3 + (int)((l + 40)/44); //Your month when is Easter Sunday
int d = l + 28 - 31*(int)(m/4);
return m;
}
public int dayOfWeek(int day, int month, int year)
{
int [] CENTURY_TABLE = {0, 5, 3, 1};
int [] MONTH_TABLE = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
boolean leap = false;
int t1 = (day + MONTH_TABLE[month - 1]) % 7;
int m1 = year % 100;
int t2 = (m1 % 7) + (m1/4) + CENTURY_TABLE[((int)(year/100)) % CENTURY_TABLE.length] - (leap && (month == 1 || month == 2) ? 1 : 0);
if(t2 == -1){
t2 = 6;
}
int d = (t1 + t2) % 7;
return d;
}