#define UCLIP(a,b,c) ((a<b)?(b):((a>c)?c:a))
uint8 week_day[7]={6,7,1,2,3,4,5};//这个定义是依据2000年1月1日是星期六而定的,如果是其他基准就要变。以此道理,可以选择其他的作为基准参考点,这样就可以解决该算法只能计算2000年后的星期数限制。
/*************************************************************
* 函数介绍: 计算该月份总天数
* 输入参数: year: 年
: month: 月份
* 输出参数:无
* 返回值 :当前月份的天数
* 闰年,能被400整除,或者能被4整除但不能被100整除
*************************************************************/
uint16 dayofmonth(uint16 year, uint8 month);
/*************************************************************
* 函数介绍: 计算给定的月份与2000年1月1号的星期数相差多少天
* 输入参数: year: 年
: month: 月份
* 输出参数:无
* 返回值 :当前月份的天数
* 闰年,能被400整除,或者能被4整除但不能被100整除
*************************************************************/
uint8 weekofmonth(uint16 year,uint8 month);
/*************************************************************
* 函数介绍: 计算给定的时间的星期数
* 输入参数: year: 年
: month: 月份
: date: 当前日子
* 输出参数:无
* 返回值 :当前月份的天数
算法:
//以2000年一月一日为参考点;星期六
//计算隔N年,星期相差几;
//计算不同月份,星期差几个;
//还要计算闰年之间的差距;
*************************************************************/
uint8 weekofdate(uint16 my, uint8 m, uint8 d);
uint16 dayofmonth(uint16 year, uint8 month)
{
uint16 y;
uint8 m;
y= UCLIP(year,2000,2100);
m= UCLIP(month,1,12);
if(1==m||3==m||5==m||7==m||8==m||10==m||12==m)
{
return 31;
}
else if(2==m)
{
if (((0==y%4)&(0!=y%100))||(0==y%400))
{
return 29;
}
else
{
return 28;
}
}
else
{
return 30;
}
}
uint8 weekofmonth(uint16 year,uint8 month)
{
uint16 y;
uint8 m;
y = UCLIP(year,2000,2100);
m = UCLIP(month,1,12);
switch(m)
{
case 1:
return 0;//0
break;
case 2:
return 3;//2000年2月1日,比2000年1月1日,多4周又三天
break;
case 3:
return 3;//3
break;
case 4:
return 6;//6
break;
case 5:
return 1;//8
break;
case 6:
return 4;//11
break;
case 7:
return 6;//13
break;
case 8:
return 2;//16
break;
case 9:
return 5;//19
break;
case 10:
return 0;//21
break;
case 11:
return 3;//24
break;
case 12:
return 5;//26
break;
}
}
uint8 weekofdate(uint16 y, uint8 m, uint8 d)
{
uint16 year = 0;
uint8 month = 0;
uint8 date = 0;
uint8 day = 0;
uint16 leap_year = 0 ;
Int16 i = 0;
uint16 j = 0;
uint16 k = 0;
uint16 interval_day = 0;
year = UCLIP(y,2000,2100);
month = UCLIP(m, 1, 12);
day = dayofmonth( year, month );
date = ((d> day)?day:d);
//计算当前年与作为基准的2000年,相差的年数
k = year - 2000;
//计算当前的年与做为基准的2000年之间的闰年的天数
for(i=k,j=2000; i >=0; i--, j++)
{
if (((0==j%4)&(0!=j%100))||(0==j%400))
{
leap_year+=1;
}
}
if (((0==year%4)&(0!=year%100))||(0==year%400))//即使闰年,也要大于2月,闰年的那天才能加上否则要减去
{
if(month<3)
{
leap_year-=1;
}
}
//printf("~~~~~leap_year=%d~~~~~~~~~~/n",leap_year);
//printf("~~~~~interval_year=%d~~~~~~~~~~/n",k);
//计算当前月份与2000年1月1日的星期数相差的天数
if(year >=2000)
{
//interval_day = k + weekofmonth(year,month) + leap_year + (date-1) ;//加k是没多一年就会多一天
//printf("~~~~~week_day[%d]=%d~~~~~~~~~~/n/n/n",interval_day,week_day[interval_day%7]);
//return week_day[interval_day%7];
return week_day[(k + weekofmonth(year,month) + leap_year + (date-1))%7];
}
}