农历C算法

/*------------农历转换函数-----------*/
char   * GetDayOf(PSYSTEMTIME pSt)

 
/*天干名称*/
 
const char *cTianGan[] = {"","","","","","","","","",""};
 
/*地支名称*/
 
const char *cDiZhi[] = {"","","","","","","",
       
"","","","",""}
;
 
/*属相名称*/
 
const char *cShuXiang[] = {"","","","","","",
       
"","","","","",""}
;
 
/*农历日期名*/
 
const char *cDayName[] = {"*","初一","初二","初三","初四","初五",
       
"初六","初七","初八","初九","初十",
       
"十一","十二","十三","十四","十五",
       
"十六","十七","十八","十九","二十",
       
"廿一","廿二","廿三","廿四","廿五",       
       
"廿六","廿七","廿八","廿九","三十"}
;
 
/*农历月份名*/
 
const char *cMonName[] = {"*","","","","","","",
       
"","","","","十一",""}
;

 
/*公历每月前面的天数*/
 
const int wMonthAdd[12= {0,31,59,90,120,151,181,212,243,273,304,334};
 
/*农历数据*/
 
const int wNongliData[100= {2635,333387,1701,1748,267701,694,2391,133423,1175,396438
       ,
3402,3749,331177,1453,694,201326,2350,465197,3221,3402
       ,
400202,2901,1386,267611,605,2349,137515,2709,464533,1738
       ,
2901,330421,1242,2651,199255,1323,529706,3733,1706,398762
       ,
2741,1206,267438,2647,1318,204070,3477,461653,1386,2413
       ,
330077,1197,2637,268877,3365,531109,2900,2922,398042,2395
       ,
1179,267415,2635,661067,1701,1748,398772,2742,2391,330031
       ,
1175,1611,200010,3749,527717,1452,2742,332397,2350,3222
       ,
268949,3402,3493,133973,1386,464219,605,2349,334123,2709
       ,
2890,267946,2773,592565,1210,2651,395863,1323,2707,265877}
;
 
static int wCurYear,wCurMonth,wCurDay;
 
static int nTheDate,nIsEnd,m,k,n,i,nBit;
 TCHAR szNongli[
30], szNongliDay[10],szShuXiang[10];
 
/*---取当前公历年、月、日---*/
 wCurYear 
= pSt->wYear;
 wCurMonth 
= pSt->wMonth;
 wCurDay 
= pSt->wDay;
 
/*---计算到初始时间1921年2月8日的天数:1921-2-8(正月初一)---*/
 nTheDate 
= (wCurYear - 1921* 365 + (wCurYear - 1921/ 4 + wCurDay + wMonthAdd[wCurMonth - 1- 38;
 
if((!(wCurYear % 4)) && (wCurMonth > 2))
  nTheDate 
= nTheDate + 1;

 
/*--计算农历天干、地支、月、日---*/
 nIsEnd 
= 0;
 m 
= 0;
 
while(nIsEnd != 1)
 
{
  
if(wNongliData[m] < 4095)
   k 
= 11;
  
else
   k 
= 12;
  n 
= k;
  
while(n>=0)
  
{
   
//获取wNongliData(m)的第n个二进制位的值
   nBit = wNongliData[m];
   
for(i=1;i<n+1;i++)
    nBit 
= nBit/2;

   nBit 
= nBit % 2;

   
if (nTheDate <= (29 + nBit))
   
{
    nIsEnd 
= 1;
    
break;
   }


   nTheDate 
= nTheDate - 29 - nBit;
   n 
= n - 1;
  }

  
if(nIsEnd)
   
break;
  m 
= m + 1;
 }

 wCurYear 
= 1921 + m;
 wCurMonth 
= k - n + 1;
 wCurDay 
= nTheDate;
 
if (k == 12)
 
{
  
if (wCurMonth == wNongliData[m] / 65536 + 1)
   wCurMonth 
= 1 - wCurMonth;
  
else if (wCurMonth > wNongliData[m] / 65536 + 1)
   wCurMonth 
= wCurMonth - 1;
 }


 
/*--生成农历天干、地支、属相 ==> wNongli--*/
 wsprintf(szShuXiang,
"%s",cShuXiang[((wCurYear - 4% 60% 12]);
 wsprintf(szNongli,
"%s(%s%s)年",szShuXiang,cTianGan[((wCurYear - 4% 60% 10],cDiZhi[((wCurYear - 4% 60% 12]);

 
/*--生成农历月、日 ==> wNongliDay--*/
 
if (wCurMonth < 1)
  wsprintf(szNongliDay,
"闰%s",cMonName[-1 * wCurMonth]);
 
else
  strcpy(szNongliDay,cMonName[wCurMonth]);

 strcat(szNongliDay,
"");
 strcat(szNongliDay,cDayName[wCurDay]);
 
return strcat(szNongli,szNongliDay);

}

 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一段51单片机公历转农历的C语言代码,希望对你有帮助: ```c #include <reg51.h> #include <intrins.h> /* 定义公历结构体 */ typedef struct { unsigned char year; // 公历年份 unsigned char month; // 公历月份 unsigned char day; // 公历日 } solar_calendar; /* 定义农历结构体 */ typedef struct { unsigned char year; // 农历年份 unsigned char month; // 农历月份 unsigned char day; // 农历日 unsigned char isLeap; // 是否为闰月 } lunar_calendar; /* 定义公历和农历转换用到的数组 */ const unsigned char solar_month_days[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; const unsigned char lunar_month_days[12] = {0x4d,0x37,0x29,0x4a,0x36,0x2a,0x54,0x39,0x2d,0x5a,0x3e,0x2e}; /* 定义农历节日数组 */ const char * lunar_festivals[] = { "春节", "元宵节", "清明节", "端午节", "七夕节", "中秋节", "重阳节", "腊八节", "小年", "除夕" }; /* 定义公历节日数组 */ const char * solar_festivals[] = { "元旦", "情人节", "妇女节", "植树节", "愚人节", "劳动节", "青年节", "儿童节", "建党节", "建军节", "教师节", "国庆节", "万圣节", "光棍节", "感恩节", "圣诞节" }; /* 公历转农历函数 */ void solar_to_lunar(solar_calendar solar, lunar_calendar * lunar) { unsigned char i, leap, temp; unsigned short offset; /* 计算离公元年1月1日的天数 */ offset = (solar.year - 1921) * 365 + (solar.year - 1921) / 4 + solar.day - 38; if ((solar.year % 4 == 0) && (solar.month > 2)) { offset++; } /* 计算农历年份 */ for (i = 1921; i <= 2100 && offset > 0; i++) { temp = lunar_month_days[(i - 1921)]; if (leap > 0 && i == (leap + 1921)) { /* 如果是闰月,需要加上闰月的天数 */ if ((offset - temp) < 0) { break; } offset -= temp; temp = ((temp & 0x80) == 0) ? 29 : 30; } /* 减去该年的天数 */ offset -= temp; /* 如果已经减到0或者减完了,说明找到了农历年份 */ if (offset <= 0) { offset += temp; lunar->year = i; break; } /* 如果是闰月,需要记录闰月的月份 */ if (leap == 0 && (temp & 0x80) != 0) { leap = i - 1921; } } /* 计算农历月份和日 */ lunar->month = 1; for (i = 1; i <= 12 && offset > 0; i++) { temp = lunar_month_days[lunar->month - 1]; if (leap > 0 && i == (leap + 1) && lunar->month < 13) { /* 如果是闰月,需要加上闰月的天数 */ if ((offset - temp) < 0) { break; } offset -= temp; temp = ((temp & 0x80) == 0) ? 29 : 30; } /* 减去该月的天数 */ offset -= temp; /* 如果已经减到0或者减完了,说明找到了农历月份 */ if (offset <= 0) { offset += temp; /* 如果是闰月,需要特殊处理 */ if (leap > 0 && i > (leap + 1)) { lunar->month = i - 1; } else { lunar->month = i; } break; } } lunar->day = offset; /* 如果是闰月,需要标记一下 */ if (leap > 0 && lunar->month == (leap + 1)) { lunar->isLeap = 1; } else { lunar->isLeap = 0; } } /* 主函数 */ void main(void) { unsigned char i; solar_calendar solar = {2021, 1, 1}; // 公历2021年1月1日 lunar_calendar lunar; solar_to_lunar(solar, &lunar); printf("公历:%d年%d月%d日\n", solar.year, solar.month, solar.day); if (lunar.isLeap) { printf("农历:%d年闰%d月%d日\n", lunar.year, lunar.month, lunar.day); } else { printf("农历:%d年%d月%d日\n", lunar.year, lunar.month, lunar.day); } /* 判断是否是农历节日 */ for (i = 0; i < 10; i++) { if (lunar.month == i + 1 && lunar.day == lunar_month_days[i]) { printf("农历节日:%s\n", lunar_festivals[i]); break; } } /* 判断是否是公历节日 */ for (i = 0; i < 16; i++) { if (solar.month == i + 1 && solar.day == solar_month_days[i]) { printf("公历节日:%s\n", solar_festivals[i]); break; } } while (1); } ``` 需要注意的是,该代码只是一个简单的示例,可能存在一些限制和不足之处,如果需要更加完善的农历转公历算法,需要考虑更多的细节和特殊情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值