具体如下:
001 | <?php |
002 | function lunarcalendar ( $month , $year ) |
003 | { |
004 | global $lnlunarcalendar ; |
005 | /** |
006 | * Lunar calendar 博大精深的农历 |
007 | * 原始数据和算法思路来自 S&S |
008 | */ |
009 | /* |
010 | 农历每月的天数。 |
011 | 每个元素为一年。每个元素中的数据为: |
012 | [0]是闰月在哪个月,0为无闰月; |
013 | [1]到[13]是每年12或13个月的每月天数; |
014 | [14]是当年的天干次序, |
015 | [15]是当年的地支次序 |
016 | */ $everymonth = array ( |
017 | 0 => array (8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 7, 1), |
018 | 1 => array (0, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 0, 8, 2), |
019 | 2 => array (0, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 0, 9, 3), 3 => array (5, 29, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 10, 4), |
020 | 4 => array (0, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 0, 1, 5), |
021 | 5 => array (0, 30, 30, 29, 30, 30, 29, 29, 30, 29, 30, 29, 30, 0, 2, 6), |
022 | 6 => array (4, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 3, 7), |
023 | 7 => array (0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 4, 8), |
024 | 8 => array (0, 30, 29, 29, 30, 30, 29, 30, 29, 30, 30, 29, 30, 0, 5, 9), |
025 | 9 => array (2, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 30, 6, 10), |
026 | 10 => array (0, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 0, 7, 11), |
027 | 11 => array (6, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 8, 12), |
028 | 12 => array (0, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 0, 9, 1), |
029 | 13 => array (0, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 0, 10, 2), |
030 | 14 => array (5, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 29, 30, 1, 3), |
031 | 15 => array (0, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 0, 2, 4), |
032 | 16 => array (0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 3, 5), |
033 | 17 => array (2, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 4, 6), |
034 | 18 => array (0, 30, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 0, 5, 7), |
035 | 19 => array (7, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 30, 6, 8), |
036 | 20 => array (0, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 0, 7, 9), |
037 | 21 => array (0, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 0, 8, 10), |
038 | 22 => array (5, 30, 29, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 9, 11), |
039 | 23 => array (0, 29, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 0, 10, 12), |
040 | 24 => array (0, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 29, 0, 1, 1), |
041 | 25 => array (4, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 2, 2), |
042 | 26 => array (0, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 3, 3), |
043 | 27 => array (0, 30, 29, 29, 30, 29, 30, 29, 30, 29, 30, 30, 30, 0, 4, 4), |
044 | 28 => array (2, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 30, 5, 5), |
045 | 29 => array (0, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 0, 6, 6), |
046 | 30 => array (6, 29, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 7, 7), |
047 | 31 => array (0, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 0, 8, 8), |
048 | 32 => array (0, 30, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 0, 9, 9), |
049 | 33 => array (5, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 29, 30, 10, 10), |
050 | 34 => array (0, 29, 30, 29, 30, 30, 29, 30, 29, 30, 30, 29, 30, 0, 1, 11), |
051 | 35 => array (0, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 2, 12), |
052 | 36 => array (3, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 30, 29, 3, 1), |
053 | 37 => array (0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 29, 0, 4, 2), |
054 | 38 => array (7, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 5, 3), |
055 | 39 => array (0, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 29, 30, 0, 6, 4), |
056 | 40 => array (0, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 0, 7, 5), |
057 | 41 => array (6, 30, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 8, 6), |
058 | 42 => array (0, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 0, 9, 7), |
059 | 43 => array (0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 10, 8), |
060 | 44 => array (4, 30, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 1, 9), |
061 | 45 => array (0, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 29, 30, 0, 2, 10), |
062 | 46 => array (0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 0, 3, 11), |
063 | 47 => array (2, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 4, 12), |
064 | 48 => array (0, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 0, 5, 1), |
065 | 49 => array (7, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 6, 2), |
066 | 50 => array (0, 29, 30, 30, 29, 30, 30, 29, 29, 30, 29, 30, 29, 0, 7, 3), |
067 | 51 => array (0, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 0, 8, 4), |
068 | 52 => array (5, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 9, 5), |
069 | 53 => array (0, 29, 30, 29, 29, 30, 30, 29, 30, 30, 29, 30, 29, 0, 10, 6), |
070 | 54 => array (0, 30, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 0, 1, 7), |
071 | 55 => array (3, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 2, 8), |
072 | 56 => array (0, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 0, 3, 9), |
073 | 57 => array (8, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 29, 4, 10), |
074 | 58 => array (0, 30, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 0, 5, 11), |
075 | 59 => array (0, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 0, 6, 12), |
076 | 60 => array (6, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 7, 1), |
077 | 61 => array (0, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 0, 8, 2), |
078 | 62 => array (0, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 9, 3), |
079 | 63 => array (4, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 10, 4), |
080 | 64 => array (0, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 0, 1, 5), |
081 | 65 => array (0, 29, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 0, 2, 6), |
082 | 66 => array (3, 30, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 3, 7), |
083 | 67 => array (0, 30, 30, 29, 30, 30, 29, 29, 30, 29, 30, 29, 30, 0, 4, 8), |
084 | 68 => array (7, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 5, 9), |
085 | 69 => array (0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 6, 10), |
086 | 70 => array (0, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 0, 7, 11), |
087 | 71 => array (5, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 30, 8, 12), |
088 | 72 => array (0, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 0, 9, 1), |
089 | 73 => array (0, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 0, 10, 2), |
090 | 74 => array (4, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 1, 3), |
091 | 75 => array (0, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 0, 2, 4), |
092 | 76 => array (8, 30, 30, 29, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 3, 5), |
093 | 77 => array (0, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 29, 0, 4, 6), |
094 | 78 => array (0, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 5, 7), |
095 | 79 => array (6, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 6, 8), |
096 | 80 => array (0, 30, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 0, 7, 9), |
097 | 81 => array (0, 29, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 0, 8, 10), |
098 | 82 => array (4, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 9, 11), |
099 | 83 => array (0, 30, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 0, 10, 12), |
100 | 84 => array (10, 30, 29, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 1, 1), |
101 | 85 => array (0, 29, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 0, 2, 2), |
102 | 86 => array (0, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 29, 0, 3, 3), |
103 | 87 => array (6, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 29, 4, 4), |
104 | 88 => array (0, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 5, 5), |
105 | 89 => array (0, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 30, 0, 6, 6), |
106 | 90 => array (5, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 30, 7, 7), |
107 | 91 => array (0, 29, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 0, 8, 8), |
108 | 92 => array (0, 29, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 0, 9, 9), |
109 | 93 => array (3, 29, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 10, 10), |
110 | 94 => array (0, 30, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 0, 1, 11), |
111 | 95 => array (8, 29, 30, 30, 29, 30, 29, 30, 30, 29, 29, 30, 29, 30, 2, 12), |
112 | 96 => array (0, 29, 30, 29, 30, 30, 29, 30, 29, 30, 30, 29, 29, 0, 3, 1), |
113 | 97 => array (0, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29, 0, 4, 2), |
114 | 98 => array (5, 30, 29, 29, 30, 29, 29, 30, 30, 29, 30, 30, 29, 30, 5, 3), |
115 | 99 => array (0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 29, 0, 6, 4), |
116 | 100 => array (0, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 0, 7, 5), |
117 | 101 => array (4, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 8, 6), |
118 | 102 => array (0, 30, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 0, 9, 7), |
119 | 103 => array (0, 30, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 0, 10, 8), |
120 | 104 => array (2, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 1, 9), |
121 | 105 => array (0, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 0, 2, 10), |
122 | 106 => array (7, 30, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 3, 11), |
123 | 107 => array (0, 29, 29, 30, 29, 29, 30, 29, 30, 30, 30, 29, 30, 0, 4, 12), |
124 | 108 => array (0, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 0, 5, 1), |
125 | 109 => array (5, 30, 30, 29, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 6, 2), |
126 | 110 => array (0, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 0, 7, 3), |
127 | 111 => array (0, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 0, 8, 4), |
128 | 112 => array (4, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 9, 5), |
129 | 113 => array (0, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 0, 10, 6), |
130 | 114 => array (9, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 1, 7), |
131 | 115 => array (0, 29, 30, 29, 29, 30, 29, 30, 30, 30, 29, 30, 29, 0, 2, 8), |
132 | 116 => array (0, 30, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 0, 3, 9), |
133 | 117 => array (6, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 4, 10), |
134 | 118 => array (0, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 0, 5, 11), |
135 | 119 => array (0, 30, 29, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30, 0, 6, 12), |
136 | 120 => array (4, 29, 30, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 7, 1) |
137 | ); |
138 | $mten = $lnlunarcalendar [ 'tiangan' ]; // 农历天干 |
139 | $mtwelve = $lnlunarcalendar [ 'dizhi' ]; // 农历地支 |
140 | $mmonth = $lnlunarcalendar [ 'month' ]; // 农历月份 |
141 | $mday = $lnlunarcalendar [ 'day' ]; // 农历日 |
142 | // 阳历总天数 至1900年12月21日 |
143 | $total = 69 * 365 + 17 + 11; |
144 | //1970年1月1日前的就不算了 |
145 | if ( $year == "" || $month == "" || ( $year < 1970 or $year > 2020)) return '' ; //超出这个范围不计算 |
146 | // 计算到所求日期阳历的总天数-自1900年12月21日始 |
147 | for ( $y = 1970; $y < $year ; $y ++) { // 先算年的和 |
148 | $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 <= 120) { |
157 | $lci = 1; |
158 | while ( $lci <= 13) { |
159 | @ $mtotal += $everymonth [ $lcj ][ $lci ]; |
160 | if ( $mtotal >= $total ) { |
161 | $flag1 = 1; |
162 | break ; |
163 | } |
164 | $lci ++; |
165 | } |
166 | if ( $flag1 == 1) break ; |
167 | $lcj ++; |
168 | } |
169 | // 由上,得到的 $lci 为当前农历月, $lcj 为当前农历年 |
170 | // 计算所求月份1号的农历日期 |
171 | $fisrtdaylunar = $everymonth [ $lcj ][ $lci ] - ( $mtotal - $total ); |
172 | $results [ 'year' ] = $mten [ $everymonth [ $lcj ][14]] . $mtwelve [ $everymonth [ $lcj ][15]]; //当前是什么年 |
173 | $daysthismonth = gmdate ( "t" , gmmktime (0, 0, 0, $month , 1, $year )); //当前月共几天 |
174 | $op = 1; |
175 | for ( $i = 1; $i <= $daysthismonth ; $i ++) { |
176 | $possiblelunarday = $fisrtdaylunar + $op -1; //理论上叠加后的农历日 |
177 | if ( $possiblelunarday <= $everymonth [ $lcj ][ $lci ]) { // 在本月的天数范畴内 |
178 | $results [ $i ] = $mday [ $possiblelunarday ]; |
179 | $op += 1; |
180 | } |
181 | else { // 不在本月的天数范畴内 |
182 | $results [ $i ] = $mday [1]; //退回到1日 |
183 | $fisrtdaylunar = 1; |
184 | $op = 2; |
185 | $curmonthnum = ( $everymonth [ $lcj ][0] != 0) ? 13 : 12; //当年有几个月 |
186 | if ( $lci + 1 > $curmonthnum ) { // 第13/14个月了,转到下一年 |
187 | $lci = 1; |
188 | $lcj = $lcj + 1; |
189 | // 换年头了,把新一年的天干地支也写上 |
190 | $results [ 'year' ] .= '/' . $mten [ $everymonth [ $lcj ][14]] . $mtwelve [ $everymonth [ $lcj ][15]]; |
191 | } |
192 | else { // 还在这年里 |
193 | $lci = $lci + 1; |
194 | $lcj = $lcj ; |
195 | } |
196 | } |
197 | if ( $results [ $i ] == $mday [1]) { // 每月的初一应该显示当月是什么月 |
198 | if ( $everymonth [ $lcj ][0] != 0) { // 有闰月的年 |
199 | $monthss = ( $lci > $everymonth [ $lcj ][0]) ? ( $lci -1) : $lci ; //闰月后的月数-1 |
200 | if ( $lci == $everymonth [ $lcj ][0] + 1) { // 这个月正好是闰月 |
201 | $monthssshow = $mmonth [0] . $mmonth [ $monthss ]; //前面加个闰字 |
202 | $runyue = 1; |
203 | } |
204 | else { |
205 | $monthssshow = $mmonth [ $monthss ]; |
206 | } |
207 | } |
208 | else { |
209 | $monthss = $lci ; |
210 | $monthssshow = $mmonth [ $monthss ]; |
211 | } |
212 | if ( $monthss <= 10 && @ $runyue != 1){ //只有1个字的月加上‘月'字 |
213 | $monthssshow .= $mmonth [13]; |
214 | } |
215 | $results [ $i ] = $monthssshow ; |
216 | } |
217 | } |
218 | return $results ; |
219 | } |
220 | // 忘了加上这个:农历用字 |
221 | $lnlunarcalendar = array ( |
222 | 'tiangan' => array ( "未知" , "甲" , "乙" , "丙" , "丁" , "戊" , "己" , "庚" , "辛" , "壬" , "癸" ), |
223 | 'dizhi' => array ( "未知" , "子年(鼠)" , "丑年(牛)" , "寅年(虎)" , "卯年(兔)" , "辰年(龙)" , |
224 | "巳年(蛇)" , "午年(马)" , "未年(羊)" , "申年(猴)" , "酉年(鸡)" , "戌年(狗)" , "亥年(猪)" ), |
225 | 'month' => array ( "闰" , "正" , "二" , "三" , "四" , "五" , "六" , |
226 | "七" , "八" , "九" , "十" , "十一" , "十二" , "月" ), |
227 | 'day' => array ( "未知" , "初一" , "初二" , "初三" , "初四" , "初五" , "初六" , "初七" , "初八" , "初九" , "初十" , |
228 | "十一" , "十二" , "十三" , "十四" , "十五" , "十六" , "十七" , "十八" , "十九" , "二十" , |
229 | "廿一" , "廿二" , "廿三" , "廿四" , "廿五" , "廿六" , "廿七" , "廿八" , "廿九" , "三十" ) |
230 | ); |
231 | print_r(lunarcalendar(8,2015)); |
运行结果如下:
01 | Array |
02 | ( |
03 | [year] => 乙未年(羊) |
04 | [1] => 十七 |
05 | [2] => 十八 |
06 | [3] => 十九 |
07 | [4] => 二十 |
08 | [5] => 廿一 |
09 | [6] => 廿二 |
10 | [7] => 廿三 |
11 | [8] => 廿四 |
12 | [9] => 廿五 |
13 | [10] => 廿六 |
14 | [11] => 廿七 |
15 | [12] => 廿八 |
16 | [13] => 廿九 |
17 | [14] => 七月 |
18 | [15] => 初二 |
19 | [16] => 初三 |
20 | [17] => 初四 |
21 | [18] => 初五 |
22 | [19] => 初六 |
23 | [20] => 初七 |
24 | [21] => 初八 |
25 | [22] => 初九 |
26 | [23] => 初十 |
27 | [24] => 十一 |
28 | [25] => 十二 |
29 | [26] => 十三 |
30 | [27] => 十四 |
31 | [28] => 十五 |
32 | [29] => 十六 |
33 | [30] => 十七 |
34 | [31] => 十八 |
35 | ) |