首頁  >  文章  >  後端開發  >  博大精深的 農曆演算法

博大精深的 農曆演算法

WBOY
WBOY原創
2016-07-25 09:07:591050瀏覽
/** * 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. * Lunar calendar 博大精深的農曆
  5. * 原始資料和演算法思路來自 S&S
  6. Lab http://www.focus-2000.com 可惜網站好像關了
  7. */
  8. /*
  9. 農曆每個月的天數。
  10. 每個元素為一年。每個元素中的數據為:
  11. [0]是閏月在哪個月,0為無閏月;
  12. [1]到[13]是每年12或13個月的每月天數;
  13. [14]是當年的天干次序,
  14. [15]是當年的地支次序
  15. */
  16. $everymonth = array(
  17. 0 => array(8, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 29, 30, 7, 1),
  18. 1 => array(0, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 0, 8, 2),
  19. 2 => array(0, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 00 , 9, 3),
  20. 3 => array(5, 29, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 10, 4),
  21. 4 => array(0, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 0, 1, 5),
  22. 5 => array(0, 30, 30, 29, 30, 30, 29, 29, 30, 29, 30, 29, 30, 0, 2, 6),
  23. 6 => array(4, 29, 30, 30, 29, 30, array(4, 29, 30, 30, 29, 30, 229 , 30, 29, 30, 29, 30, 29, 30, 3, 7),
  24. 7 => array(0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 4, 8),
  25. 8 => array(0, 30, 29, 29, 30, 30, 29, 30, 29, 30, 30, 29, 30, 0, 5, 9 ),
  26. 9 => array(2, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 30, 6, 10),
  27. 10 = 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, 2929 , 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, 299, 30, 30, 29, 30, 30, 29, 30, 29, 4, 6),
  36. 18 => array(0, 30, 29, 29, 30, 29, 30, 29, 30, 30, 32930, 329 , 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, 300, 29, 300, 33, 300, 29, 29, 30, 29, 30, 0, 10, 12),
  42. 24 => array(0, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 2929 , 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,0, 30, 29, 29, 30, 29, 30, 29, 30, 29, 30, 30, 30, 0, 4, 4),
  46. 28 => array(2, 29, 30, 290 29, 330 , 29, 29, 30, 29, 30, 30, 30, 30, 5, 5),
  47. 29 => array(0, 29, 30, 29, 29, 30, 29, 29, 30, 2929 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 , 29, 30, 30, 29, 30, 0, 1, 11),
  53. 35 => array(0, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 230 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(77 , 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 5, 3),
  57. 39 => array(0, 30, 30, 2, 229 30, 29, 29, 30, 29, 30, 29, 30, 0, 6, 4),
  58. 40 => array(0, 30, 30, 29, 30, 29, 30, 290 29, 330 , 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, 330, 30, 290, 29, 330 29, 30, 30, 30, 29, 30, 0, 2, 10),
  64. 46 => array(0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, , 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, 3029 , 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, 300, 29, 300 , 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), 55 =>陣列(3, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 2, 8),
  73. 56 =>陣列(0, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 0, 3, 9),
  74. 57 =>陣列(8, 30, 29, 30, 29, 30, 2929 , 29, 30, 29, 30, 29, 30, 29, 4, 10),
  75. 58 =>陣列(0, 30, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 0, 5, 11),
  76. 59 =>陣列(0, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 0, 6, 12 ),
  77. 60 =>陣列(6, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 7, 1),
  78. 61 =>陣列(0, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 0, 8, 2),
  79. 62 =>陣列(0, 29, 30, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 9, 3),
  80. 63 =>陣列(4, 30, 29, 30, 29, 29, 30, 29, 300 , 29, 30, 30, 30, 29, 10, 4),
  81. 64 =>陣列(0, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 0, 1, 5),
  82. 65 =>陣列(0, 29, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 0, 2, 6),
  83. 66 =>陣列(3, 30, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 3, 7),
  84. 67 =>陣列(0, 30 , 30, 29, 30, 30, 29, 29, 30, 29, 30, 29, 30, 0, 4, 8),
  85. 68 =>陣列(7, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 5, 9),
  86. 69 =>陣列(0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 229 , 30, 29, 0, 6, 10),
  87. 70 =>陣列(0, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 0, 7, 11),
  88. 71 =>陣列(5, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 30, 8, 12),
  89. 72 = =陣列(0, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 0, 9, 1),
  90. 73 =>陣列(0, 30, 29, 30 , 29, 29, 30, 29, 29, 30, 30, 29, 30, 0, 10, 2),
  91. 74 =>陣列(4, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 1, 3),
  92. 75 =>陣列(0, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30 , 0, 2, 4),
  93. 76 =>陣列(8, 30, 30, 29, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 3, 5),
  94. 77 =>陣列(0, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 29, 0, 4, 6),
  95. 78 =>陣列(0, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 5, 7),
  96. 79 =>數位(6, 30, 29, 29, 30, 2929 , 30, 30, 29, 30, 30, 29, 30, 29, 6, 8),
  97. 80 =>陣列(0, 30, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 0, 7, 9),
  98. 81 =>陣列(0, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 0, 8 , 10),
  99. 82 =>陣列(4, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 9, 11),
  100. 83 = >陣列(0, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 0, 10, 12),
  101. 84 =>陣列(10, 30, 29, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 1, 1),
  102. 85 =>陣列(0, 29, 30, 30, 29, 30, 29, 30 , 29, 29, 30, 29, 30, 0, 2, 2),
  103. 86 =>陣列(0, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 29, 0, 3, 3),
  104. 87 =>陣列(6, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 29, 4, 4),
  105. 88 =>陣列(0, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 5, 5),
  106. 89 =>陣列(0 , 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 30, 0, 6, 6),
  107. 90 =>陣列(5, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 30, 7, 7),
  108. 91 =>陣列(0, 29, 30, 29, 29, 30, 29, 29, 30, 2929 , 30, 30, 30, 0, 8, 8),
  109. 92 =>陣列(0, 29, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 0, 9, 9),
  110. 93 =>陣列(3, 29, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 10, 10),
  111. 499 =>陣列(0, 30, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 0, 1, 11),
  112. 95 =>陣列(8, 29, 30 , 30, 29, 30, 29, 30, 30, 29, 29, 30, 29, 30, 2, 12),
  113. 96 =>陣列(0, 29, 30, 29, 30, 30, 3029, 29, 30,29 30, 29, 30, 30, 29, 29, 0, 3, 1),
  114. 97 =>陣列(0, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 330 , 29, 0, 4, 2),
  115. 98 =>陣列(5, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 29, 30, 5, 3) ,
  116. 99 =>陣列(0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 29, 0, 6, 4),
  117. 100 =>陣列( 0, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 0, 7, 5),
  118. 101 =>陣列(4, 30, 30, 29, 330 , 29, 30, 29, 29, 30, 29, 30, 29, 30, 8, 6),
  119. 102 =>陣列(0, 30, 30, 29, 30, 29, 3029, 30,29, 3029, 30, 29, 30, 29, 0, 9, 7),
  120. 103 =>陣列(0, 30, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 00 , 10, 8),
  121. 104 =>陣列(2, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 1, 9),
  122. 105 =>陣列(0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 2, 10),
  123. 106 =>陣列(7, 30, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 3, 11),
  124. 107 =>陣列(0, 29, 29, 30, 29, 29, 29, 30, 29, 29, 29 , 29, 30, 30, 30, 29, 30, 0, 4, 12),
  125. 108 =>陣列(0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 230, 29, 30, 0, 5, 1),
  126. 109 =>陣列(5, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 29, 30, 32 ),
  127. 110 =>陣列(0, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 0, 7, 3),
  128. 111 => 陣列(0, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 0, 8, 4),
  129. 112 => array(4, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 9, 5),
  130. 113 => array(0, 300, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 0, 10, 6),
  131. 114 => array(9, 29, 30, 29, 30, 29 , 29, 30, 30, 29, 30, 29, 30, 1, 7),
  132. 115 => array(0, 29, 30, 29, 29, 30, 29, 30, 309, 30, 309, 30, 309, 30, 29, 22 30, 29, 0, 2, 8),
  133. 116 => array(0, 30, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 0, 3, 9 ),
  134. 117 => array(6, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 4, 10),
  135. 118 => array18 => (0, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 0, 5, 11),
  136. 119 => array(0, 30, 29, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 0, 6, 12),
  137. 120 => array(4, 29, 30, 30, 30, 29, 30, 29, 2929 , 30, 29, 30, 29, 30, 7, 1)
  138. );
  139. $mten = $lnlunarcalendar['tiangan'];// 農曆天乾
  140. $lnm 'dizhi'];// 農曆地支
  141. $mmonth = $lnlunarcalendar['month'];// 農曆月份
  142. $mday = $lnlunarcalendar['day'];// 農曆日
  143. //陽曆總天數至1900年12月21日
  144. $total = 69 * 365 + 17 + 11;
  145. //1970年1月1日前的就不算了
  146. if ($year == " " || $month == "" || ($year 2020)) return ''; //超出這個範圍不計算
  147. // 計算到所求日期陽曆的總天數-自1900年12月21日始
  148. for ($y = 1970; $y $total += 365;
  149. if ($y % 4 == 0) $total ++;
  150. }
  151. // 再加當年的幾個月
  152. $total += gmdate("z", gmmktime(0, 0, 0 , $month, 1, $year));
  153. // 用農曆的天數累加來判斷是否超過陽曆的天數
  154. $flag1 = 0; //判斷跳出循環的條件
  155. $lcj = 0 ;
  156. while ($lcj $lci = 1;
  157. while ($lci $mtotal += $everymonth[$lcj][$lci] ;
  158. if ($mtotal >= $total) {
  159. $flag1 = 1;
  160. break;
  161. }
  162. $lci++;
  163. }
  164. if ($flag1 == 1) break;
  165. $lcj++;
  166. }
  167. // 由上,得到的$lci 為當前農曆月, $lcj 為當前農曆年
  168. // 計算所求月份1號的農曆日期
  169. $fisrtdaylunar = $everymonth[$lcj][$lci] - ($mtotal - $total);
  170. $results['year'] = $mten[$everymonth[$lcj][14]] . $mtwelve[$everymonth[$lcj][15]]; //目前是什麼年
  171. $daysthismonth = gmdate("t", gmmktime(0, 0, 0, $month, 1, $year)) ; //當月共幾天
  172. $op = 1;
  173. for ($i = 1; $i $possiblelunarday = $fisrtdaylunar + $op-1 ; //理論上疊加後的農曆日
  174. if ($possiblelunarday $results[$i] = $mday[$possiblelunarday];
  175. $op += 1;
  176. }
  177. else { // 不在本月的天數範疇內
  178. $results[$i] = $mday[1]; //退到1日
  179. $fisrtdaylunar = 1;
  180. $op = 2;
  181. $curmonthnum = ($everymonth[$lcj][0] != 0) ? 13 : 12; //當年有幾個月
  182. if ($lci + 1 > $curmonthnum) { // 第13/14個月了,轉到下一年
  183. $lci = 1;
  184. $lcj = $lcj + 1;
  185. // 換年頭了,把新一年的天干地支也寫上
  186. $results['year'] .= '/' . $mten[$everymonth[$lcj][14]] . $mtwelve[$everymonth[$lcj][15]];
  187. }
  188. else { // 還在這年裡
  189. $lci = $lci + 1;
  190. $lcj = $lcj ;
  191. }
  192. }
  193. if ($results[$i] == $mday[1]) { // 每個月的初一應該顯示當月是什麼月
  194. if ($everymonth[ $lcj][0] != 0) { // 有閏月的年
  195. $monthss = ($lci > $everymonth[$lcj][0]) ? ($lci-1) : $lci; //閏月後的月數-1
  196. if ($lci == $everymonth[$lcj][0] + 1) { // 這個月正好是閏月
  197. $monthssshow = $mmonth[0] . $mmonth [$monthss]; //前面加上閏字
  198. $runyue = 1;
  199. }
  200. else {
  201. $monthssshow = $mmonth[$monthss];
  202. }
  203. } }
  204. else {
  205. $monthss = $lci;
  206. $monthssshow = $mmonth[$monthss];
  207. }
  208. if ($monthss $monthssshow .= $mmonth[13];
  209. }
  210. $results[$i] = $monthssshow;
  211. }
  212. }
  213. return $results;
  214. }
  215. // 忘了加上這個:農曆用字
  216. $lnlunarcalendar = array(
  217. 'tiangan' => array("未知", "甲", "乙", "C", "丁", "戊", "自己", "庚", "辛", "壬", "癸"),
  218. 'dizhi' => array("未知", "子年(鼠)", "醜年(牛)", "寅年(虎)", "卯年(兔)", "辰年(龍)",
  219. "巳年(蛇)", "午年(馬)", "未年(羊)", "申年(猴)", "酉年(雞)", "戌年(狗)", "亥年(豬)"),
  220. 'month' => array("閏", "正", "二", "三", "四", "五", "六",
  221. "七", "八", "九", "十", "十一" , "十二", "月"),
  222. 'day' => array("未知", "初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十",
  223. "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十",
  224. "廿一", "廿二", "廿三", "廿四" , "廿五", "廿六", "廿七", "廿八", "廿九", "三十")
  225. );
複製程式碼


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:LZW壓縮演算法下一篇:LZW壓縮演算法