请问有没有计算农历的函数

能计算出农历月日的
  1. [本篇全文] [回复本文] [本篇作者: top ] [本篇人气: 10]
  2. 发信人: top (英语六级&&PHP), 信区: Programming
  3. 标  题: 阴阳历算法
  4. 发信站: 燕赵 BBS (Tue Apr  8 12:14:16 2003), 转信


  5. [url]http://linux.tcpip.com.cn[/url]

  6. 阴阳历算法
  7. 发言者:kent 发言时间:2001-11-08 12:03:11

  8. 程序为:

  9. /*

  10. prototype: int calconv( struct convdate * );

  11. struct convdate
  12. {
  13. int source; ==0 则输入日期为西历, !=0 则输入为农历
  14. int solaryear; 输出或输入之西历年份
  15. int solarmonth; 西历月
  16. int solardate; 西历日
  17. int lunaryear; 输出或输入之农历年份
  18. int lunarmonth; 农历月
  19. int lunarmonth; 农历月
  20. int lunardate; 农历日
  21. int weekday; 该日为星期几 ( 0==星期日, 1==星期一, ... )
  22. int kan; 该日天干 ( 0==甲, 1==乙, ..., 9==癸 )
  23. int chih; 该日地支 ( 0==子, 1==丑, ..., 11==亥 )
  24. };

  25. 呼叫时须设定 souce 的值, 若为 0 则为西历转农历, 否则为农历转西历. 然後视

  26. 输入为西历或农历来设定西历或农历的年月日. 转换後的年月日会填入结构中( 农

  27. 历或西历 ), 以及该日为星期几, 天干地支.
  28. 若函式的返回值为 0 表示没有错误, 1 为输入之年份错误, 2 为输入之月份错误
  29. ,
  30. 3 为输入之日期错误.
  31. 输入之西历年须在 1937 - 2031 间
  32. 输入之农历年须在 1936 - 2030 间
  33. 若须扩充, 则增加 lunarcal[]

  34. */

  35. #define firstyear 1936 /* the first year in lunarcal[] */

  36. struct convdate
  37. {
  38. int source;
  39. int source;
  40. int solaryear;
  41. int solarmonth;
  42. int solardate;
  43. int lunaryear;
  44. int lunarmonth;
  45. int lunardate;
  46. int weekday;
  47. int kan;
  48. int chih;
  49. };

  50. struct taglunarcal
  51. {
  52. int basedays; /* 到西历 1 月 1 日到农历正月初一的累积日数 */
  53. int intercalation; /* 闰月月份. 0==此年没有闰月 */
  54. int baseweekday; /* 此年西历 1 月 1 日为星期几再减 1 */
  55. int basekanchih; /* 此年西历 1 月 1 日之干支序号减 1 */
  56. int monthdays[13]; /* 此农历年每月之大小, 0==小月(29日), 1==大月(30日
  57. )*/
  58. };

  59. struct taglunarcal lunarcal[] = {
  60. { 23, 3, 2, 17, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 }, /* 1936 */
  61. { 23, 3, 2, 17, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 }, /* 1936 */
  62. { 41, 0, 4, 23, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1 },
  63. { 30, 7, 5, 28, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 },
  64. { 49, 0, 6, 33, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
  65. { 38, 0, 0, 38, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, /* 1940 */
  66. { 26, 6, 2, 44, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
  67. { 45, 0, 3, 49, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
  68. { 35, 0, 4, 54, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
  69. { 24, 4, 5, 59, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 1944 */
  70. { 43, 0, 0, 5, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 },
  71. { 32, 0, 1, 10, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 },
  72. { 21, 2, 2, 15, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
  73. { 40, 0, 3, 20, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }, /* 1948 */
  74. { 28, 7, 5, 26, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
  75. { 47, 0, 6, 31, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1 },
  76. { 36, 0, 0, 36, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
  77. { 26, 5, 1, 41, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 }, /* 1952 */
  78. { 44, 0, 3, 47, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1 },
  79. { 33, 0, 4, 52, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 },
  80. { 23, 3, 5, 57, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 },
  81. { 42, 0, 6, 2, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 }, /* 1956 */
  82. { 30, 8, 1, 8, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
  83. { 48, 0, 2, 13, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
  84. { 48, 0, 2, 13, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
  85. { 38, 0, 3, 18, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
  86. { 27, 6, 4, 23, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 }, /* 1960 */
  87. { 45, 0, 6, 29, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 },
  88. { 35, 0, 0, 34, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
  89. { 24, 4, 1, 39, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 },
  90. { 43, 0, 2, 44, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 }, /* 1964 */
  91. { 32, 0, 4, 50, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 },
  92. { 20, 3, 5, 55, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 },
  93. { 39, 0, 6, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
  94. { 29, 7, 0, 5, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, /* 1968 */
  95. { 47, 0, 2, 11, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
  96. { 36, 0, 3, 16, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 },
  97. { 26, 5, 4, 21, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1 },
  98. { 45, 0, 5, 26, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 1972 */
  99. { 33, 0, 0, 32, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1 },
  100. { 22, 4, 1, 37, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 },
  101. { 41, 0, 2, 42, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 },
  102. { 30, 8, 3, 47, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 }, /* 1976 */
  103. { 48, 0, 5, 53, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1 },
  104. { 37, 0, 6, 58, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
  105. { 27, 6, 0, 3, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 },
  106. { 46, 0, 1, 8, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, /* 1980 */
  107. { 46, 0, 1, 8, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, /* 1980 */
  108. { 35, 0, 3, 14, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1 },
  109. { 24, 4, 4, 19, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
  110. { 43, 0, 5, 24, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
  111. { 32, 10, 6, 29, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 }, /* 1984 */
  112. { 50, 0, 1, 35, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
  113. { 39, 0, 2, 40, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1 },
  114. { 28, 6, 3, 45, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0 },
  115. { 47, 0, 4, 50, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, /* 1988 */
  116. { 36, 0, 6, 56, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 },
  117. { 26, 5, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1 },
  118. { 45, 0, 1, 6, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0 },
  119. { 34, 0, 2, 11, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0 }, /* 1992 */
  120. { 22, 3, 4, 17, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
  121. { 40, 0, 5, 22, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
  122. { 30, 8, 6, 27, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1 },
  123. { 49, 0, 0, 32, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1 }, /* 1996 */
  124. { 37, 0, 2, 38, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
  125. { 27, 5, 3, 43, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1 },
  126. { 46, 0, 4, 48, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1 },
  127. { 35, 0, 5, 53, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 }, /* 2000 */
  128. { 23, 4, 0, 59, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
  129. { 42, 0, 1, 4, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
  130. { 42, 0, 1, 4, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
  131. { 31, 0, 2, 9, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
  132. { 21, 2, 3, 14, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, /* 2004 */
  133. { 39, 0, 5, 20, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
  134. { 28, 7, 6, 25, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 },
  135. { 48, 0, 0, 30, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 },
  136. { 37, 0, 1, 35, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 2008 */
  137. { 25, 5, 3, 41, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
  138. { 44, 0, 4, 46, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
  139. { 33, 0, 5, 51, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
  140. { 22, 4, 6, 56, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }, /* 2012 */
  141. { 40, 0, 1, 2, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
  142. { 30, 9, 2, 7, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 },
  143. { 49, 0, 3, 12, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 },
  144. { 38, 0, 4, 17, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, /* 2016 */
  145. { 27, 6, 6, 23, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 },
  146. { 46, 0, 0, 28, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0 },
  147. { 35, 0, 1, 33, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 },
  148. { 24, 4, 2, 38, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, /* 2020 */
  149. { 42, 0, 4, 44, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
  150. { 31, 0, 5, 49, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 },
  151. { 21, 2, 6, 54, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 },
  152. { 40, 0, 0, 59, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, /* 2024 */
  153. { 40, 0, 0, 59, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, /* 2024 */
  154. { 28, 6, 2, 5, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 },
  155. { 47, 0, 3, 10, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1 },
  156. { 36, 0, 4, 15, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 },
  157. { 25, 5, 5, 20, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 }, /* 2028 */
  158. { 43, 0, 0, 26, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 },
  159. { 32, 0, 1, 31, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0 },
  160. { 22, 3, 2, 36, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 } };

  161. #define lastyear (firstyear+sizeof(lunarcal)/sizeof(struct
  162. taglunarcal)-1)

  163. /* 西历年每月之日数 */
  164. int solarcal[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

  165. /* 西历年每月之累积日数, 平年与闰年 */
  166. int solardays[2][14] = {
  167. { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 396 },
  168. { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366, 397 } };

  169. /* 求此西历年是否为闰年, 返回 0 为平年, 1 为闰年 */
  170. int getleap( int year )
  171. {
  172. if ( year % 400 == 0 )
  173. if ( year % 400 == 0 )
  174. return 1;
  175. else if ( year % 100 == 0 )
  176. return 0;
  177. else if ( year % 4 == 0 )
  178. return 1;
  179. else
  180. return 0;
  181. }

  182. /* 西历农历转换 */
  183. int calconv( struct convdate *cd )
  184. {
  185. int leap, d, sm, y, im, l1, l2, acc, i, lm, kc;
  186. if ( cd->source == 0 ) /* solar */
  187. {
  188. if ( cd->solaryear <= firstyear || cd->solaryear > lastyear )
  189. return 1;
  190. sm = cd->solarmonth - 1;
  191. if ( sm < 0 || sm > 11 )
  192. return 2;
  193. leap = getleap( cd->solaryear );
  194. if ( sm == 1 )
  195. if ( sm == 1 )
  196. d = leap + 28;
  197. else
  198. d = solarcal[sm];
  199. if ( cd->solardate < 1 || cd->solardate > d )
  200. return 3;
  201. y = cd->solaryear - firstyear;
  202. acc = solardays[leap][sm] + cd->solardate;
  203. cd->weekday = ( acc + lunarcal[y].baseweekday ) % 7;
  204. kc = acc + lunarcal[y].basekanchih;
  205. cd->kan = kc % 10;
  206. cd->chih = kc % 12;
  207. if ( acc <= lunarcal[y].basedays )
  208. {
  209. y--;
  210. cd->lunaryear = cd->solaryear - 1;
  211. leap = getleap( cd->lunaryear );
  212. sm += 12;
  213. acc = solardays[leap][sm] + cd->solardate;
  214. }
  215. else
  216. cd->lunaryear = cd->solaryear;
  217. l1 = lunarcal[y].basedays;
  218. l1 = lunarcal[y].basedays;
  219. for ( i=0; i<13; i++ )
  220. {
  221. l2 = l1 + lunarcal[y].monthdays[i] + 29;
  222. if ( acc <= l2 )
  223. break;
  224. l1 = l2;
  225. }
  226. cd->lunarmonth = i + 1;
  227. cd->lunardate = acc - l1;
  228. im = lunarcal[y].intercalation;
  229. if ( im != 0 && cd->lunarmonth > im )
  230. {
  231. cd->lunarmonth--;
  232. if ( cd->lunarmonth == im )
  233. cd->lunarmonth = -im;
  234. }
  235. if ( cd->lunarmonth > 12 )
  236. cd->lunarmonth -= 12;
  237. }
  238. else /* lunar */
  239. {
  240. if ( cd->lunaryear < firstyear || cd->lunaryear >= lastyear )
  241. if ( cd->lunaryear < firstyear || cd->lunaryear >= lastyear )
  242. return 1;
  243. y = cd->lunaryear - firstyear;
  244. im = lunarcal[y].intercalation;
  245. lm = cd->lunarmonth;
  246. if ( lm < 0 )
  247. {
  248. if ( lm != -im )
  249. return 2;
  250. }
  251. else if ( lm < 1 || lm > 12 )
  252. return 2;
  253. if ( im != 0 )
  254. {
  255. if ( lm > im )
  256. lm++;
  257. else if ( lm == -im )
  258. lm = im + 1;
  259. }
  260. lm--;
  261. if ( cd->lunardate > lunarcal[y].monthdays[lm] + 29 )
  262. return 3;
  263. acc = lunarcal[y].basedays;
  264. acc = lunarcal[y].basedays;
  265. for ( i=0; i acc += lunarcal[y].monthdays[i] + 29;
  266. acc += cd->lunardate;
  267. leap = getleap( cd->lunaryear );
  268. for ( i=13; i>=0; i-- )
  269. if ( acc > solardays[leap][i] )
  270. break;
  271. cd->solardate = acc - solardays[leap][i];
  272. if ( i <= 11 )
  273. {
  274. cd->solaryear = cd->lunaryear;
  275. cd->solarmonth = i + 1;
  276. }
  277. else
  278. {
  279. cd->solaryear = cd->lunaryear + 1;
  280. cd->solarmonth = i - 11;
  281. }
  282. leap = getleap( cd->solaryear );
  283. y = cd->solaryear - firstyear;
  284. acc = solardays[leap][cd->solarmonth-1] + cd->solardate;
  285. cd->weekday = ( acc + lunarcal[y].baseweekday ) % 7;
  286. kc = acc + lunarcal[y].basekanchih;
  287. {
  288. cd->kan = kc % 10;
  289. cd->chih = kc % 12;
  290. }
  291. return 0;
  292. }


  293. 摘自:中华技术网
  294. 作者:黄晓鸣
复制代码
万分感谢!
Cougar网站@银河双子星→http://www.sbysky.com
这是什么语言?
楼上的大哥,我想要一个你的日历的原程序,请发到我邮箱里好吗?
8411p@163.com
谢谢
最初由 moocky 发布
[B]看看我写的
http://www.moocky.com/rili.php [/B]
我也需要学习一下,可否发给我一份,谢谢
thbhy@163.net:blowzy:
我也想一份,多谢~
free@zj165.com
最初由 moocky 发布
[B]看看我写的
http://www.moocky.com/rili.php [/B]
很不错啊....
可以贴出来共享一下吗?