?? 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 + -