此程序为本人所写,免费供有需要的人使用,无版权纠纷;
程序的功能是输入2000年2月5日(正月初一)至2100年12月31日之间的公历日期,输出对应的农历日期(闰月以月份+128表示);
该程序由IAR编译成MSP430的目标代码,大约占用600个字节的程序空间,如改用汇编,去除多余的头尾,应该可以缩减到500字节以内;
程序特在于用101个16位字表述了101年的农历大小月及闰月的数据。低12位表示对应12个月的月大或月小,最低位为正月,1表示月大;高4位为0时表示当年及下一年无闰月;高4位为1~12时表示下一年度的相应月存在闰月;高4位为13或14时,分别表示当前年的闰月为月小或月大。按照这个结构可以扩充到更多年份,但程序中对非闰年的公历1900,2200,2300,2500年份未作处理,仅对2100作为特例处理。
为简化程序,在转换函数内对输入日期的合法性未作判别,如输入1810-2-15、2008-6-31等,将导致不可预料的输出结果。
提醒:程序仅进行了抽样测试,未做逐月验证,对于相近农历月大小颠倒的情况不能排除,如作为产品使用,请再次确认转换表数据的正确性。
//Lunar calendar convert program
//Designed by QQ984809120, 2009-10-6
unsigned int yy1,mm1,dd1;
unsigned int yy2,mm2,dd2;
/*
convert table(2000~2100) structure:
D15~D12=1110  leap month(30 days)
D15~D12=1101  leap month(29 days)
D15~D12=0000  Current and next year no leap month
D15~D12=0001~1100 leap month number of next year
D11~D0 = days of 12 months, 1: 30 days; 0: 29 days
*/
const unsigned int table[101] = {0x4693,
0xDA9B, 0x052B, 0x2A5B, 0xDAAE, 0x756A, 0xDDD5, 0x0BA4, 0x5B49, 0xDD53, 0x0A95,
0x452D, 0xD55D, 0x9AB5, 0xDBAA, 0x05D2, 0x6DA5, 0xEE8A, 0x0D4A, 0x4C95, 0xDA9E,
0x0556, 0x2AB5, 0xDADA, 0x66D2, 0xD765, 0x0725, 0x564B, 0xD657, 0x0CAB, 0x355A,日期转字符串函数
0xD56E, 0xBB69, 0xDF52, 0x0B52, 0x5B25, 0xDD2B, 0x0A4B, 0x54AB, 0xD2BB, 0x05AD,
0x2B6A, 0xDDAA, 0x7D92, 0xDEA5, 0x0D25, 0x5A55, 0xEA4D, 0x04B6, 0x35B5, 0xE6D2,
0x8EC9, 0xDF92, 0x0E92, 0x6D26, 0xE516, 0x0A57, 0x44D6, 0xE365, 0x0755, 0x3749,
0xD74B, 0x7693, 0xDAAB, 0x052B, 0x5A5B, 0xDABA, 0x056A, 0x4B65, 0xDBAA, 0x8B4A,
0xDD95, 0x0A95, 0x652D, 0xD56D, 0x0AB5, 0x55AA, 0xE5C5, 0x0DA5, 0x3D4A, 0xDE4D,
0x7C96, 0xDCCE, 0x0556, 0x5AB5, 0xEAD2, 0x06D2, 0x5EA5, 0xD72A, 0x868B, 0xD697,
0x04AB, 0x655B, 0xE556, 0x0B6A, 0x4752, 0xDB95, 0x0B25, 0x2A8B, 0xDA4F, 0x04AB};
/
*Convert routine
2000<yy<=2100, 1<=mm<=12, 1<=dd<=31
*/
date_cvt (yy,mm,dd)
unsigned int yy;
unsigned char mm,dd;
{ unsigned char i,j,leap;
unsigned int days1,days2,x;
days1 = (yy-2000) * 365 + ((yy-1997)>>2) + (mm-1)*30 + dd;
if ((mm >2) && (((yy-2000) & 3) == 0) && (yy != 2100))
days1 ++;
switch(mm)
{
case 3:  days1--;
break;
case 11:
case 12: days1 ++;
case 9:
case 10: days1 ++;
case 8:  days1 ++;
case 2:
case 6:
case 7:  days1 ++;
break;
}  //------days from 1999-12-31
days1 -=35;
days2=0;
leap=0xFF;
for (i=0; i<=2100; i++)
{x=table[i];
for (j=0; j<12; j++)
{
days2 += 29 + (x & 1);
if (days2 >= days1)
break;
if (j==leap)
{
days2 = days2 + 16 + (table[i] >> 12);
if (days2 >= days1)
{  j |= 0x80;
break;
}
x >>= 1;
}
if (days2 >= days1)
break;
leap = x-1;
}
x = 29 + (x & 1) -(days2-days1);
yy2=i+2000;  //output result
mm2=j+1;
dd2=x;
}
main()  /*main program*/
{ yy1=2009;
mm1=10;
dd1=6;
date_cvt(yy1,mm1,dd1);
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。