#include "stdio.h"
/*验证数据*/ typedef struct DATE_tag { int y, m, d; int w; }DATE;
int numItem; DATE aCheck[]={ /* 年,月,日,星期 */ {0000, 3, 1, 3}, {1600, 3, 1, 3}, {2000, 3, 1, 3}, {2001, 3, 1, 4}, {2004, 3, 1, 1}, {2008, 3, 1, 6}, {2042, 3, 1, 6},
/* 平年3月1日 */ {1700, 3, 1, 1}, /* 注意:1700年是平年 */ {1800, 3, 1, 6}, /* 注意:1800年是平年 */ {1900, 3, 1, 4}, /* 注意:1900年是平年 */ {1901, 3, 1, 5}, {1918, 3, 1, 5}, {1958, 3, 1, 6}, {1988, 3, 1, 2}, {1999, 3, 1, 1}, {2100, 3, 1, 1}, /* 注意:2100年是平年 */ {2101, 3, 1, 2}, {2102, 3, 1, 3}, {2103, 3, 1, 4}, {2104, 3, 1, 6}, /* 注意:2104年是闰年 */ /* 不是周2 */ {9999, 3, 1, 1},
/* 2004年的重大节日 */ {2004, 1, 1, 4}, /* 元旦 */ {2004, 1, 22, 4}, /*春节*/ {2004, 2, 5, 4}, /*宵节*/ {2004, 3, 8, 1}, /*妇女节*/ {2004, 3, 12, 5}, /*植树节*/ {2004, 3, 15, 1}, /*投诉节*/ {2004, 4, 4, 0}, /*清明节*/ {2004, 5, 1, 6}, /*五一节*/ {2004, 5, 4, 2}, /*青年节*/ {2004, 5, 9, 0}, /*母亲节*/ {2004, 6, 1, 2}, /*儿童节*/ {2004, 6, 22, 2}, /*端午节*/ {2004, 7, 1, 4}, /*建党节*/ {2004, 8, 1, 0}, /*建军节*/ {2004, 8, 8, 0}, /*父亲节*/ {2004, 9, 10, 5}, /*教师节*/ {2004, 9, 28, 2}, /*中秋节*/ {2004, 10, 1, 5}, /*国庆节*/ {2004, 10, 6, 3}, /*老人节*/ {2004, 10, 22, 5}, /*重阳节*/ {2004, 11, 7, 0}, /*立冬节*/ {2004, 12, 21, 2}, /*冬至节*/
/* 二十世纪 */ {1900, 1, 1, 1}, /*元旦*/
{1900, 3, 1, 4}, /* 公式测试关键点 */
{1918, 1, 21,1}, /*大寒*/ {1918, 2, 11, 1}, /*春节*/ {1927, 1, 1, 6}, /*元旦 */ {1948, 1, 18, 0}, /*腊八节*/ {1949, 10, 1, 6}, /*国庆*/ {1962, 5, 1, 2}, /*劳动节*/ {1999, 12, 31, 5},
/* 二十一世纪 */ {2000, 1, 1, 6}, /*元旦*/ {2018, 1, 20, 6}, /*大寒*/ {2018, 2, 16, 5}, /*春节*/ {2027, 1, 1, 5}, /*元旦*/ {2048, 1, 22, 3}, /*腊八节*/ {2099, 12, 31, 4},
/* 二十二世纪 */ {2100, 1, 1, 5}, {2100, 1, 31, 0}, {2100, 2, 1, 1}, {2100, 2, 28, 0}, {2100, 3, 1, 1}, {2100, 3, 31, 3}, {2100, 12, 31, 5}, {2101, 1, 1, 6}, {2101, 1, 31, 1}, {2101, 2, 1, 2}, {2101, 2, 28, 1}, {2101, 3, 1, 2}, {2101, 3, 31, 4}, {2101, 12, 31, 6}, {2104, 2, 29, 5}, /* 不是周1 */ {2104, 3, 1, 6}, /* 不是周2 */ {2199, 12, 31, 2} };
| int dayofweek(int y, int m, int d); /* 0 sunday */
int main() { int i; int y, m, d, w;
numItem = sizeof(aCheck)/sizeof(aCheck[0]); for(i=0; i<numItem; i++) { y = aCheck[i].y; m = aCheck[i].m; d = aCheck[i].d; w = aCheck[i].w; if(w != dayofweek(y, m, d)) { printf("error on %dth item:(%d,%d,%d,%d), calc res is %d \n", i, y, m, d, w, dayofweek(y, m, d)); break; } } if(i == numItem) puts("ok"); else puts("no");
}
int leap(int y) { return ( (y%4==0)&&(y%100!=0) ) || (y%400==0); }
int dayofweek(int y, int m, int d) /* 0 sunday */ { #if 1 /* 算法原型——需要判断润年 */ int w=0;
static int wFirstDayOfMonth_noLeap[]={0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5}; #if 0 if(leap(y)) { if(m<3) w = (y + y/4-y/100+y/400 -1 + wFirstDayOfMonth_noLeap[m-1] + d + 6) % 7; else w = (y + y/4-y/100+y/400 + wFirstDayOfMonth_noLeap[m-1] + d + 6) % 7;
} else { w = (y + y/4-y/100+y/400 + wFirstDayOfMonth_noLeap[m-1] + d + 6) % 7; } #else if(m<3) { if(leap(y)) { w = (y + y/4-y/100+y/400 + wFirstDayOfMonth_noLeap[m-1] + d + 5) % 7; } else { w = (y + y/4-y/100+y/400 + wFirstDayOfMonth_noLeap[m-1] + d + 6) % 7; } } else w = (y + y/4-y/100+y/400 + wFirstDayOfMonth_noLeap[m-1] + d + 6) % 7; #endif
return w;
#else /* 算法变形——不需要判断润年 */ /* 此算法版本最初由 Tomohiko Sakamoto 提供 */ int w=0; static int t[]={0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; y-=m<3; w = (y+y/4-y/100+y/400+t[m-1]+d)%7; return w;
#endif }
|