📄 lunar.c.svn-base
字号:
0x0d,0x15,0x41, //2098
0x2d,0x92,0xB5, //2099
};
///月份数据表
code uchar ri_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};
code uint ri_code2[3]={0x111,0x130,0x14e};
code uchar table_xingqi[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表
bit get_moon_ri(uchar yue_p,uint table_addr)
{
uchar tenp;
switch (yue_p)
{
case 1:{tenp=nian_code[table_addr]&0x08;
if (tenp==0)return(0);else return(1);}
case 2:{tenp=nian_code[table_addr]&0x04;
if (tenp==0)return(0);else return(1);}
case 3:{tenp=nian_code[table_addr]&0x02;
if (tenp==0)return(0);else return(1);}
case 4:{tenp=nian_code[table_addr]&0x01;
if (tenp==0)return(0);else return(1);}
case 5:{tenp=nian_code[table_addr+1]&0x80;
if (tenp==0) return(0);else return(1);}
case 6:{tenp=nian_code[table_addr+1]&0x40;
if (tenp==0)return(0);else return(1);}
case 7:{tenp=nian_code[table_addr+1]&0x20;
if (tenp==0)return(0);else return(1);}
case 8:{tenp=nian_code[table_addr+1]&0x10;
if (tenp==0)return(0);else return(1);}
case 9:{tenp=nian_code[table_addr+1]&0x08;
if (tenp==0)return(0);else return(1);}
case 10:{tenp=nian_code[table_addr+1]&0x04;
if (tenp==0)return(0);else return(1);}
case 11:{tenp=nian_code[table_addr+1]&0x02;
if (tenp==0)return(0);else return(1);}
case 12:{tenp=nian_code[table_addr+1]&0x01;
if (tenp==0)return(0);else return(1);}
case 13:{tenp=nian_code[table_addr+2]&0x80;
if (tenp==0)return(0);else return(1);}
}
}
/*
函数功能:输入BCD阳历数据,输出BCD阴历数据(只允许1901-2099年)
调用函数示例:Conversion(c_sun,nian_sun,yue_sun,ri_sun)
如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);
c_sun,nian_sun,yue_sun,ri_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世
纪,c_sun=1为19世纪
调用函数后,原有数据不变,读c_moon,nian_moon,yue_moon,ri_moon得出阴历BCD数据
*/
void Conversion(bit c,uchar nian,uchar yue,uchar ri)
{ //c=0 为21世纪,c=1 为19世纪 输入输出数据均为BCD数据
uchar tenp1,tenp2,tenp3,yue_p;
uint tenp4,table_addr;
bit flag2,flag_y;
tenp1=nian/16; //BCD->hex 先把数据转换为十六进制
tenp2=nian%16;
nian=tenp1*10+tenp2;
tenp1=yue/16;
tenp2=yue%16;
yue=tenp1*10+tenp2;
tenp1=ri/16;
tenp2=ri%16;
ri=tenp1*10+tenp2;
//定位数据表地址
if(c==0)
{
table_addr=(nian+0x64-1)*0x3;
}
else
{
table_addr=(nian-1)*0x3;
}
//定位数据表地址完成
//取当年春节所在的公历月份
tenp1=nian_code[table_addr+2]&0x60;
tenp1=_cror_(tenp1,5);
//取当年春节所在的公历月份完成
//取当年春节所在的公历日
tenp2=nian_code[table_addr+2]&0x1f;
//取当年春节所在的公历日完成
// 计算当年春年离当年元旦的天数,春节只会在公历1月或2月
if(tenp1==0x1)
{
tenp3=tenp2-1;
}
else
{
tenp3=tenp2+0x1f-1;
}
// 计算当年春年离当年元旦的天数完成
//计算公历日离当年元旦的天数,为了减少运算,用了两个表
//ri_code1[9],ri_code2[3]
//如果公历月在九月或前,天数会少于0xff,用表ri_code1[9],
//在九月后,天数大于0xff,用表ri_code2[3]
//如输入公历日为8月10日,则公历日离元旦天数为ri_code1[8-1]+10-1
//如输入公历日为11月10日,则公历日离元旦天数为ri_code2[11-10]+10-1
if (yue<10)
{
tenp4=ri_code1[yue-1]+ri-1;
}
else
{
tenp4=ri_code2[yue-10]+ri-1;
}
if ((yue>0x2)&&(nian%0x4==0))
{ //如果公历月大于2月并且该年的2月为闰月,天数加1
tenp4+=1;
}
//计算公历日离当年元旦的天数完成
//判断公历日在春节前还是春节后
if (tenp4>=tenp3)
{ //公历日在春节后或就是春节当日使用下面代码进行运算
tenp4-=tenp3;
yue=0x1;
yue_p=0x1; //yue_p为月份指向,公历日在春节前或就是春节当日yue_p指向首月
flag2=get_moon_ri(yue_p,table_addr);
//检查该农历月为大小还是小月,大月返回1,小月返回0
flag_y=0;
if(flag2==0)tenp1=0x1d; //小月29天
else tenp1=0x1e; //大小30天
tenp2=nian_code[table_addr]&0xf0;
tenp2=_cror_(tenp2,4); //从数据表中取该年的闰月月份,如为0则该年无闰月
while(tenp4>=tenp1)
{
tenp4-=tenp1;
yue_p+=1;
if(yue==tenp2)
{
flag_y=~flag_y;
if(flag_y==0)
yue+=1;
}
else
yue+=1;
flag2=get_moon_ri(yue_p,table_addr);
if(flag2==0)
tenp1=0x1d;
else
tenp1=0x1e;
}
ri=tenp4+1;
}
else
{ //公历日在春节前使用下面代码进行运算
tenp3-=tenp4;
if (nian==0x0)
{
nian=0x63;c=1;
}
else
nian-=1;
table_addr-=0x3;
yue=0xc;
tenp2=nian_code[table_addr]&0xf0;
tenp2=_cror_(tenp2,4);
if (tenp2==0)
yue_p=0xc;
else
yue_p=0xd; //
/*yue_p为月份指向,如果当年有闰月,一年有十三个月,月指向13,无闰月指向12*/
flag_y=0;
flag2=get_moon_ri(yue_p,table_addr);
if(flag2==0)
tenp1=0x1d;
else
tenp1=0x1e;
while(tenp3>tenp1)
{
tenp3-=tenp1;
yue_p-=1;
if(flag_y==0)
yue-=1;
if(yue==tenp2)
flag_y=~flag_y;
flag2=get_moon_ri(yue_p,table_addr);
if(flag2==0)
tenp1=0x1d;
else
tenp1=0x1e;
}
ri=tenp1-tenp3+1;
}
c_moon=c; //HEX->BCD ,运算结束后,把数据转换为BCD数据
tenp1=nian/10;
tenp1=_crol_(tenp1,4);
tenp2=nian%10;
nian_moon=tenp1|tenp2;
tenp1=yue/10;
tenp1=_crol_(tenp1,4);
tenp2=yue%10;
yue_moon=tenp1|tenp2;
tenp1=ri/10;
tenp1=_crol_(tenp1,4);
tenp2=ri%10;
ri_moon=tenp1|tenp2;
}
/*函数功能:输入BCD阳历数据,输出BCD星期数据(只允许1901-2099年)
调用函数示例:Conver_xingqi(c_sun,nian_sun,yue_sun,ri_sun)
如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);
c_sun,nian_sun,yue_sun,ri_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世
纪,c_sun=1为19世纪
调用函数后,原有数据不变,读xingqi得出阴历BCD数据
*/
/*
算法:日期+年份+所过闰年数+月较正数之和除7 的余数就是星期但如果是在
闰年又不到3 月份上述之和要减一天再除7
星期数为0
*/
void Conver_xingqi(bit c,uchar nian,uchar yue,uchar ri)
{//c=0 为21世纪,c=1 为19世纪 输入输出数据均为BCD数据
uchar tenp1,tenp2;
tenp1=nian/16; //BCD->hex 先把数据转换为十六进制
tenp2=nian%16;
nian=tenp1*10+tenp2;
tenp1=yue/16;
tenp2=yue%16;
yue=tenp1*10+tenp2;
tenp1=ri/16;
tenp2=ri%16;
ri=tenp1*10+tenp2;
if(c==0)
{
nian+=0x64; //如果为21世纪,年份数加100
}
tenp1=nian/0x4; //所过闰年数只算1900年之后的
tenp2=nian+tenp1;
tenp2=tenp2%0x7; //为节省资源,先进行一次取余,避免数大于0xff,避免使用整型数据
tenp2=tenp2+ri+table_xingqi[yue-1];
if (nian%0x4==0&&yue<3)
tenp2-=1;
xingqi=tenp2%0x7;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -