📄 nongli.c
字号:
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);
}
static unsigned char const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表
/*********************************************************************************************************
** 函数名称:GetWeek
** 功能描述:输入公历日期得到星期(只允许1901-2099年)
** 输 入: year 公历年
** month 公历月
** day 公历日
** p 储存星期地址
** 输 出: 无
** 作 者: Campo
** 修 改: 赖皮
** 日 期: 2007年02月06日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void GetWeek(
unsigned int year,
unsigned char month,
unsigned char day,
unsigned char *p)
{
unsigned int temp2;
unsigned char 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 储存星期地址
** 输 出: 无
** 作 者: 赖皮
** 日 期: 2007年02月06日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static void GetSkyEarth(unsigned int year,unsigned char *p)
{
unsigned char x;
if(year>=1984)
{
year=year-1984;
x=year%60;
}
else
{
year=1984-year;
x=60-year%60;
}
*p=x;
}
static unsigned char const sky[][3]= {"甲","乙","丙","丁","戊","己","庚","辛","壬","癸",};
static unsigned char const earth[][3]={"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥",};
static unsigned char const monthcode[][3]={"一","二","三","四","五","六","七","八","九","十","冬","腊",};
static unsigned char const nongliday[][3]={"初","十","廿","三",};
static void StrCopy(char *target,unsigned char const *source,unsigned char no)
{
unsigned int i;
for(i=0;i<no;i++)
{
*target++=*source++;
}
}
/*********************************************************************************************************
** 函数名称:GetChinaCalendarStr
** 功能描述:输入公历日期得到农历字符串
** 如:GetChinaCalendarStr(2007,02,06,str) 返回str="丙戌年腊月十九"
** 输 入: year 公历年
** month 公历月
** day 公历日
** str 储存农历日期字符串地址 15Byte
** 输 出: 无
** 作 者: 赖皮 ★〓个人原创〓★
** 日 期: 2007年02月06日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void GetChinaCalendarStr(
unsigned int year,
unsigned char month,
unsigned char day,
char *str)
{
unsigned char NLyear[4];
unsigned char SEyear;
StrCopy(&str[0],(unsigned char *)"甲子年正月初一",15);
if(GetChinaCalendar(year,month,day,(unsigned char *)NLyear)==0) return;
GetSkyEarth(NLyear[0]*100+NLyear[1],&SEyear);
StrCopy(&str[0],(unsigned char *) sky[SEyear%10],2); // 甲
StrCopy(&str[2],(unsigned char *)earth[SEyear%12],2); // 子
if(NLyear[2]==1) StrCopy(&str[6],(unsigned char *)"正",2);
else StrCopy(&str[6],(unsigned char *)monthcode[NLyear[2]-1],2);
if(NLyear[3]>10) StrCopy(&str[10],(unsigned char *)nongliday[NLyear[3]/10],2);
else StrCopy(&str[10],(unsigned char *)"初",2);
StrCopy(&str[12],(unsigned char *)monthcode[(NLyear[3]-1)%10],2);
}
/*********************************************************************************************************
** 以下为24节气计算相关程序
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
/*
每年24节气标志表
有兴趣的朋友可按照上面给的原理添加其它年份的表格
不是很清楚的朋友可给我发EMAIL
*/
static unsigned char const YearMonthBit[]=
{
0x4E,0xA6,0x99, //2000
0x9C,0xA2,0x98, //2001
0x80,0x00,0x18, //2002
0x00,0x10,0x24, //2003
0x4E,0xA6,0x99, //2004
0x9C,0xA2,0x98, //2005
0x80,0x82,0x18, //2006
0x00,0x10,0x24, //2007
0x4E,0xA6,0xD9, //2008
0x9E,0xA2,0x98, //2009
0x80,0x82,0x18, //2010
0x00,0x10,0x04, //2011
0x4E,0xE6,0xD9, //2012
0x9E,0xA6,0xA8, //2013
0x80,0x82,0x18, //2014
0x00,0x10,0x00, //2015
0x0F,0xE6,0xD9, //2016
0xBE,0xA6,0x98, //2017
0x88,0x82,0x18, //2018
0x80,0x00,0x00, //2019
0x0F,0xEF,0xD9, //2020
0xBE,0xA6,0x99, //2021
0x8C,0x82,0x98, //2022
0x80,0x00,0x00, //2023
0x0F,0xEF,0xDB, //2024
0xBE,0xA6,0x99, //2025
0x9C,0xA2,0x98, //2026
0x80,0x00,0x18, //2027
0x0F,0xEF,0xDB, //2028
0xBE,0xA6,0x99, //2029
0x9C,0xA2,0x98, //2030
0x80,0x00,0x18, //2031
0x0F,0xEF,0xDB, //2032
0xBE,0xA2,0x99, //2033
0x8C,0xA0,0x98, //2034
0x80,0x82,0x18, //2035
0x0B,0xEF,0xDB, //2036
0xBE,0xA6,0x99, //2037
0x8C,0xA2,0x98, //2038
0x80,0x82,0x18, //2039
0x0F,0xEF,0xDB, //2040
0xBE,0xE6,0xD9, //2041
0x9E,0xA2,0x98, //2042
0x80,0x82,0x18, //2043
0x0F,0xEF,0xFB, //2044
0xBF,0xE6,0xD9, //2045
0x9E,0xA6,0x98, //2046
0x80,0x82,0x18, //2047
0x0F,0xFF,0xFF, //2048
0xFC,0xEF,0xD9, //2049
0xBE,0xA6,0x18, //2050
};
static unsigned char const days[]=
{
6,20,4,19,6,21, //一月到三月 的节气基本日期
5,20,6,21,6,21, //四月到六月 的节气基本日期
7,23,8,23,8,23, //七月到九月 的节气基本日期
8,24,8,22,7,22, //十月到十二月的节气基本日期
};
static char const JieQiStr[][5]= //以公历日期先后排序
{
/* 名称 角度 公历日期 周期 */
"小寒", //285 1月 6日
"大寒", //300 1月20日 29.5天
"立春", //315 2月 4日
"雨水", //330 2月19日 29.8天
"惊蛰", //345 3月 6日
"春分", // 0 3月21日 30.2天
"清明", // 15 4月 5日
"谷雨", // 30 4月20日 30.7天
"立夏", // 45 5月 6日
"夏满", // 60 5月21日 31.2天
"芒种", // 75 6月 6日
"夏至", // 90 6月21日 31.4天
"小暑", //105 7月 7日
"大暑", //120 7月23日 31.4天
"立秋", //135 8月 8日
"处暑", //150 8月23日 31.1天
"白露", //165 9月 8日
"秋分", //180 9月23日 30.7天
"寒露", //195 10月 8日
"霜降", //210 10月24日 30.1天
"立冬", //225 11月 8日
"小雪", //240 11月22日 29.7天
"大雪", //255 12月 7日
"冬至", //270 12月22日 29.5天
};
/*********************************************************************************************************
** 函数名称:GetJieQi
** 功能描述:输入公历日期得到本月24节气日期 day<15返回上半月节气,反之返回下半月
** 如:GetJieQiStr(2007,02,08,str) 返回str[0]=4
** 输 入: year 公历年
** month 公历月
** day 公历日
** str 储存对应本月节气日期地址 1Byte
** 输 出: 1 成功
** 0 失败
** 作 者: 赖皮 ★〓个人原创〓★
** 日 期: 2007年02月08日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
unsigned char GetJieQi(
unsigned int year,
unsigned char month,
unsigned char day,
unsigned char *JQdate)
{
unsigned char 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 unsigned char 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 失败
** 作 者: 赖皮 ★〓个人原创〓★
** 日 期: 2007年02月08日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
unsigned char GetJieQiStr(
unsigned int year,
unsigned char month,
unsigned char day,
char *str)
{
unsigned char 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,(unsigned char *)JieQiStr[JQ],5);
return 1;
}
//今天不是一个节气日
StrCopy(str,(unsigned char *)"离小寒还有??天",15);
if(day<JQdate) //如果今天日期小于本月的节气日期
{
StrCopy(&str[2],(unsigned char *)JieQiStr[JQ],4);
day=JQdate-day;
}
else //如果今天日期大于本月的节气日期
{
StrCopy(&str[2],(unsigned char *)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 + -