返回官网官方微博

麦步社区-论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
热搜: MAI 表盘
查看: 6758|回复: 9
打印 上一主题 下一主题

公历转换农历的函数代码for麦步

[复制链接]

8

主题

53

帖子

405

麦力

精华
1
阅读权限
100
在线时间
44 小时

麦步极客实验室

跳转到指定楼层
楼主
发表于 2016-1-18 01:26:20 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
本帖最后由 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 麦力) 附件无内容





评分

参与人数 1麦力 +5 收起 理由
陶坤@麦步 + 5 开放源码,赞一个

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信 WeiboWeibo
收藏收藏 分享分享 顶16 踩

7

主题

107

帖子

1020

麦力

精华
0
阅读权限
100
在线时间
24 小时

麦步工业测评协会

10#
发表于 2016-6-5 09:00:02 | 只看该作者
很是羡慕。。
回复

使用道具 举报

3

主题

118

帖子

1223

麦力

精华
1
阅读权限
150
在线时间
59 小时
9#
发表于 2016-1-23 18:28:52 | 只看该作者
点赞。
回复

使用道具 举报

3

主题

13

帖子

0

麦力

精华
0
阅读权限
20
在线时间
8 小时

8#
发表于 2016-1-23 12:27:52 | 只看该作者
支持一下!!!
回复

使用道具 举报

8

主题

53

帖子

405

麦力

精华
1
阅读权限
100
在线时间
44 小时

麦步极客实验室

7#
 楼主| 发表于 2016-1-19 17:46:55 来自手机 | 只看该作者
本帖最后由 dscao 于 2016-1-19 18:12 编辑
jccg 发表于 2016-1-19 15:35
感谢分享。。。刚稍微改了一下试了试,确实好用。。。可以删除前面已经过去的年份数据,能减少一下内存占用 ...
很好!实测安装文件缩小了0.36KB。(原10.51KB的变成了10.15KB)

来自: 微社区

48

主题

670

帖子

3384

麦力

精华
0
阅读权限
200
在线时间
745 小时
6#
发表于 2016-1-19 15:47:00 | 只看该作者
jccg 发表于 2016-1-19 15:35
感谢分享。。。刚稍微改了一下试了试,确实好用。。。可以删除前面已经过去的年份数据,能减少一下内存占用 ...

新人?

期待你的应用或者表盘...
发帖内容均来自麦步智能手表自动触发,不接受抄水表、送快递、送温暖等任何形式的关怀

0

主题

5

帖子

0

麦力

精华
0
阅读权限
20
在线时间
27 小时

5#
发表于 2016-1-19 15:35:51 | 只看该作者
感谢分享。。。刚稍微改了一下试了试,确实好用。。。可以删除前面已经过去的年份数据,能减少一下内存占用。。。


//改下面三个地方就行了,大概测试了一下,不知道有没有问题
//把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;

48

主题

670

帖子

3384

麦力

精华
0
阅读权限
200
在线时间
745 小时
地板
发表于 2016-1-18 10:30:36 | 只看该作者
技术贴,支持一下
就是考虑只增加一年的数据,可以精简表盘大小,是不是更合适一些
发帖内容均来自麦步智能手表自动触发,不接受抄水表、送快递、送温暖等任何形式的关怀

14

主题

1494

帖子

9854

麦力

精华
1
阅读权限
100
在线时间
622 小时

麦步手表用户麦步工业测评协会

板凳
发表于 2016-1-18 09:06:37 | 只看该作者
感谢分享 喊人来抄袭折腾了!!

8

主题

53

帖子

405

麦力

精华
1
阅读权限
100
在线时间
44 小时

麦步极客实验室

沙发
 楼主| 发表于 2016-1-18 01:32:25 | 只看该作者
本帖最后由 dscao 于 2016-1-18 01:44 编辑

农历代码发布了 @Zola
网站上代码发布也有点麻烦,老是被截断,只好分段放。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|麦步官方论坛 ( 粤ICP备12052190号  

GMT+8, 2024-12-4 03:20 , Processed in 0.100110 second(s), 33 queries .

Powered by Discuz! X3.2

© 2012-2021 Comsenz Inc.

快速回复 返回顶部 返回列表