/** * Lunar calendar 博大精深的農曆
* 原始資料和演算法思路來自 S&S
Lab http://www.focus-2000.com 可惜網站好像關了
*/
/*
農曆每個月的天數。
每個元素為一年。每個元素中的數據為:
[0]是閏月在哪個月,0為無閏月;
[1]到[13]是每年12或13個月的每月天數;
[14]是當年的天乾次序,
[15]是當年的地支次序
*/
-
- function lunarcalendar ($month, $year)
- {
- global $lnlunarcalendar;
- * Lunar calendar 博大精深的農曆
- * 原始資料和演算法思路來自 S&S
- Lab http://www.focus-2000.com 可惜網站好像關了
- */
- /*
- 農曆每個月的天數。
- 每個元素為一年。每個元素中的數據為:
- [0]是閏月在哪個月,0為無閏月;
- [1]到[13]是每年12或13個月的每月天數;
- [14]是當年的天干次序,
- [15]是當年的地支次序
- */
- $everymonth = array(
- 0 => array(8, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 29, 30, 7, 1),
- 1 => array(0, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 0, 8, 2),
- 2 => array(0, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 00 , 9, 3),
- 3 => array(5, 29, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 10, 4),
- 4 => array(0, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 0, 1, 5),
- 5 => array(0, 30, 30, 29, 30, 30, 29, 29, 30, 29, 30, 29, 30, 0, 2, 6),
- 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),
- 7 => array(0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 4, 8),
- 8 => array(0, 30, 29, 29, 30, 30, 29, 30, 29, 30, 30, 29, 30, 0, 5, 9 ),
- 9 => array(2, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 30, 6, 10),
- 10 = 29, 30, 6, 10),
- 10 = array> (0, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 0, 7, 11),
- 11 => array(6, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 8, 12),
- 12 => array(0, 30, 29, 30, 29, 29, 30, 29, 2929 , 30, 30, 29, 30, 0, 9, 1),
- 13 => array(0, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 0, 10, 2),
- 14 => array(5, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 29, 30, 1, 3),
- 15 => array(0, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 0, 2, 4),
- 16 => array(0, 29 , 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 3, 5),
- 17 => array(2, 30, 29, 29, 30, 299, 30, 30, 29, 30, 30, 29, 30, 29, 4, 6),
- 18 => array(0, 30, 29, 29, 30, 29, 30, 29, 30, 30, 32930, 329 , 30, 30, 0, 5, 7),
- 19 => array(7, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 30, 6, 8),
- 20 => array(0, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 0, 7, 9),
- 21 => array(0, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 0, 8, 10),
- 22 => array(5, 30, 29, 30 , 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 9, 11),
- 23 => array(0, 29, 30, 30, 29, 300, 29, 300, 33, 300, 29, 29, 30, 29, 30, 0, 10, 12),
- 24 => array(0, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 2929 , 0, 1, 1),
- 25 => array(4, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 2, 2),
- 26 => array(0, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 3, 3),
- 27 => array(0,0, 30, 29, 29, 30, 29, 30, 29, 30, 29, 30, 30, 30, 0, 4, 4),
- 28 => array(2, 29, 30, 290 29, 330 , 29, 29, 30, 29, 30, 30, 30, 30, 5, 5),
- 29 => array(0, 29, 30, 29, 29, 30, 29, 29, 30, 2929 30, 30, 30, 0, 6, 6),
- 30 => array(6, 29, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 7 , 7),
- 31 => array(0, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 0, 8, 8),
- 32 = > array(0, 30, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 0, 9, 9),
- 33 => array(5, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 29, 30, 10, 10),
- 34 => array(0, 29, 30, 29, 30, 30, 29, 30, 29 , 29, 30, 30, 29, 30, 0, 1, 11),
- 35 => array(0, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 230 29, 0, 2, 12),
- 36 => array(3, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 30, 29, 3, 1),
- 37 => array(0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 29, 0, 4, 2),
- 38 => array(77 , 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 5, 3),
- 39 => array(0, 30, 30, 2, 229 30, 29, 29, 30, 29, 30, 29, 30, 0, 6, 4),
- 40 => array(0, 30, 30, 29, 30, 29, 30, 290 29, 330 , 29, 30, 29, 0, 7, 5),
- 41 => array(6, 30, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 8, 6),
- 42 => array(0, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 0, 9, 7),
- 43 => array(0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 10, 8),
- 44 => array(4, 30, 29 , 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 1, 9),
- 45 => array(0, 29, 29, 30, 29, 29, 330, 30, 290, 29, 330 29, 30, 30, 30, 29, 30, 0, 2, 10),
- 46 => array(0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, , 30, 0, 3, 11),
- 47 => array(2, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 4, 12) ,
- 48 => array(0, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 0, 5, 1),
- 49 => array( 7, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 6, 2),
- 50 => array(0, 29, 3029 , 30, 30, 29, 29, 30, 29, 30, 29, 0, 7, 3),
- 51 => array(0, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 0, 8, 4),
- 52 => array(5, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 300, 29, 300 , 9, 5),
- 53 => array(0, 29, 30, 29, 29, 30, 30, 29, 30, 30, 29, 30, 29, 0, 10, 6),
- 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),
- 56 =>陣列(0, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 0, 3, 9),
- 57 =>陣列(8, 30, 29, 30, 29, 30, 2929 , 29, 30, 29, 30, 29, 30, 29, 4, 10),
- 58 =>陣列(0, 30, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 0, 5, 11),
- 59 =>陣列(0, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 0, 6, 12 ),
- 60 =>陣列(6, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 7, 1),
- 61 =>陣列(0, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 0, 8, 2),
- 62 =>陣列(0, 29, 30, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 9, 3),
- 63 =>陣列(4, 30, 29, 30, 29, 29, 30, 29, 300 , 29, 30, 30, 30, 29, 10, 4),
- 64 =>陣列(0, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 0, 1, 5),
- 65 =>陣列(0, 29, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 0, 2, 6),
- 66 =>陣列(3, 30, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 3, 7),
- 67 =>陣列(0, 30 , 30, 29, 30, 30, 29, 29, 30, 29, 30, 29, 30, 0, 4, 8),
- 68 =>陣列(7, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 5, 9),
- 69 =>陣列(0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 229 , 30, 29, 0, 6, 10),
- 70 =>陣列(0, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 0, 7, 11),
- 71 =>陣列(5, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 30, 8, 12),
- 72 = =陣列(0, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 0, 9, 1),
- 73 =>陣列(0, 30, 29, 30 , 29, 29, 30, 29, 29, 30, 30, 29, 30, 0, 10, 2),
- 74 =>陣列(4, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 1, 3),
- 75 =>陣列(0, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30 , 0, 2, 4),
- 76 =>陣列(8, 30, 30, 29, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 3, 5),
- 77 =>陣列(0, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 29, 0, 4, 6),
- 78 =>陣列(0, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 5, 7),
- 79 =>數位(6, 30, 29, 29, 30, 2929 , 30, 30, 29, 30, 30, 29, 30, 29, 6, 8),
- 80 =>陣列(0, 30, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 0, 7, 9),
- 81 =>陣列(0, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 0, 8 , 10),
- 82 =>陣列(4, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 9, 11),
- 83 = >陣列(0, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 0, 10, 12),
- 84 =>陣列(10, 30, 29, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 1, 1),
- 85 =>陣列(0, 29, 30, 30, 29, 30, 29, 30 , 29, 29, 30, 29, 30, 0, 2, 2),
- 86 =>陣列(0, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 29, 0, 3, 3),
- 87 =>陣列(6, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 29, 4, 4),
- 88 =>陣列(0, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 5, 5),
- 89 =>陣列(0 , 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 30, 0, 6, 6),
- 90 =>陣列(5, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 30, 7, 7),
- 91 =>陣列(0, 29, 30, 29, 29, 30, 29, 29, 30, 2929 , 30, 30, 30, 0, 8, 8),
- 92 =>陣列(0, 29, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 0, 9, 9),
- 93 =>陣列(3, 29, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 10, 10),
- 499 =>陣列(0, 30, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 0, 1, 11),
- 95 =>陣列(8, 29, 30 , 30, 29, 30, 29, 30, 30, 29, 29, 30, 29, 30, 2, 12),
- 96 =>陣列(0, 29, 30, 29, 30, 30, 3029, 29, 30,29 30, 29, 30, 30, 29, 29, 0, 3, 1),
- 97 =>陣列(0, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 330 , 29, 0, 4, 2),
- 98 =>陣列(5, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 29, 30, 5, 3) ,
- 99 =>陣列(0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 29, 0, 6, 4),
- 100 =>陣列( 0, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 0, 7, 5),
- 101 =>陣列(4, 30, 30, 29, 330 , 29, 30, 29, 29, 30, 29, 30, 29, 30, 8, 6),
- 102 =>陣列(0, 30, 30, 29, 30, 29, 3029, 30,29, 3029, 30, 29, 30, 29, 0, 9, 7),
- 103 =>陣列(0, 30, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 00 , 10, 8),
- 104 =>陣列(2, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 1, 9),
- 105 =>陣列(0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 2, 10),
- 106 =>陣列(7, 30, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 3, 11),
- 107 =>陣列(0, 29, 29, 30, 29, 29, 29, 30, 29, 29, 29 , 29, 30, 30, 30, 29, 30, 0, 4, 12),
- 108 =>陣列(0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 230, 29, 30, 0, 5, 1),
- 109 =>陣列(5, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 29, 30, 32 ),
- 110 =>陣列(0, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 0, 7, 3),
- 111 => 陣列(0, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 0, 8, 4),
- 112 => array(4, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 9, 5),
- 113 => array(0, 300, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 0, 10, 6),
- 114 => array(9, 29, 30, 29, 30, 29 , 29, 30, 30, 29, 30, 29, 30, 1, 7),
- 115 => array(0, 29, 30, 29, 29, 30, 29, 30, 309, 30, 309, 30, 309, 30, 29, 22 30, 29, 0, 2, 8),
- 116 => array(0, 30, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 0, 3, 9 ),
- 117 => array(6, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 4, 10),
- 118 => array18 => (0, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 0, 5, 11),
- 119 => array(0, 30, 29, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 0, 6, 12),
- 120 => array(4, 29, 30, 30, 30, 29, 30, 29, 2929 , 30, 29, 30, 29, 30, 7, 1)
- );
-
- $mten = $lnlunarcalendar['tiangan'];// 農曆天乾
- $lnm 'dizhi'];// 農曆地支
- $mmonth = $lnlunarcalendar['month'];// 農曆月份
- $mday = $lnlunarcalendar['day'];// 農曆日
- //陽曆總天數至1900年12月21日
- $total = 69 * 365 + 17 + 11;
- //1970年1月1日前的就不算了
- if ($year == " " || $month == "" || ($year 2020)) return ''; //超出這個範圍不計算
- // 計算到所求日期陽曆的總天數-自1900年12月21日始
-
- for ($y = 1970; $y $total += 365;
- if ($y % 4 == 0) $total ++;
- }
- // 再加當年的幾個月
- $total += gmdate("z", gmmktime(0, 0, 0 , $month, 1, $year));
- // 用農曆的天數累加來判斷是否超過陽曆的天數
- $flag1 = 0; //判斷跳出循環的條件
- $lcj = 0 ;
- while ($lcj $lci = 1;
- while ($lci $mtotal += $everymonth[$lcj][$lci] ;
- if ($mtotal >= $total) {
- $flag1 = 1;
- break;
- }
- $lci++;
- }
- if ($flag1 == 1) break;
- $lcj++;
- }
- // 由上,得到的$lci 為當前農曆月, $lcj 為當前農曆年
- // 計算所求月份1號的農曆日期
- $fisrtdaylunar = $everymonth[$lcj][$lci] - ($mtotal - $total);
- $results['year'] = $mten[$everymonth[$lcj][14]] . $mtwelve[$everymonth[$lcj][15]]; //目前是什麼年
- $daysthismonth = gmdate("t", gmmktime(0, 0, 0, $month, 1, $year)) ; //當月共幾天
- $op = 1;
- for ($i = 1; $i $possiblelunarday = $fisrtdaylunar + $op-1 ; //理論上疊加後的農曆日
- if ($possiblelunarday $results[$i] = $mday[$possiblelunarday];
- $op += 1;
- }
- else { // 不在本月的天數範疇內
- $results[$i] = $mday[1]; //退到1日
- $fisrtdaylunar = 1;
- $op = 2;
- $curmonthnum = ($everymonth[$lcj][0] != 0) ? 13 : 12; //當年有幾個月
- if ($lci + 1 > $curmonthnum) { // 第13/14個月了,轉到下一年
- $lci = 1;
- $lcj = $lcj + 1;
- // 換年頭了,把新一年的天干地支也寫上
- $results['year'] .= '/' . $mten[$everymonth[$lcj][14]] . $mtwelve[$everymonth[$lcj][15]];
- }
- else { // 還在這年裡
- $lci = $lci + 1;
- $lcj = $lcj ;
- }
- }
- if ($results[$i] == $mday[1]) { // 每個月的初一應該顯示當月是什麼月
- if ($everymonth[ $lcj][0] != 0) { // 有閏月的年
- $monthss = ($lci > $everymonth[$lcj][0]) ? ($lci-1) : $lci; //閏月後的月數-1
- if ($lci == $everymonth[$lcj][0] + 1) { // 這個月正好是閏月
- $monthssshow = $mmonth[0] . $mmonth [$monthss]; //前面加上閏字
- $runyue = 1;
- }
- else {
- $monthssshow = $mmonth[$monthss];
- }
- } }
- else {
- $monthss = $lci;
- $monthssshow = $mmonth[$monthss];
- }
- if ($monthss $monthssshow .= $mmonth[13];
- }
- $results[$i] = $monthssshow;
- }
- }
- return $results;
- }
- // 忘了加上這個:農曆用字
- $lnlunarcalendar = array(
- 'tiangan' => array("未知", "甲", "乙", "C", "丁", "戊", "自己", "庚", "辛", "壬", "癸"),
- 'dizhi' => array("未知", "子年(鼠)", "醜年(牛)", "寅年(虎)", "卯年(兔)", "辰年(龍)",
- "巳年(蛇)", "午年(馬)", "未年(羊)", "申年(猴)", "酉年(雞)", "戌年(狗)", "亥年(豬)"),
- 'month' => array("閏", "正", "二", "三", "四", "五", "六",
- "七", "八", "九", "十", "十一" , "十二", "月"),
- 'day' => array("未知", "初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十",
- "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十",
- "廿一", "廿二", "廿三", "廿四" , "廿五", "廿六", "廿七", "廿八", "廿九", "三十")
- );
-
複製程式碼
|