📄 calendar.h
字号:
typedef unsigned char uchar;
typedef unsigned int uint;
//年份数据表*/
uchar year_code[]={
0x7A,0xAd,0xBd, //2006
0x02,0x5d,0x52, //2007
0x09,0x2d,0x47, //2008
0x5C,0x95,0xBA, //2009
0x0A,0x95,0x4e, //2010
};/*月份数据表*/
static uchar day_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};
static unsigned short day_code2[3]={0x111,0x130,0x14e};
/****************************************************************************
* 子函数,用于读取数据表中农历月的大月或小月,如果该月为大返回1,为小返回0
****************************************************************************/
static uchar GetMoonDay(uchar 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);
}
/*********************************************************************************************************
** 函数名称:GetChinaCalendar
** 功能描述:公农历转换(只允许1901-2099年)
** 输 入: year 公历年
** month 公历月
** day 公历日
** p 储存农历日期地址
** 输 出: 1 成功
** 0 失败
********************************************************************************************************/
uchar GetChinaCalendar(uint year,uchar month,uchar day,uchar *p)
{
uchar temp1,temp2,temp3,month_p,yearH,yearL;
uchar flag_y;
unsigned short temp4,table_addr;
yearH=year/100; yearL=year%100;
if((yearH!=19)&&(yearH!=20)) return(0);
/* 定位数据表地址 */
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;
/* 计算公历日离当年元旦的天数 */
if (month<10) temp4=day_code1[month-1]+day-1;
else temp4=day_code2[month-10]+day-1;
/* 如果公历月大于2月并且该年的2月为闰月,天数加1 */
if ((month>2)&&(yearL%4==0)) temp4++;
/* 判断公历日在春节前还是春节后 */
if (temp4>=temp3)
{
temp4-=temp3;month=1;month_p=1;
flag_y=0;
if(GetMoonDay(month_p,table_addr)==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;
}
*p++=yearH;*p++=yearL;*p++=month;*p=day;
return(1);
}
uchar table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表
/*********************************************************************************************************
** 函数名称:GetSkyEarth
** 功能描述:输入公历日期得到一个甲子年(只允许1901-2099年)
** 输 入: year 公历年
** p 储存甲子年源数字的首地址
** 输 出: 无
********************************************************************************************************/
static void GetSkyEarth(uint year,uchar *p)
{ uchar x;
if(year>=1984)
{ year=year-1984;x=year%60; }
else
{ year=1984-year;x=60-year%60;}
*p=x;
}
//天干地支及农历相关的
static uchar const sky[][3]= {"甲","乙","丙","丁","戊","己","庚","辛","壬","癸",};
static uchar const earth[][3]={"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥",};
static uchar const monthcode[][3]={"一","二","三","四","五","六","七","八","九","十","冬","腊",};
static uchar const nongliday[][3]={"初","十","廿","三",};
//复制天干地支到target中
static void StrCopy(char *target,uchar const *source,uchar no)
{ uint i;
for(i=0;i<no;i++)
{ *target++=*source++; }
}
/*********************************************************************************************************
** 函数名称:GetChinaCalendarStr
** 功能描述:输入公历日期得到农历字符串
** 如:GetChinaCalendarStr(2007,02,06,str) 返回str="丙戌年腊月十九"
** 输 入: year 公历年
** month 公历月
** day 公历日
** str 储存农历日期字符串地址 12Byte
** 输 出: 赋值str
********************************************************************************************************/
void GetChinaCalendarStr(uint year,uchar month,uchar day,char *str)
{
uchar NLyear[4];//存农历的年月日,NLyear[0]和[1]放年,NLyear[2]放月,NLyear[3]放日
uchar SEyear; //存天干地支的源数字
StrCopy(&str[0],(uchar *)"甲子正月初一",12); //先把字符串"甲子正月初一"复制到指针str中
if(GetChinaCalendar(year,month,day,(unsigned char *)NLyear)==0)
return; //不是20或21世纪则返回
GetSkyEarth(NLyear[0]*100+NLyear[1],&SEyear); //由农历年调天干地支程序,其源数字的地址放SEyear中
StrCopy(&str[0],(uchar *) sky[SEyear%10],2); //根据SEyear求出"甲",并放在str[0]str[1]中
StrCopy(&str[2],(uchar *) earth[SEyear%12],2); //根据SEyear求出"子",并放在str[2]str[3]中
if(NLyear[2]==1) StrCopy(&str[4],(uchar *)"正",2);//农历月是一月则显示正月,放在str[4]str[5]中
else StrCopy(&str[4],(uchar *)monthcode[NLyear[2]-1],2);//不是1月,则从表格中调
if(NLyear[3]>10) StrCopy(&str[8],(unsigned char *)nongliday[NLyear[3]/10],2);
else StrCopy(&str[8],(unsigned char *)"初",2);
StrCopy(&str[12],(unsigned char *)monthcode[(NLyear[3]-1)%10],2);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -