初级会员
- 积分
- 155
- 金钱
- 155
- 注册时间
- 2013-10-17
- 在线时间
- 9 小时
|
发表于 2014-8-19 22:51:50
|
显示全部楼层
回复【21楼】bodysuit:
---------------------------------
u8 _cror_(u8 temp,u8 i)
{
u8 temp1;
u8 temp2;
temp1=temp;
temp2=temp;
temp1=temp1>>i;
temp1=temp1<<i;
temp2=temp2<<(8-i);
temp2=temp2>>(8-i);
return temp1+temp2;
}
//月份数据表
static const u8 day_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};//0,31,59,90,120,151,181,212,243
static const unsigned short day_code2[3]={0x111,0x130,0x14e}; //273,304,334
//子函数,用于读取数据表中农历月的大月或小月,如果该月为大返回1,为小返回0
static u8 GetMoonDay(u8 month_p,unsigned short table_addr)
{
switch (month_p)
{
case 1:
if((year_code[table_addr]&0x08)==0) return(0);
else return(1);
case 2:
if((year_code[table_addr]&0x04)==0) return(0);
else return(1);
case 3:
if((year_code[table_addr]&0x02)==0) return(0);
else return(1);
case 4:
if((year_code[table_addr]&0x01)==0) return(0);
else return(1);
case 5:
if((year_code[table_addr+1]&0x80)==0) return(0);
else return(1);
case 6:
if((year_code[table_addr+1]&0x40)==0) return(0);
else return(1);
case 7:
if((year_code[table_addr+1]&0x20)==0) return(0);
else return(1);
case 8:
if((year_code[table_addr+1]&0x10)==0) return(0);
else return(1);
case 9:
if((year_code[table_addr+1]&0x08)==0) return(0);
else return(1);
case 10:
if((year_code[table_addr+1]&0x04)==0) return(0);
else return(1);
case 11:
if((year_code[table_addr+1]&0x02)==0) return(0);
else return(1);
case 12:
if((year_code[table_addr+1]&0x01)==0) return(0);
else return(1);
case 13:
if((year_code[table_addr+2]&0x80)==0) return(0);
else return(1);
}
return(0);
}
//公历转农历函数
void Conversion(u8 c,u16 year,u8 month,u8 day)
{
u8 temp1,temp2,temp3,month_p,yearH,yearL;
u8 flag_y;
unsigned short temp4,table_addr;
yearH=year/100; yearL=year%100;//年份的高低两个字节
// if((yearH!=19)&&(yearH!=20))return(0);//日期不在19xx ~ 20xx 范围内,则退出
// 定位数据表地址
if(yearH==20) table_addr=(yearL+100-1)*3;
else table_addr=(yearL-1)*3;
// 取当年春节所在的公历月份
temp1=year_code[table_addr+2]&0x60;
temp1>>=5;
// 取当年春节所在的公历日
temp2=year_code[table_addr+2]&31;
//取当年春节所在的公历日完成
//计算当年春年离当年元旦的天数,春节只会在公历1月或2月
if(temp1==1) temp3=temp2-1;
else temp3=temp2+31-1;
// 计算当年春年离当年元旦的天数完成
//计算公历日离当年元旦的天数,为了减少运算,用了两个表
//day_code1[9],day_code2[3]
//如果公历月在九月或前,天数会少于0xff,用表day_code1[9],
//在九月后,天数大于0xff,用表day_code2[3]
//如输入公历日为8月10日,则公历日离元旦天数为day_code1[8-1]+10-1
//如输入公历日为11月10日,则公历日离元旦天数为day_code2[11-10]+10-1
if (month<10) temp4=day_code1[month-1]+day-1;
else temp4=day_code2[month-10]+day-1;
// 如果公历月大于2月并且该年的2月为闰月,天数加1
// if ((month>0x2)&&(year%0x4==0)&&(year!=0)) //此语句造成2000年3月1日—12月31日之间
//计算农历少算一天,应删除判断语句“&&(year!=0)”
if ((month>2)&&(yearL%4==0))
temp4++; //如果公历月大于2月并且该年的2月为闰月,天数加1
//计算公历日离当年元旦的天数完成
// 判断公历日在春节前还是春节后
if (temp4>=temp3)
{
temp4-=temp3;
month=1;
month_p=1;//month_p为月份指向,公历日在春节前或就是春节当日month_p指向首月
flag_y=0;
if(GetMoonDay(month_p,table_addr)==0) //检查该农历月为大小还是小月,大月返回1,小月返回0
temp1=29; //小月29天
else temp1=30; //大小30天
// 从数据表中取该年的闰月月份,如为0则该年无闰月
temp2=year_code[table_addr]/16;
while(temp4>=temp1)
{
temp4-=temp1;
month_p++;
if(month==temp2)
{
flag_y=~flag_y;
if(flag_y==0)month++;
}
else month++;
if(GetMoonDay(month_p,table_addr)==0) temp1=29;
else temp1=30;
}
day=temp4+1;
}
// 公历日在春节前使用下面代码进行运算
else
{
temp3-=temp4;
if (yearL==0)
{
yearL=100-1;
yearH=19;
}
else yearL--;
table_addr-=3;
month=12;
temp2=year_code[table_addr]/16;
if (temp2==0) month_p=12;
else month_p=13;
flag_y=0;
if(GetMoonDay(month_p,table_addr)==0) temp1=29;
else temp1=30;
while(temp3>temp1)
{
temp3-=temp1;
month_p--;
if(flag_y==0) month--;
if(month==temp2) flag_y=~flag_y;
if(GetMoonDay(month_p,table_addr)==0) temp1=29;
else temp1=30;
}
day=temp1-temp3+1;
}
c_moon=c;
month_moon=month;
day_moon=day;
year_moon=year; //农历年
} |
|