lunarInfo[ $year - $this->MIN_YEAR ]; if ($year == $this->MIN_YEAR && $month <= 2 && $date <= 9) return array ( 1891, '正月', '初一', '辛卯', 1, 1, '兔' ); return $this->getLunarByBetween($year, $this->getDaysBetweenSolar($year, $month, $date, $yearData[ 1 ], $yearData[ 2 ])); } function convertSolarMonthToLunar($year, $month, $date) { $yearData = $this->lunarInfo[ $year - $this->MIN_YEAR ]; if ($year == $this->MIN_YEAR && $month <= 2 && $date <= 9) return array ( 1891, '正月', '初一', '辛卯', 1, 1, '兔' ); $month_days_ary = array ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); $dd = $month_days_ary[ $month ]; if ($this->isLeapYear($year) && $month == 2) $dd++; $lunar_ary = array (); for ($i = 1; $i < $dd; $i++) { $array = $this->getLunarByBetween($year, $this->getDaysBetweenSolar($year, $month, $i, $yearData[ 1 ], $yearData[ 2 ])); $array[] = $year . '-' . $month . '-' . $i; $lunar_ary[ $i ] = $array; } return $lunar_ary; } /** * 将阴历转换为阳历 * @param year 阴历-年 * @param month 阴历-月,闰月处理:例如如果当年闰五月,那么第二个五月就传六月,相当于阴历有13个月,只是有的时候第13个月的天数为0 * @param date 阴历-日 */ function convertLunarToSolar($year, $month, $date) { $yearData = $this->lunarInfo[ $year - $this->MIN_YEAR ]; $between = $this->getDaysBetweenLunar($year, $month, $date); $res = mktime(0, 0, 0, $yearData[ 1 ], $yearData[ 2 ], $year); $res = date('Y-m-d', $res + $between * 24 * 60 * 60); $day = explode('-', $res); $year = $day[ 0 ]; $month = $day[ 1 ]; $day = $day[ 2 ]; return array ( $year, $month, $day ); } /** * 判断是否是闰年 * @param year */ function isLeapYear($year) { return ( ( $year % 4 == 0 && $year % 100 != 0 ) || ( $year % 400 == 0 ) ); } /** * 获取干支纪年 * @param year */ function getLunarYearName($year) { $sky = array ( '庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己' ); $earth = array ( '申', '酉', '戌', '亥', '子', '丑', '寅', '卯', '辰', '巳', '午', '未' ); $year = $year . ''; return $sky[ $year{3} ] . $earth[ $year % 12 ]; } /** * 根据阴历年获取生肖 * @param year 阴历年 */ function getYearZodiac($year) { $zodiac = array ( '猴', '鸡', '狗', '猪', '鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊' ); return $zodiac[ $year % 12 ]; } /** * 获取阳历月份的天数 * @param year 阳历-年 * @param month 阳历-月 */ function getSolarMonthDays($year, $month) { $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 ); return $monthHash[ "$month" ]; } /** * 获取阴历月份的天数 * @param year 阴历-年 * @param month 阴历-月,从一月开始 */ function getLunarMonthDays($year, $month) { $monthData = $this->getLunarMonths($year); return $monthData[ $month - 1 ]; } /** * 获取阴历每月的天数的数组 * @param year */ function getLunarMonths($year) { $yearData = $this->lunarInfo[ $year - $this->MIN_YEAR ]; $leapMonth = $yearData[ 0 ]; $bit = decbin($yearData[ 3 ]); for ($i = 0; $i < strlen($bit); $i++) $bitArray[ $i ] = substr($bit, $i, 1); for ($k = 0, $klen = 16 - count($bitArray); $k < $klen; $k++) array_unshift($bitArray, '0'); $bitArray = array_slice($bitArray, 0, ( $leapMonth == 0 ? 12 : 13 )); for ($i = 0; $i < count($bitArray); $i++) $bitArray[ $i ] = $bitArray[ $i ] + 29; return $bitArray; } /** * 获取农历每年的天数 * @param year 农历年份 */ function getLunarYearDays($year) { $yearData = $this->lunarInfo[ $year - $this->MIN_YEAR ]; $monthArray = $this->getLunarYearMonths($year); $len = count($monthArray); return ( $monthArray[ $len - 1 ] == 0 ? $monthArray[ $len - 2 ] : $monthArray[ $len - 1 ] ); } function getLunarYearMonths($year) { //debugger; $monthData = $this->getLunarMonths($year); $res = array (); $temp = 0; $yearData = $this->lunarInfo[ $year - $this->MIN_YEAR ]; $len = ( $yearData[ 0 ] == 0 ? 12 : 13 ); for ($i = 0; $i < $len; $i++) { $temp = 0; for ($j = 0; $j <= $i; $j++) $temp += $monthData[ $j ]; array_push($res, $temp); } return $res; } /** * 获取闰月 * @param year 阴历年份 */ function getLeapMonth($year) { $yearData = $this->lunarInfo[ $year - $this->MIN_YEAR ]; return $yearData[ 0 ]; } /** * 计算阴历日期与正月初一相隔的天数 * @param year * @param month * @param date */ function getDaysBetweenLunar($year, $month, $date) { $yearMonth = $this->getLunarMonths($year); $res = 0; for ($i = 1; $i < $month; $i++) $res += $yearMonth[ $i - 1 ]; $res += $date - 1; return $res; } /** * 计算2个阳历日期之间的天数 * @param year 阳历年 * @param cmonth * @param cdate * @param dmonth 阴历正月对应的阳历月份 * @param ddate 阴历初一对应的阳历天数 */ function getDaysBetweenSolar($year, $cmonth, $cdate, $dmonth, $ddate) { $a = mktime(0, 0, 0, $cmonth, $cdate, $year); $b = mktime(0, 0, 0, $dmonth, $ddate, $year); return ceil(( $a - $b ) / 24 / 3600); } /** * 根据距离正月初一的天数计算阴历日期 * @param year 阳历年 * @param between 天数 */ function getLunarByBetween($year, $between) { //debugger; $lunarArray = array (); $yearMonth = array (); $t = 0; $e = 0; $leapMonth = 0; $m = ''; if ($between == 0) { array_push($lunarArray, $year, '01', '01'); $t = 1; $e = 1; } else { $year = $between > 0 ? $year : ( $year - 1 ); $yearMonth = $this->getLunarYearMonths($year); $leapMonth = $this->getLeapMonth($year); $between = $between > 0 ? $between : ( $this->getLunarYearDays($year) + $between ); for ($i = 0; $i < 13; $i++) { if ($between == $yearMonth[ $i ]) { $t = $i + 2; $e = 1; break; } else if ($between < $yearMonth[ $i ]) { $t = $i + 1; $e = $between - ( empty($yearMonth[ $i - 1 ]) ? 0 : $yearMonth[ $i - 1 ] ) + 1; break; } } $m = ( $leapMonth != 0 && $t == $leapMonth + 1 ) ? ( '闰' . $this->getCapitalNum($t - 1, true) ) : $this->getCapitalNum(( $leapMonth != 0 && $leapMonth + 1 < $t ? ( $t - 1 ) : $t ), true); array_push($lunarArray, $year, $m, $this->getCapitalNum($e, false)); } array_push($lunarArray, $this->getLunarYearName($year));// 天干地支 array_push($lunarArray, $t, $e); array_push($lunarArray, $this->getYearZodiac($year));// 12生肖 array_push($lunarArray, $leapMonth);// 闰几月 return $lunarArray; } /** * 获取数字的阴历叫法 * @param num 数字 * @param isMonth 是否是月份的数字 */ function getCapitalNum($num, $isMonth) { $isMonth = $isMonth || false; $dateHash = array ( '0' => '', '1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9', '10' => '10' ); $monthHash = array ( '0' => '', '1' => '01', '2' => '02', '3' => '03', '4' => '04', '5' => '05', '6' => '06', '7' => '07', '8' => '08', '9' => '09', '10' => '10', '11' => '11', '12' => '12' ); $res = ''; if ($isMonth) $res = $monthHash[ $num ]; else { if ($num <= 10) $res = '0' . $dateHash[ $num ]; else if ($num > 10 && $num < 20) $res = '1' . $dateHash[ $num - 10 ]; else if ($num == 20) $res = "20"; else if ($num > 20 && $num < 30) $res = "2" . $dateHash[ $num - 20 ]; else if ($num == 30) $res = "30"; } return $res; } /* * 节气通用算法 */ function getJieQi($_year, $month, $day) { $year = substr($_year, -2) + 0; $coefficient = array ( array ( 5.4055, 2019, -1 ),//小寒 array ( 20.12, 2082, 1 ),//大寒 array ( 3.87 ),//立春 array ( 18.74, 2026, -1 ),//雨水 array ( 5.63 ),//惊蛰 array ( 20.646, 2084, 1 ),//春分 array ( 4.81 ),//清明 array ( 20.1 ),//谷雨 array ( 5.52, 1911, 1 ),//立夏 array ( 21.04, 2008, 1 ),//小满 array ( 5.678, 1902, 1 ),//芒种 array ( 21.37, 1928, 1 ),//夏至 array ( 7.108, 2016, 1 ),//小暑 array ( 22.83, 1922, 1 ),//大暑 array ( 7.5, 2002, 1 ),//立秋 array ( 23.13 ),//处暑 array ( 7.646, 1927, 1 ),//白露 array ( 23.042, 1942, 1 ),//秋分 array ( 8.318 ),//寒露 array ( 23.438, 2089, 1 ),//霜降 array ( 7.438, 2089, 1 ),//立冬 array ( 22.36, 1978, 1 ),//小雪 array ( 7.18, 1954, 1 ),//大雪 array ( 21.94, 2021, -1 )//冬至 ); $term_name = array ( "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至" ); $idx1 = ( $month - 1 ) * 2; $_leap_value = floor(( $year - 1 ) / 4); $day1 = floor($year * 0.2422 + $coefficient[ $idx1 ][ 0 ]) - $_leap_value; if (isset($coefficient[ $idx1 ][ 1 ]) && $coefficient[ $idx1 ][ 1 ] == $_year) $day1 += $coefficient[ $idx1 ][ 2 ]; $day2 = floor($year * 0.2422 + $coefficient[ $idx1 + 1 ][ 0 ]) - $_leap_value; if (isset($coefficient[ $idx1 + 1 ][ 1 ]) && $coefficient[ $idx1 + 1 ][ 1 ] == $_year) $day1 += $coefficient[ $idx1 + 1 ][ 2 ]; //echo __FILE__.'->'.__LINE__.' $day1='.$day1,',$day2='.$day2.'
'.chr(10); $data = array (); if ($day < $day1) { $data[ 'name1' ] = $term_name[ $idx1 - 1 ]; $data[ 'name2' ] = $term_name[ $idx1 - 1 ] . '后'; } else if ($day == $day1) { $data[ 'name1' ] = $term_name[ $idx1 ]; $data[ 'name2' ] = $term_name[ $idx1 ]; } else if ($day > $day1 && $day < $day2) { $data[ 'name1' ] = $term_name[ $idx1 ]; $data[ 'name2' ] = $term_name[ $idx1 ] . '后'; } else if ($day == $day2) { $data[ 'name1' ] = $term_name[ $idx1 + 1 ]; $data[ 'name2' ] = $term_name[ $idx1 + 1 ]; } else if ($day > $day2) { $data[ 'name1' ] = $term_name[ $idx1 + 1 ]; $data[ 'name2' ] = $term_name[ $idx1 + 1 ] . '后'; } return $data; } /* * 获取节日:特殊的节日只能修改此函数来计算 */ function getFestival($today, $nl_info = false, $config = 1) { if ($config == 1) { $arr_lunar = array ( '01-01' => '春节', '01-15' => '元宵节', '02-02' => '二月二', '05-05' => '端午节', '07-07' => '七夕节', '08-15' => '中秋节', '09-09' => '重阳节', '12-08' => '腊八节', '12-23' => '小年' ); $arr_solar = array ( '01-01' => '元旦', '02-14' => '情人节', '03-12' => '植树节', '04-01' => '愚人节', '05-01' => '劳动节', '06-01' => '儿童节', '10-01' => '国庆节', '10-31' => '万圣节', '12-24' => '平安夜', '12-25' => '圣诞节' ); }//需要不同节日的,用不同的$config,然后配置$arr_lunar和$arr_solar $festivals = array (); list($y, $m, $d) = explode('-', $today); if (!$nl_info) $nl_info = $this->convertSolarToLunar($y, intval($m), intval($d)); if ($nl_info[ 7 ] > 0 && $nl_info[ 7 ] < $nl_info[ 4 ]) $nl_info[ 4 ] -= 1; $md_lunar = substr('0' . $nl_info[ 4 ], -2) . '-' . substr('0' . $nl_info[ 5 ], -2); $md_solar = substr_replace($today, '', 0, 5); isset($arr_lunar[ $md_lunar ]) ? array_push($festivals, $arr_lunar[ $md_lunar ]) : ''; isset($arr_solar[ $md_solar ]) ? array_push($festivals, $arr_solar[ $md_solar ]) : ''; $glweek = date("w", strtotime($today)); //0-6 if ($m == 5 && ( $d > 7 ) && ( $d < 15 ) && ( $glweek == 0 )) array_push($festivals, "母亲节"); if ($m == 6 && ( $d > 14 ) && ( $d < 22 ) && ( $glweek == 0 )) array_push($festivals, "父亲节"); $jieqi = $this->getJieQi($y, $m, $d); if ($jieqi) array_push($festivals, $jieqi); return implode('/', $festivals); } /* * 获取当前时间属于哪个时辰 @param int $time 时间戳 */ function getTheHour($h) { $d = $h; if ($d == 23 || $d == 0) { return '子时'; } else if ($d == 1 || $d == 2) { return '丑时'; } else if ($d == 3 || $d == 4) { return '寅时'; } else if ($d == 5 || $d == 6) { return '卯时'; } else if ($d == 7 || $d == 8) { return '辰时'; } else if ($d == 9 || $d == 10) { return '巳时'; } else if ($d == 11 || $d == 12) { return '午时'; } else if ($d == 13 || $d == 14) { return '未时'; } else if ($d == 15 || $d == 16) { return '申时'; } else if ($d == 17 || $d == 18) { return '酉时'; } else if ($d == 19 || $d == 20) { return '戌时'; } else if ($d == 21 || $d == 22) { return '亥时'; } } }