📄 calendar.c
字号:
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);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数名称:GetWeek
// 功能描述:输入公历日期得到星期(只允许1901-2099年)
// 输 入: year 公历年
// month 公历月
// day 公历日
// p 储存星期地址
// 输 出: 无
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void GetWeek(u16 year,u8 month,u8 day,u8 *p)
{
u16 temp2;
u8 yearH,yearL;
yearH=year/100; yearL=year%100;
// 如果为21世纪,年份数加100
if (yearH>19) yearL+=100;
// 所过闰年数只算1900年之后的
temp2=yearL+yearL/4;
temp2=temp2%7;
temp2=temp2+day+table_week[month-1];
if (yearL%4==0&&month<3)temp2--;
*p=(temp2%7);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数名称:GetSkyEarth
// 功能描述:输入公历日期得到一个甲子年(只允许1901-2099年)
// 输 入: year 公历年
// p 储存星期地址
// 输 出: 无
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void GetSkyEarth(u16 year,u8 *p)
{
u8 x;
if(year>=1984)
{
year=year-1984;
x=year%60;
}
else
{
year=1984-year;
x=60-year%60;
}
*p=x;
}
//将指定字符source复制no个给target
void StrCopy(u8 *target,u8 const *source,u8 no)
{
u16 i;
for(i=0;i<no;i++)
{
*target++=*source++;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数名称:GetChinaCalendarStr
// 功能描述:输入公历日期得到农历字符串
// 如:GetChinaCalendarStr(2007,02,06,str) 返回str="丙戌年腊月十九"
// 输 入: year 公历年
// month 公历月
// day 公历日
// str 储存农历日期字符串地址 15Byte
// 输 出: 无
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void GetChinaCalendarStr(u16 year,u8 month,u8 day,u8 *str)
{
u8 NLyear[4];
u8 SEyear;
StrCopy(&str[0],(u8 *)"甲子年正月初一",15);
if(GetChinaCalendar(year,month,day,(u8 *)NLyear)==0) return;
GetSkyEarth(NLyear[0]*100+NLyear[1],&SEyear);
StrCopy(&str[0],(u8 *) sky[SEyear%10],2); // 甲
StrCopy(&str[2],(u8 *)earth[SEyear%12],2); // 子
if(NLyear[2]==1) StrCopy(&str[6],(u8 *)"正",2);
else StrCopy(&str[6],(u8 *)monthcode[NLyear[2]-1],2);
if(NLyear[3]>10) StrCopy(&str[10],(u8 *)nongliday[NLyear[3]/10],2);
else StrCopy(&str[10],(u8 *)"初",2);
StrCopy(&str[12],(u8 *)monthcode[(NLyear[3]-1)%10],2);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数名称:GetJieQi
// 功能描述:输入公历日期得到本月24节气日期 day<15返回上半月节气,反之返回下半月
// 如:GetJieQiStr(2007,02,08,str) 返回str[0]=4
// 输 入: year 公历年
// month 公历月
// day 公历日
// str 储存对应本月节气日期地址 1Byte
// 输 出: 1 成功
// 0 失败
/////////////////////////////////////////////////////////////////////////////////////////////////////////
u8 GetJieQi(u16 year,u8 month,u8 day,u8 *JQdate)
{
u8 bak1,value,JQ;
if((year<2000)||(year>2050)) return 0;//节气表的范围限制
if((month==0) ||(month>12)) return 0;
JQ = (month-1) *2 ; //获得节气顺序标号(0~23
if(day >= 15) JQ++; //判断是否是上半月
bak1=YearMonthBit[(year-2000)*3+JQ/8]; //获得节气日期相对值所在字节
value =((bak1<<(JQ%8))&0x80); //获得节气日期相对值状态
*JQdate=days[JQ]; //得到基本节气日
if( value != 0 )
{
//判断年份,以决定节气相对值1代表1,还是-1。
if( (JQ== 1||JQ== 11||JQ== 18||JQ== 21)&&year< 2044) (*JQdate)++;
else (*JQdate)--;
}
return 1;
}
static u8 const MonthDayMax[]={31,28,31,30,31,30,31,31,30,31,30,31,};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数名称:GetJieQiStr
// 功能描述:输入公历日期得到24节气字符串
// 如:GetJieQiStr(2007,02,08,str) 返回str="离雨水还有11天"
// 输 入: year 公历年
// month 公历月
// day 公历日
// str 储存24节气字符串地址 15Byte
// 输 出: 1 成功
// 0 失败
/////////////////////////////////////////////////////////////////////////////////////////////////////////
u8 GetJieQiStr(u16 year,u8 month,u8 day,u8 *str)
{
u8 JQdate,JQ,MaxDay;
if(GetJieQi(year,month,day,&JQdate)==0) return 0;
JQ = (month-1) *2 ; //获得节气顺序标号(0~23
if(day >= 15) JQ++; //判断是否是上半月
if(day==JQdate) //今天正是一个节气日
{
StrCopy(str,(u8 *)JieQiStr[JQ],5);
return 1;
}
//今天不是一个节气日
StrCopy(str,(u8 *)"离小寒还有??天",15);
if(day<JQdate) //如果今天日期小于本月的节气日期
{
StrCopy(&str[2],(u8 *)JieQiStr[JQ],4);
day=JQdate-day;
}
else //如果今天日期大于本月的节气日期
{
StrCopy(&str[2],(u8 *)JieQiStr[JQ+1],4);
if(day < 15)
{
GetJieQi(year,month,15,&JQdate);
day=JQdate-day;
}
else //翻月
{
MaxDay=MonthDayMax[month-1];
if(month==2) //润月问题
{
if((year%4==0)&&((year%100!=0)||(year%400==0))) MaxDay++;
}
if(++month==13) month=1;
GetJieQi(year,month,1,&JQdate);
day=MaxDay-day+JQdate;
}
}
str[10]=day/10+'0';
str[11]=day%10+'0';
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -