麦步社区-论坛

标题: 公历转换农历的函数代码for麦步 [打印本页]

作者: dscao    时间: 2016-1-18 01:26
标题: 公历转换农历的函数代码for麦步
本帖最后由 dscao 于 2016-1-18 13:58 编辑

公历转换农历的函数代码,来源于网络上的。但如果直接copy,手表的os对有些函数或参数不支持,造成安装后消失的情况。可能这点也阻碍其它同学未完成此代码的原因,我采用一行一行加入测试的方法,所以耗费了相当多的时间,才找到问题的具体代码行,再替换相应的代码来解决的。
代码如下,应该还有很大的优化空间。
  1. /*------------农历转换函数-----------*/
  2. char *DayToNL(int year, int month,int day)
  3. {
  4. /*天干名称*/
  5. char cTianGan[10][4] = {"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};
  6. /*地支名称*/
  7. char cDiZhi[12][4] = {"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};
  8. /*属相名称*/
  9. char cShuXiang[12][4] = {"鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"};
  10. /*农历日期名*/
  11. char cDayName[31][8] = {"*","初一","初二","初三","初四","初五",
  12.        "初六","初七","初八","初九","初十",
  13.        "十一","十二","十三","十四","十五",
  14.        "十六","十七","十八","十九","二十",
  15.        "廿一","廿二","廿三","廿四","廿五",
  16.        "廿六","廿七","廿八","廿九","三十"};
  17. /*农历月份名*/
  18. char cMonName[13][4] = {"*","正","二","三","四","五","六","七","八","九","十","冬","腊"};
  19. /*公历每月前面的天数*/
  20. int wMonthAdd[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
  21. /*农历数据——1921至2020年有效,这一块我没搞懂怎么算出来的,想加上2021-2050年的数据但没加上,或者只要2016-2020年的数据,但没完全懂没敢删除前面的。算法的理解上对农历月日方面没太理解过来,主要是润月、大月、小月问题*/
  22. int wNongliData[100] =
  23.         {2635,333387,1701,1748,267701,694,2391,133423,1175,396438
  24.            ,3402,3749,331177,1453,694,201326,2350,465197,3221,3402
  25.            ,400202,2901,1386,267611,605,2349,137515,2709,464533,1738
  26.            ,2901,330421,1242,2651,199255,1323,529706,3733,1706,398762
  27.            ,2741,1206,267438,2647,1318,204070,3477,461653,1386,2413
  28.            ,330077,1197,2637,268877,3365,531109,2900,2922,398042,2395
  29.            ,1179,267415,2635,661067,1701,1748,398772,2742,2391,330031
  30.            ,1175,1611,200010,3749,527717,1452,2742,332397,2350,3222
  31.            ,268949,3402,3493,133973,1386,464219,605,2349,334123,2709
  32.            ,2890,267946,2773,592565,1210,2651,395863,1323,2707,265877};
  33. int wCurYear,wCurMonth,wCurDay;
  34. int nTheDate,nIsEnd,m,k,n,i,nBit;

  35. /*char *szNongli = malloc(24); 原来用这个的可行,后来说怕耖尽内存改为下一句。*/
复制代码
  1. /*接上面,网站这里代码段可能是长度限制,全部放一起就被截断了。*/
  2. static char szNongli[24] = "";
复制代码
发现一句被截断的,想补上来。结果一提交,这一句上去了,一大段又被截掉了。再接一块。
  1. char szNongliDay[10] = "";
  2. char szShuXiang[10] = "";
  3. /*---取当前公历年、月、日---*/
  4. wCurYear = year;
  5. wCurMonth = month;
  6. wCurDay = day;
  7. /*---计算到初始时间1921年2月8日的天数:1921-2-8(正月初一)---*/
  8. nTheDate = (wCurYear - 1921) * 365 + (wCurYear - 1921) / 4 + wCurDay + wMonthAdd[wCurMonth - 1] - 38;
  9. if((!(wCurYear % 4)) && (wCurMonth > 2))
  10.   nTheDate = nTheDate + 1;
  11. /*--计算农历天干、地支、月、日---*/
  12. nIsEnd = 0;
  13. m = 0;
  14. while(nIsEnd != 1)
  15. {
  16.   if(wNongliData[m] < 4095)
  17.    k = 11;
  18.   else
  19.    k = 12;
  20.   n = k;
  21.   while(n>=0)
  22.   {
  23.    //获取wNongliData(m)的第n个二进制位的值
  24.    nBit = wNongliData[m];
  25.    for(i=1;i<n+1;i++)
  26.     nBit = nBit/2;
  27.    nBit = nBit % 2;
  28.    if (nTheDate <= (29 + nBit))
  29.    {
  30.     nIsEnd = 1;
  31.     break;
  32.    }
  33.    nTheDate = nTheDate - 29 - nBit;
  34.    n = n - 1;
  35.   }
  36.   if(nIsEnd)
  37.    break;
  38.   m = m + 1;
  39. }
  40. wCurYear = 1921 + m;
  41. wCurMonth = k - n + 1;
  42. wCurDay = nTheDate;
  43. if (k == 12)
  44. {
  45.   if (wCurMonth == wNongliData[m] / 65536 + 1)
  46.    wCurMonth = 1 - wCurMonth;
  47.   else if (wCurMonth > wNongliData[m] / 65536 + 1)
  48.    wCurMonth = wCurMonth - 1;
  49. }
  50. /*--生成农历年天干、地支、属相 ==> wNongli--*/
  51. sprintf(szShuXiang,"%s",cShuXiang[((wCurYear - 4) % 60) % 12]);
  52. sprintf(szNongli,"%s(%s%s)年",szShuXiang,cTianGan[((wCurYear - 4) % 60) % 10],cDiZhi[((wCurYear - 4) % 60) % 12]);
  53. /*--生成农历月、日 ==> wNongliDay--*/
  54. if (wCurMonth < 1)
  55.   sprintf(szNongliDay,"闰%s",cMonName[-1 * wCurMonth]);
  56. else
  57. strcpy(szNongliDay,cMonName[wCurMonth]);
  58. sprintf(szNongli,"%s%s月%s" ,szNongli,szNongliDay, cDayName[wCurDay]);  //可修改成不同形式输出。

  59. return szNongli;
  60. }
复制代码


调用方法:DayToNL(t.year, t.mon,t.mday)
示例:
  1. struct date_time t;
  2. app_service_get_datetime(&t);
复制代码
  1. /*添加农历图层*/
  2.         GRect frame_nlday = {{MWD_NLDAY_ORIGIN_X, MWD_NLDAY_ORIGIN_Y}, {MWD_NLDAY_SIZE_H, MWD_NLDAY_SIZE_W}};
  3.         LayerText lt_nlday = { DayToNL(t.year, t.mon,t.mday), frame_nlday, GAlignCenter, U_GBK_SIMSUN_12, 0};
  4.         P_Layer layer_text_nlday = app_layer_create_text(<_nlday);
  5.         if(layer_text_nlday != NULL)
  6.         {
  7.                 app_layer_set_bg_color(layer_text_nlday, GColorBlack);        
  8.                 g_app_mwd_nlday_layer_id = app_window_add_layer(p_window, layer_text_nlday);
  9.         }
复制代码

农历这一段编译后占用的大小可能有5~6KB。这里抛砖引玉,希望有同学能做一些优化或改进。或者也有另外思路的更好实现方法。
希望麦步手表功能越来越强大,有更多实用的表盘或应用出现。

感谢支持.txt.rar (10 Bytes, 下载次数: 10, 售价: 1 麦力) 附件无内容






作者: dscao    时间: 2016-1-18 01:32
本帖最后由 dscao 于 2016-1-18 01:44 编辑

农历代码发布了 @Zola
网站上代码发布也有点麻烦,老是被截断,只好分段放。

作者: sure    时间: 2016-1-18 09:06
感谢分享 喊人来抄袭折腾了!!
作者: 陶坤@麦步    时间: 2016-1-18 10:30
技术贴,支持一下
就是考虑只增加一年的数据,可以精简表盘大小,是不是更合适一些
作者: jccg    时间: 2016-1-19 15:35
感谢分享。。。刚稍微改了一下试了试,确实好用。。。可以删除前面已经过去的年份数据,能减少一下内存占用。。。


//改下面三个地方就行了,大概测试了一下,不知道有没有问题
//把15年之前的都删掉了
int wNongliData[10] =
        {1210,2651,395863,1323,2707,265877};


/*---计算到初始时间2015-2-18的天数:2015-2-18((正月初一),2015-2-18(正月初一)---*/
nTheDate = (wCurYear - 2015) * 365 + (wCurYear - 2015) / 4 + wCurDay + wMonthAdd[wCurMonth - 1] - 49;


wCurYear = 2015 + m;


作者: 陶坤@麦步    时间: 2016-1-19 15:47
jccg 发表于 2016-1-19 15:35
感谢分享。。。刚稍微改了一下试了试,确实好用。。。可以删除前面已经过去的年份数据,能减少一下内存占用 ...

新人?

期待你的应用或者表盘...
作者: dscao    时间: 2016-1-19 17:46
本帖最后由 dscao 于 2016-1-19 18:12 编辑
jccg 发表于 2016-1-19 15:35
感谢分享。。。刚稍微改了一下试了试,确实好用。。。可以删除前面已经过去的年份数据,能减少一下内存占用 ...
很好!实测安装文件缩小了0.36KB。(原10.51KB的变成了10.15KB)

作者: achen    时间: 2016-1-23 12:27
支持一下!!!
作者: mark    时间: 2016-1-23 18:28
点赞。

作者: gylgb    时间: 2016-6-5 09:00
很是羡慕。。




欢迎光临 麦步社区-论坛 (http://bbs.maibu.cc/) Powered by Discuz! X3.2