日历-星期数计算方式(可计算2000年后的星期数)

#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];
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值