当前位置:Gxlcms > PHP教程 > 博大精深的农历算法

博大精深的农历算法

时间:2021-07-01 10:21:17 帮助过:43人阅读

/** * Lunar calendar 博大精深的农历 * 原始数据和算法思路来自 S&S Lab http://www.focus-2000.com 可惜网站好像关了 */ /* 农历每月的天数。 每个元素为一年。每个元素中的数据为: [0]是闰月在哪个月,0为无闰月; [1]到[13]是每年12或13个月的每月天数; [14]是当年的天干次序, [15]是当年的地支次序 */
  1. function lunarcalendar ($month, $year)
  2. {
  3. global $lnlunarcalendar;
  4. /**
  5. * Lunar calendar 博大精深的农历
  6. * 原始数据和算法思路来自 S&S
  7. Lab http://www.focus-2000.com 可惜网站好像关了
  8. */
  9. /*
  10. 农历每月的天数。
  11. 每个元素为一年。每个元素中的数据为:
  12. [0]是闰月在哪个月,0为无闰月;
  13. [1]到[13]是每年12或13个月的每月天数;
  14. [14]是当年的天干次序,
  15. [15]是当年的地支次序
  16. */
  17. $everymonth = array(
  18. 0 => array(8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 7, 1),
  19. 1 => array(0, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 0, 8, 2),
  20. 2 => array(0, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 0, 9, 3),
  21. 3 => array(5, 29, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 10, 4),
  22. 4 => array(0, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 0, 1, 5),
  23. 5 => array(0, 30, 30, 29, 30, 30, 29, 29, 30, 29, 30, 29, 30, 0, 2, 6),
  24. 6 => array(4, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 3, 7),
  25. 7 => array(0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 4, 8),
  26. 8 => array(0, 30, 29, 29, 30, 30, 29, 30, 29, 30, 30, 29, 30, 0, 5, 9),
  27. 9 => array(2, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 30, 6, 10),
  28. 10 => array(0, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 0, 7, 11),
  29. 11 => array(6, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 8, 12),
  30. 12 => array(0, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 0, 9, 1),
  31. 13 => array(0, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 0, 10, 2),
  32. 14 => array(5, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 29, 30, 1, 3),
  33. 15 => array(0, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 0, 2, 4),
  34. 16 => array(0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 3, 5),
  35. 17 => array(2, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 4, 6),
  36. 18 => array(0, 30, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 0, 5, 7),
  37. 19 => array(7, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 30, 6, 8),
  38. 20 => array(0, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 0, 7, 9),
  39. 21 => array(0, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 0, 8, 10),
  40. 22 => array(5, 30, 29, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 9, 11),
  41. 23 => array(0, 29, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 0, 10, 12),
  42. 24 => array(0, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 29, 0, 1, 1),
  43. 25 => array(4, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 2, 2),
  44. 26 => array(0, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 3, 3),
  45. 27 => array(0, 30, 29, 29, 30, 29, 30, 29, 30, 29, 30, 30, 30, 0, 4, 4),
  46. 28 => array(2, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 30, 5, 5),
  47. 29 => array(0, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 0, 6, 6),
  48. 30 => array(6, 29, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 7, 7),
  49. 31 => array(0, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 0, 8, 8),
  50. 32 => array(0, 30, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 0, 9, 9),
  51. 33 => array(5, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 29, 30, 10, 10),
  52. 34 => array(0, 29, 30, 29, 30, 30, 29, 30, 29, 30, 30, 29, 30, 0, 1, 11),
  53. 35 => array(0, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 2, 12),
  54. 36 => array(3, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 30, 29, 3, 1),
  55. 37 => array(0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 29, 0, 4, 2),
  56. 38 => array(7, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 5, 3),
  57. 39 => array(0, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 29, 30, 0, 6, 4),
  58. 40 => array(0, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 0, 7, 5),
  59. 41 => array(6, 30, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 8, 6),
  60. 42 => array(0, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 0, 9, 7),
  61. 43 => array(0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 10, 8),
  62. 44 => array(4, 30, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 1, 9),
  63. 45 => array(0, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 29, 30, 0, 2, 10),
  64. 46 => array(0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 0, 3, 11),
  65. 47 => array(2, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 4, 12),
  66. 48 => array(0, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 0, 5, 1),
  67. 49 => array(7, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 6, 2),
  68. 50 => array(0, 29, 30, 30, 29, 30, 30, 29, 29, 30, 29, 30, 29, 0, 7, 3),
  69. 51 => array(0, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 0, 8, 4),
  70. 52 => array(5, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 9, 5),
  71. 53 => array(0, 29, 30, 29, 29, 30, 30, 29, 30, 30, 29, 30, 29, 0, 10, 6),
  72. 54 => array(0, 30, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 0, 1, 7),
  73. 55 => array(3, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 2, 8),
  74. 56 => array(0, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 0, 3, 9),
  75. 57 => array(8, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 29, 4, 10),
  76. 58 => array(0, 30, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 0, 5, 11),
  77. 59 => array(0, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 0, 6, 12),
  78. 60 => array(6, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 7, 1),
  79. 61 => array(0, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 0, 8, 2),
  80. 62 => array(0, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 9, 3),
  81. 63 => array(4, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 10, 4),
  82. 64 => array(0, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 0, 1, 5),
  83. 65 => array(0, 29, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 0, 2, 6),
  84. 66 => array(3, 30, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 3, 7),
  85. 67 => array(0, 30, 30, 29, 30, 30, 29, 29, 30, 29, 30, 29, 30, 0, 4, 8),
  86. 68 => array(7, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 5, 9),
  87. 69 => array(0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 6, 10),
  88. 70 => array(0, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 0, 7, 11),
  89. 71 => array(5, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 30, 8, 12),
  90. 72 => array(0, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 0, 9, 1),
  91. 73 => array(0, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 0, 10, 2),
  92. 74 => array(4, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 1, 3),
  93. 75 => array(0, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 0, 2, 4),
  94. 76 => array(8, 30, 30, 29, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 3, 5),
  95. 77 => array(0, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 29, 0, 4, 6),
  96. 78 => array(0, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 5, 7),
  97. 79 => array(6, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 6, 8),
  98. 80 => array(0, 30, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 0, 7, 9),
  99. 81 => array(0, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 0, 8, 10),
  100. 82 => array(4, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 9, 11),
  101. 83 => array(0, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 0, 10, 12),
  102. 84 => array(10, 30, 29, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 1, 1),
  103. 85 => array(0, 29, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 0, 2, 2),
  104. 86 => array(0, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 29, 0, 3, 3),
  105. 87 => array(6, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 29, 4, 4),
  106. 88 => array(0, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 5, 5),
  107. 89 => array(0, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 30, 0, 6, 6),
  108. 90 => array(5, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 30, 7, 7),
  109. 91 => array(0, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 0, 8, 8),
  110. 92 => array(0, 29, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 0, 9, 9),
  111. 93 => array(3, 29, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 10, 10),
  112. 94 => array(0, 30, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 0, 1, 11),
  113. 95 => array(8, 29, 30, 30, 29, 30, 29, 30, 30, 29, 29, 30, 29, 30, 2, 12),
  114. 96 => array(0, 29, 30, 29, 30, 30, 29, 30, 29, 30, 30, 29, 29, 0, 3, 1),
  115. 97 => array(0, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 4, 2),
  116. 98 => array(5, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 29, 30, 5, 3),
  117. 99 => array(0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 29, 0, 6, 4),
  118. 100 => array(0, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 0, 7, 5),
  119. 101 => array(4, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 8, 6),
  120. 102 => array(0, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 0, 9, 7),
  121. 103 => array(0, 30, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 0, 10, 8),
  122. 104 => array(2, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 1, 9),
  123. 105 => array(0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 2, 10),
  124. 106 => array(7, 30, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 3, 11),
  125. 107 => array(0, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 29, 30, 0, 4, 12),
  126. 108 => array(0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 0, 5, 1),
  127. 109 => array(5, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 6, 2),
  128. 110 => array(0, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 0, 7, 3),
  129. 111 => array(0, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 0, 8, 4),
  130. 112 => array(4, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 9, 5),
  131. 113 => array(0, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 0, 10, 6),
  132. 114 => array(9, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 1, 7),
  133. 115 => array(0, 29, 30, 29, 29, 30, 29, 30, 30, 30, 29, 30, 29, 0, 2, 8),
  134. 116 => array(0, 30, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 0, 3, 9),
  135. 117 => array(6, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 4, 10),
  136. 118 => array(0, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 0, 5, 11),
  137. 119 => array(0, 30, 29, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 0, 6, 12),
  138. 120 => array(4, 29, 30, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 7, 1)
  139. );
  140. $mten = $lnlunarcalendar['tiangan'];// 农历天干
  141. $mtwelve = $lnlunarcalendar['dizhi'];// 农历地支
  142. $mmonth = $lnlunarcalendar['month'];// 农历月份
  143. $mday = $lnlunarcalendar['day'];// 农历日
  144. // 阳历总天数 至1900年12月21日
  145. $total = 69 * 365 + 17 + 11;
  146. //1970年1月1日前的就不算了
  147. if ($year == "" || $month == "" || ($year < 1970 or $year > 2020)) return ''; //超出这个范围不计算
  148. // 计算到所求日期阳历的总天数-自1900年12月21日始
  149. for ($y = 1970; $y < $year;$y++) {// 先算年的和
  150. $total += 365;
  151. if ($y % 4 == 0) $total ++;
  152. }
  153. // 再加当年的几个月
  154. $total += gmdate("z", gmmktime(0, 0, 0, $month, 1, $year));
  155. // 用农历的天数累加来判断是否超过阳历的天数
  156. $flag1 = 0; //判断跳出循环的条件
  157. $lcj = 0;
  158. while ($lcj <= 120) {
  159. $lci = 1;
  160. while ($lci <= 13) {
  161. $mtotal += $everymonth[$lcj][$lci];
  162. if ($mtotal >= $total) {
  163. $flag1 = 1;
  164. break;
  165. }
  166. $lci++;
  167. }
  168. if ($flag1 == 1) break;
  169. $lcj++;
  170. }
  171. // 由上,得到的 $lci 为当前农历月, $lcj 为当前农历年
  172. // 计算所求月份1号的农历日期
  173. $fisrtdaylunar = $everymonth[$lcj][$lci] - ($mtotal - $total);
  174. $results['year'] = $mten[$everymonth[$lcj][14]] . $mtwelve[$everymonth[$lcj][15]]; //当前是什么年
  175. $daysthismonth = gmdate("t", gmmktime(0, 0, 0, $month, 1, $year)); //当前月共几天
  176. $op = 1;
  177. for ($i = 1; $i <= $daysthismonth; $i++) {
  178. $possiblelunarday = $fisrtdaylunar + $op-1; //理论上叠加后的农历日
  179. if ($possiblelunarday <= $everymonth[$lcj][$lci]) { // 在本月的天数范畴内
  180. $results[$i] = $mday[$possiblelunarday];
  181. $op += 1;
  182. }
  183. else { // 不在本月的天数范畴内
  184. $results[$i] = $mday[1]; //退回到1日
  185. $fisrtdaylunar = 1;
  186. $op = 2;
  187. $curmonthnum = ($everymonth[$lcj][0] != 0) ? 13 : 12; //当年有几个月
  188. if ($lci + 1 > $curmonthnum) { // 第13/14个月了,转到下一年
  189. $lci = 1;
  190. $lcj = $lcj + 1;
  191. // 换年头了,把新一年的天干地支也写上
  192. $results['year'] .= '/' . $mten[$everymonth[$lcj][14]] . $mtwelve[$everymonth[$lcj][15]];
  193. }
  194. else { // 还在这年里
  195. $lci = $lci + 1;
  196. $lcj = $lcj;
  197. }
  198. }
  199. if ($results[$i] == $mday[1]) { // 每月的初一应该显示当月是什么月
  200. if ($everymonth[$lcj][0] != 0) { // 有闰月的年
  201. $monthss = ($lci > $everymonth[$lcj][0]) ? ($lci-1) : $lci; //闰月后的月数-1
  202. if ($lci == $everymonth[$lcj][0] + 1) { // 这个月正好是闰月
  203. $monthssshow = $mmonth[0] . $mmonth[$monthss]; //前面加个闰字
  204. $runyue = 1;
  205. }
  206. else {
  207. $monthssshow = $mmonth[$monthss];
  208. }
  209. }
  210. else {
  211. $monthss = $lci;
  212. $monthssshow = $mmonth[$monthss];
  213. }
  214. if ($monthss <= 10 && $runyue != 1){ //只有1个字的月加上‘月’字
  215. $monthssshow .= $mmonth[13];
  216. }
  217. $results[$i] = $monthssshow;
  218. }
  219. }
  220. return $results;
  221. }
  222. // 忘了加上这个:农历用字
  223. $lnlunarcalendar = array(
  224. 'tiangan' => array("未知", "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"),
  225. 'dizhi' => array("未知", "子年(鼠)", "丑年(牛)", "寅年(虎)", "卯年(兔)", "辰年(龙)",
  226. "巳年(蛇)", "午年(马)", "未年(羊)", "申年(猴)", "酉年(鸡)", "戌年(狗)", "亥年(猪)"),
  227. 'month' => array("闰", "正", "二", "三", "四", "五", "六",
  228. "七", "八", "九", "十", "十一", "十二", "月"),
  229. 'day' => array("未知", "初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十",
  230. "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十",
  231. "廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十")
  232. );

人气教程排行