PHP编程实现阳历转换为阴历的方法

php类:

  1   
2
/**
3
*PHP编程实现阳历转换为阴历的方法
4
*根据实际情况所需进行调用
5
*
6
/
7
8 9
10
11 <?php 12 class Lunar 13 { 14 public $MIN_YEAR = 1891; 15 public $MAX_YEAR = 2100; 16 public $lunarInfo = array( 17 array(0, 2, 9, 21936), array(6, 1, 30, 9656), array(0, 2, 17, 9584), array(0, 2, 6, 21168), array(5, 1, 26, 43344), array(0, 2, 13, 59728), 18 array(0, 2, 2, 27296), array(3, 1, 22, 44368), array(0, 2, 10, 43856), array(8, 1, 30, 19304), array(0, 2, 19, 19168), array(0, 2, 8, 42352), 19 array(5, 1, 29, 21096), array(0, 2, 16, 53856), array(0, 2, 4, 55632), array(4, 1, 25, 27304), array(0, 2, 13, 22176), array(0, 2, 2, 39632), 20 array(2, 1, 22, 19176), array(0, 2, 10, 19168), array(6, 1, 30, 42200), array(0, 2, 18, 42192), array(0, 2, 6, 53840), array(5, 1, 26, 54568), 21 array(0, 2, 14, 46400), array(0, 2, 3, 54944), array(2, 1, 23, 38608), array(0, 2, 11, 38320), array(7, 2, 1, 18872), array(0, 2, 20, 18800), 22 array(0, 2, 8, 42160), array(5, 1, 28, 45656), array(0, 2, 16, 27216), array(0, 2, 5, 27968), array(4, 1, 24, 44456), array(0, 2, 13, 11104), 23 array(0, 2, 2, 38256), array(2, 1, 23, 18808), array(0, 2, 10, 18800), array(6, 1, 30, 25776), array(0, 2, 17, 54432), array(0, 2, 6, 59984), 24 array(5, 1, 26, 27976), array(0, 2, 14, 23248), array(0, 2, 4, 11104), array(3, 1, 24, 37744), array(0, 2, 11, 37600), array(7, 1, 31, 51560), 25 array(0, 2, 19, 51536), array(0, 2, 8, 54432), array(6, 1, 27, 55888), array(0, 2, 15, 46416), array(0, 2, 5, 22176), array(4, 1, 25, 43736), 26 array(0, 2, 13, 9680), array(0, 2, 2, 37584), array(2, 1, 22, 51544), array(0, 2, 10, 43344), array(7, 1, 29, 46248), array(0, 2, 17, 27808), 27 array(0, 2, 6, 46416), array(5, 1, 27, 21928), array(0, 2, 14, 19872), array(0, 2, 3, 42416), array(3, 1, 24, 21176), array(0, 2, 12, 21168), 28 array(8, 1, 31, 43344), array(0, 2, 18, 59728), array(0, 2, 8, 27296), array(6, 1, 28, 44368), array(0, 2, 15, 43856), array(0, 2, 5, 19296), 29 array(4, 1, 25, 42352), array(0, 2, 13, 42352), array(0, 2, 2, 21088), array(3, 1, 21, 59696), array(0, 2, 9, 55632), array(7, 1, 30, 23208), 30 array(0, 2, 17, 22176), array(0, 2, 6, 38608), array(5, 1, 27, 19176), array(0, 2, 15, 19152), array(0, 2, 3, 42192), array(4, 1, 23, 53864), 31 array(0, 2, 11, 53840), array(8, 1, 31, 54568), array(0, 2, 18, 46400), array(0, 2, 7, 46752), array(6, 1, 28, 38608), array(0, 2, 16, 38320), 32 array(0, 2, 5, 18864), array(4, 1, 25, 42168), array(0, 2, 13, 42160), array(10, 2, 2, 45656), array(0, 2, 20, 27216), array(0, 2, 9, 27968), 33 array(6, 1, 29, 44448), array(0, 2, 17, 43872), array(0, 2, 6, 38256), array(5, 1, 27, 18808), array(0, 2, 15, 18800), array(0, 2, 4, 25776), 34 array(3, 1, 23, 27216), array(0, 2, 10, 59984), array(8, 1, 31, 27432), array(0, 2, 19, 23232), array(0, 2, 7, 43872), array(5, 1, 28, 37736), 35 array(0, 2, 16, 37600), array(0, 2, 5, 51552), array(4, 1, 24, 54440), array(0, 2, 12, 54432), array(0, 2, 1, 55888), array(2, 1, 22, 23208), 36 array(0, 2, 9, 22176), array(7, 1, 29, 43736), array(0, 2, 18, 9680), array(0, 2, 7, 37584), array(5, 1, 26, 51544), array(0, 2, 14, 43344), 37 array(0, 2, 3, 46240), array(4, 1, 23, 46416), array(0, 2, 10, 44368), array(9, 1, 31, 21928), array(0, 2, 19, 19360), array(0, 2, 8, 42416), 38 array(6, 1, 28, 21176), array(0, 2, 16, 21168), array(0, 2, 5, 43312), array(4, 1, 25, 29864), array(0, 2, 12, 27296), array(0, 2, 1, 44368), 39 array(2, 1, 22, 19880), array(0, 2, 10, 19296), array(6, 1, 29, 42352), array(0, 2, 17, 42208), array(0, 2, 6, 53856), array(5, 1, 26, 59696), 40 array(0, 2, 13, 54576), array(0, 2, 3, 23200), array(3, 1, 23, 27472), array(0, 2, 11, 38608), array(11, 1, 31, 19176), array(0, 2, 19, 19152), 41 array(0, 2, 8, 42192), array(6, 1, 28, 53848), array(0, 2, 15, 53840), array(0, 2, 4, 54560), array(5, 1, 24, 55968), array(0, 2, 12, 46496), 42 array(0, 2, 1, 22224), array(2, 1, 22, 19160), array(0, 2, 10, 18864), array(7, 1, 30, 42168), array(0, 2, 17, 42160), array(0, 2, 6, 43600), 43 array(5, 1, 26, 46376), array(0, 2, 14, 27936), array(0, 2, 2, 44448), array(3, 1, 23, 21936), array(0, 2, 11, 37744), array(8, 2, 1, 18808), 44 array(0, 2, 19, 18800), array(0, 2, 8, 25776), array(6, 1, 28, 27216), array(0, 2, 15, 59984), array(0, 2, 4, 27424), array(4, 1, 24, 43872), 45 array(0, 2, 12, 43744), array(0, 2, 2, 37600), array(3, 1, 21, 51568), array(0, 2, 9, 51552), array(7, 1, 29, 54440), array(0, 2, 17, 54432), 46 array(0, 2, 5, 55888), array(5, 1, 26, 23208), array(0, 2, 14, 22176), array(0, 2, 3, 42704), array(4, 1, 23, 21224), array(0, 2, 11, 21200), 47 array(8, 1, 31, 43352), array(0, 2, 19, 43344), array(0, 2, 7, 46240), array(6, 1, 27, 46416), array(0, 2, 15, 44368), array(0, 2, 5, 21920), 48 array(4, 1, 24, 42448), array(0, 2, 12, 42416), array(0, 2, 2, 21168), array(3, 1, 22, 43320), array(0, 2, 9, 26928), array(7, 1, 29, 29336), 49 array(0, 2, 17, 27296), array(0, 2, 6, 44368), array(5, 1, 26, 19880), array(0, 2, 14, 19296), array(0, 2, 3, 42352), array(4, 1, 24, 21104), 50 array(0, 2, 10, 53856), array(8, 1, 30, 59696), array(0, 2, 18, 54560), array(0, 2, 7, 55968), array(6, 1, 27, 27472), array(0, 2, 15, 22224), 51 array(0, 2, 5, 19168), array(4, 1, 25, 42216), array(0, 2, 12, 42192), array(0, 2, 1, 53584), array(2, 1, 21, 55592), array(0, 2, 9, 54560) 52 ); 53 54 /** 55 * 将阳历转换为阴历 56 * @param year 公历-年 57 * @param month 公历-月 58 * @param date 公历-日 59 */ 60 public function convertSolarToLunar($year, $month, $date) 61 { 62 $yearData = $this->lunarInfo[$year - $this->MIN_YEAR]; 63 if ($year == $this->MIN_YEAR && $month <= 2 && $date <= 9) return array(1891, '正月', '初一', '辛卯', 1, 1, '兔'); 64 return $this->getLunarByBetween($year, $this->getDaysBetweenSolar($year, $month, $date, $yearData[1], $yearData[2])); 65 } 66 67 public function convertSolarMonthToLunar($year, $month, $date) 68 { 69 $yearData = $this->lunarInfo[$year - $this->MIN_YEAR]; 70 if ($year == $this->MIN_YEAR && $month <= 2 && $date <= 9) return array(1891, '正月', '初一', '辛卯', 1, 1, '兔'); 71 $month_days_ary = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); 72 $dd = $month_days_ary[$month]; 73 if ($this->isLeapYear($year) && $month == 2) $dd++; 74 $lunar_ary = array(); 75 for ($i = 1; $i < $dd; $i++) { 76 $array = $this->getLunarByBetween($year, $this->getDaysBetweenSolar($year, $month, $i, $yearData[1], $yearData[2])); 77 $array[] = $year . '-' . $month . '-' . $i; 78 $lunar_ary[$i] = $array; 79 } 80 return $lunar_ary; 81 } 82 /** 83 * 将阴历转换为阳历(润月处理) 84 * @param year 阴历-年 85 * @param month 阴历-月,闰月处理:例如如果当年闰五月,那么第二个五月就传六月,相当于阴历有13个月,只是有的时候第13个月的天数为0 86 * @param date 阴历-日 87 */ 88 public function convertLunarToSolarLeapMonth($year, $month, $date) 89 { 90 $leapMonth = $this->getLeapMonth($year);//获取闰月 91 $month = intval($month); 92 if ($leapMonth > 0) { 93 //判断如果是闰月并且单前月大于润月的话 +1 94 if ($month > $leapMonth) { 95 $month = $month + 1; 96 } 97 } 98 $month = strval($month); 99 return $this->convertLunarToSolar($year, $month, $date); 100 } 101 102 /** 103 * 将阴历转换为阳历 104 * @param year 阴历-年 105 * @param month 阴历-月,闰月处理:例如如果当年闰五月,那么第二个五月就传六月,相当于阴历有13个月,只是有的时候第13个月的天数为0 106 * @param date 阴历-日 107 */ 108 public function convertLunarToSolar($year, $month, $date) 109 { 110 $yearData = $this->lunarInfo[$year - $this->MIN_YEAR]; 111 $between = $this->getDaysBetweenLunar($year, $month, $date); 112 $res = mktime(0, 0, 0, $yearData[1], $yearData[2], $year); 113 $res = date('Y-m-d', $res + $between * 24 * 60 * 60); 114 $day = explode('-', $res); 115 $year = $day[0]; 116 $month = $day[1]; 117 $day = $day[2]; 118 return array($year, $month, $day); 119 } 120 121 /** 122 * 判断是否是闰年 123 * @param year 124 */ 125 public function isLeapYear($year) 126 { 127 return (($year % 4 == 0 && $year % 100 != 0) || ($year % 400 == 0)); 128 } 129 130 /** 131 * 获取干支纪年 132 * @param year 133 */ 134 public function getLunarYearName($year) 135 { 136 $sky = array('庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己'); 137 $earth = array('申', '酉', '戌', '亥', '子', '丑', '寅', '卯', '辰', '巳', '午', '未'); 138 $year = $year . ''; 139 return $sky[$year{3}] . $earth[$year % 12]; 140 } 141 142 /** 143 * 根据阴历年获取生肖 144 * @param year 阴历年 145 */ 146 public function getYearZodiac($year) 147 { 148 $zodiac = array('猴', '鸡', '狗', '猪', '鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊'); 149 return $zodiac[$year % 12]; 150 } 151 152 /** 153 * 获取阳历月份的天数 154 * @param year 阳历-年 155 * @param month 阳历-月 156 */ 157 public function getSolarMonthDays($year, $month) 158 { 159 $monthHash = array('1' => 31, '2' => $this->isLeapYear($year) ? 29 : 28, '3' => 31, '4' => 30, '5' => 31, '6' => 30, '7' => 31, '8' => 31, '9' => 30, '10' => 31, '11' => 30, '12' => 31); 160 return $monthHash["$month"]; 161 } 162 163 /** 164 * 获取阴历月份的天数 165 * @param year 阴历-年 166 * @param month 阴历-月,从一月开始 167 */ 168 public function getLunarMonthDays($year, $month) 169 { 170 $monthData = $this->getLunarMonths($year); 171 return $monthData[$month - 1]; 172 } 173 174 /** 175 * 获取阴历每月的天数的数组 176 * @param year 177 */ 178 public function getLunarMonths($year) 179 { 180 $yearData = $this->lunarInfo[$year - $this->MIN_YEAR]; 181 $leapMonth = $yearData[0]; 182 $bit = decbin($yearData[3]); 183 for ($i = 0; $i < strlen($bit); $i++) $bitArray[$i] = substr($bit, $i, 1); 184 for ($k = 0, $klen = 16 - count($bitArray); $k < $klen; $k++) array_unshift($bitArray, '0'); 185 $bitArray = array_slice($bitArray, 0, ($leapMonth == 0 ? 12 : 13)); 186 for ($i = 0; $i < count($bitArray); $i++) $bitArray[$i] = $bitArray[$i] + 29; 187 return $bitArray; 188 } 189 190 /** 191 * 获取农历每年的天数 192 * @param year 农历年份 193 */ 194 public function getLunarYearDays($year) 195 { 196 $yearData = $this->lunarInfo[$year - $this->MIN_YEAR]; 197 $monthArray = $this->getLunarYearMonths($year); 198 $len = count($monthArray); 199 return ($monthArray[$len - 1] == 0 ? $monthArray[$len - 2] : $monthArray[$len - 1]); 200 } 201 202 public function getLunarYearMonths($year) 203 { 204 $monthData = $this->getLunarMonths($year); 205 $res = array(); 206 $temp = 0; 207 $yearData = $this->lunarInfo[$year - $this->MIN_YEAR]; 208 $len = ($yearData[0] == 0 ? 12 : 13); 209 for ($i = 0; $i < $len; $i++) { 210 $temp = 0; 211 for ($j = 0; $j <= $i; $j++) $temp += $monthData[$j]; 212 array_push($res, $temp); 213 } 214 return $res; 215 } 216 217 /** 218 * 获取闰月 219 * @param year 阴历年份 220 */ 221 public function getLeapMonth($year) 222 { 223 $yearData = $this->lunarInfo[$year - $this->MIN_YEAR]; 224 return $yearData[0]; 225 } 226 227 /** 228 * 计算阴历日期与正月初一相隔的天数 229 * @param year 230 * @param month 231 * @param date 232 */ 233 public function getDaysBetweenLunar($year, $month, $date) 234 { 235 $yearMonth = $this->getLunarMonths($year); 236 $res = 0; 237 for ($i = 1; $i < $month; $i++) $res += $yearMonth[$i - 1]; 238 $res += $date - 1; 239 return $res; 240 } 241 242 /** 243 * 计算2个阳历日期之间的天数 244 * @param year 阳历年 245 * @param cmonth 246 * @param cdate 247 * @param dmonth 阴历正月对应的阳历月份 248 * @param ddate 阴历初一对应的阳历天数 249 */ 250 public function getDaysBetweenSolar($year, $cmonth, $cdate, $dmonth, $ddate) 251 { 252 $a = mktime(0, 0, 0, $cmonth, $cdate, $year); 253 $b = mktime(0, 0, 0, $dmonth, $ddate, $year); 254 return ceil(($a - $b) / 24 / 3600); 255 } 256 257 /** 258 * 根据距离正月初一的天数计算阴历日期 259 * @param year 阳历年 260 * @param between 天数 261 */ 262 public function getLunarByBetween($year, $between) 263 { 264 $lunarArray = array(); 265 $yearMonth = array(); 266 $t = 0; 267 $e = 0; 268 $leapMonth = 0; 269 $m = ''; 270 if ($between == 0) { 271 array_push($lunarArray, $year, '正月', '初一'); 272 $t = 1; 273 $e = 1; 274 } else { 275 $year = $between > 0 ? $year : ($year - 1); 276 $yearMonth = $this->getLunarYearMonths($year); 277 $leapMonth = $this->getLeapMonth($year); 278 $between = $between > 0 ? $between : ($this->getLunarYearDays($year) + $between); 279 for ($i = 0; $i < 13; $i++) { 280 if ($between == $yearMonth[$i]) { 281 $t = $i + 2; 282 $e = 1; 283 break; 284 } else if ($between < $yearMonth[$i]) { 285 $t = $i + 1; 286 $e = $between - (empty($yearMonth[$i - 1]) ? 0 : $yearMonth[$i - 1]) + 1; 287 break; 288 } 289 } 290 $m = ($leapMonth != 0 && $t == $leapMonth + 1) ? ('闰' . $this->getCapitalNum($t - 1, true)) : $this->getCapitalNum(($leapMonth != 0 && $leapMonth + 1 < $t ? ($t - 1) : $t), true); 291 array_push($lunarArray, $year, $m, $this->getCapitalNum($e, false)); 292 } 293 array_push($lunarArray, $this->getLunarYearName($year));// 天干地支 294 array_push($lunarArray, $t, $e); 295 array_push($lunarArray, $this->getYearZodiac($year));// 12生肖 296 array_push($lunarArray, $leapMonth);// 闰几月 297 return $lunarArray; 298 } 299 300 /** 301 * 获取数字的阴历叫法 302 * @param num 数字 303 * @param isMonth 是否是月份的数字 304 */ 305 public function getCapitalNum($num, $isMonth) 306 { 307 $isMonth = $isMonth || false; 308 $dateHash = array('0' => '', '1' => '一', '2' => '二', '3' => '三', '4' => '四', '5' => '五', '6' => '六', '7' => '七', '8' => '八', '9' => '九', '10' => '十 '); 309 $monthHash = array('0' => '', '1' => '正月', '2' => '二月', '3' => '三月', '4' => '四月', '5' => '五月', '6' => '六月', '7' => '七月', '8' => '八月', '9' => '九月', '10' => '十月', '11' => '冬月', '12' => '腊月'); 310 $res = ''; 311 if ($isMonth) $res = $monthHash[$num]; 312 else { 313 if ($num <= 10) $res = '初' . $dateHash[$num]; 314 else if ($num > 10 && $num < 20) $res = '十' . $dateHash[$num - 10]; 315 else if ($num == 20) $res = "二十"; 316 else if ($num > 20 && $num < 30) $res = "廿" . $dateHash[$num - 20]; 317 else if ($num == 30) $res = "三十"; 318 } 319 return $res; 320 } 321 322 /** 323 * 节气通用算法 324 */ 325 public function getJieQi($_year, $month, $day) 326 { 327 $year = substr($_year, -2) + 0; 328 $coefficient = array( 329 array(5.4055, 2019, -1),//小寒 330 array(20.12, 2082, 1),//大寒 331 array(3.87),//立春 332 array(18.74, 2026, -1),//雨水 333 array(5.63),//惊蛰 334 array(20.646, 2084, 1),//春分 335 array(4.81),//清明 336 array(20.1),//谷雨 337 array(5.52, 1911, 1),//立夏 338 array(21.04, 2008, 1),//小满 339 array(5.678, 1902, 1),//芒种 340 array(21.37, 1928, 1),//夏至 341 array(7.108, 2016, 1),//小暑 342 array(22.83, 1922, 1),//大暑 343 array(7.5, 2002, 1),//立秋 344 array(23.13),//处暑 345 array(7.646, 1927, 1),//白露 346 array(23.042, 1942, 1),//秋分 347 array(8.318),//寒露 348 array(23.438, 2089, 1),//霜降 349 array(7.438, 2089, 1),//立冬 350 array(22.36, 1978, 1),//小雪 351 array(7.18, 1954, 1),//大雪 352 array(21.94, 2021, -1)//冬至 353 ); 354 $term_name = array( 355 "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", 356 "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", 357 "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"); 358 $idx1 = ($month - 1) * 2; 359 $_leap_value = floor(($year - 1) / 4); 360 $day1 = floor($year * 0.2422 + $coefficient[$idx1][0]) - $_leap_value; 361 if (isset($coefficient[$idx1][1]) && $coefficient[$idx1][1] == $_year) $day1 += $coefficient[$idx1][2]; 362 $day2 = floor($year * 0.2422 + $coefficient[$idx1 + 1][0]) - $_leap_value; 363 if (isset($coefficient[$idx1 + 1][1]) && $coefficient[$idx1 + 1][1] == $_year) $day1 += $coefficient[$idx1 + 1][2]; 364 if ($day == $day1) return $term_name[$idx1]; 365 if ($day == $day2) return $term_name[$idx1 + 1]; 366 return ''; 367 } 368 369 /** 370 * 获取节日:特殊的节日只能修改此函数来计算 371 */ 372 public function getFestival($today, $nl_info = false, $config = 1) 373 { 374 if ($config == 1) { 375 $arr_lunar = array('01-01' => '春节', '01-15' => '元宵节', '02-02' => '二月二', '05-05' => '端午节', '07-07' => '七夕节', '08-15' => '中秋节', '09-09' => '重阳节', '12-08' => '腊八节', '12-23' => '小年'); 376 $arr_solar = array('01-01' => '元旦', '02-14' => '情人节', '03-12' => '植树节', '04-01' => '愚人节', '05-01' => '劳动节', '06-01' => '儿童节', '10-01' => '国庆节', '10-31' => '万圣节', '12-24' => '平安夜', '12-25' => '圣诞节'); 377 }//需要不同节日的,用不同的$config,然后配置$arr_lunar和$arr_solar 378 $festivals = array(); 379 list($y, $m, $d) = explode('-', $today); 380 if (!$nl_info) $nl_info = $this->convertSolarToLunar($y, intval($m), intval($d)); 381 if ($nl_info[7] > 0 && $nl_info[7] < $nl_info[4]) $nl_info[4] -= 1; 382 $md_lunar = substr('0' . $nl_info[4], -2) . '-' . substr('0' . $nl_info[5], -2); 383 $md_solar = substr_replace($today, '', 0, 5); 384 isset($arr_lunar[$md_lunar]) ? array_push($festivals, $arr_lunar[$md_lunar]) : ''; 385 isset($arr_solar[$md_solar]) ? array_push($festivals, $arr_solar[$md_solar]) : ''; 386 $glweek = date("w", strtotime($today)); //0-6 387 if ($m == 5 && ($d > 7) && ($d < 15) && ($glweek == 0)) array_push($festivals, "母亲节"); 388 if ($m == 6 && ($d > 14) && ($d < 22) && ($glweek == 0)) array_push($festivals, "父亲节"); 389 $jieqi = $this->getJieQi($y, $m, $d); 390 if ($jieqi) array_push($festivals, $jieqi); 391 return implode('/', $festivals); 392 } 393 }

调用方法:

1 $lunar = new Lunar();
2 $month = $lunar->convertSolarToLunar(date('Y'),date('m'),date('d'));
3 print_r($month);

运行结果:

Array
(
    [0] => 2019
    [1] => 七月
    [2] => 初一
    [3] => 己亥
    [4] => 7
    [5] => 1
    [6] => 猪
    [7] => 0
)

猜你喜欢

转载自www.cnblogs.com/liu-bear/p/11285009.html