php 阴历-农历-转换类代码

代码如下:
PHP
/**
* 公农历转换(1912 - 2012)
*
* Usage:
* // 公历1983-10-5转农历
* $lunar = new Lunar();
* $date = $lunar->getLar('1983-10-5',0);
* echo date("Y-m-d",$date);
* // 农历1983-8-29转公历
* $date = $lunar->getLar('1983-8-29',1);
* echo date("Y-m-d",$date);
*
* @param string 日期
* @param int 日期历法
* - 0 公历
* 1 农历
*
* @return timestamp


这是一个国历与农历互相转的Unit.

其中年份皆用民国年份,请自行转换 (西元年-1911 = 民国年).
***************************************************************************
*国农历对映表之说明 : *
***************************************************************************
* 前二数字 = 闰月月份,如果为 13 则没有闰月 *
* 第叁至第六数字 = 12 个月之大小月之2进位码->10进位 *
* 例如: *
* 101010101010 = 2730 *
* 1 : 代表大月(30天) 0 : 代表小月(29天) ==> 1月大2月小3月大.. *
* 第七位数字为闰月天数 *
* 0 : 没有闰月之天数 *
* 1 : 闰月为小月(29天) *
* 2 : 闰月为大月(30天) *
* 最後2位数字代表阳历之1月1日与阴历之1月1日相差天数 *
***************************************************************************
这对映表只有民国一年至民国一百年,如不敷您的使用请按照上述之方式自行增加.

这个程式没有判断您所输入之年,月,日是否正确,请自行判断.

如果转换出来之农历的月份是闰月则传给您的值是***负数***
如果农历要转换国历如果是闰月请输入***负数***

此版本为FreeWare Version : 0.1
您可以自行修改,但最好可以将修改过之程式Mail一份给我.
如果您要用於商业用途,请mail给我告知您的用途及原因.*/
class Lunar {
var $LMDay = array();
var $InterMonth = 0;
var $InterMonthDays = 0;
var $SLRangeDay = 0;

var $SMDay = array(1 => 31,28,31,30,31);
var $LongLife = array( 1 =>
'132637048','133365036','053365225','132900044','131386034','022778122',//6
'132395041','071175231','131175050','132635038','052891127','131701046',//12
'131748035','042741223','130694043','132391032','021327122','131175040',//18
'061623129','133402047','133402036','051769125','131453044','130694034',//24
'032158223','132350041','073213230','133221049','133402038','063466226',//30
'132901045','131130035','042651224','130605043','132349032','023371121',//36
'132709040','072901128','131738047','132901036','051333226','131210044',//42
'132651033','031111223','131323042','082714130','133733048','131706038',//48
'062794127','132741045','131206035','042734124','132647043','131318032',//54
'033878120','133477039','071461129','131386047','132413036','051245126',//60
'131197045','132637033','043405122','133365041','083413130','132900048',//66
'132922037','062394227','132395046','131179035','042711124','132635043',//72
'102855132','131701050','131748039','062804128','132742047','132359036',//78
'051199126','131175045','131611034','031866122','133749040','081717130',//84
'131452049','132742037','052413127','132350046','133222035','043477123',//90
'133402042','133493031','021877121','131386039','072747128','130605048',//96
'132349037','053243125','132709044','132890033'); function getLar($date,$isLunar = 1){
list($year,$month,$day) = split("-",$date);
if($isLunar == 1)
return $this->Lunar2Solar($year,$day);
else
return $this->Solar2Lunar($year,$day);
} function IsLeapYear($AYear){
return ($AYear % 4 == 0) and (($AYear % 100 <> 0) or ($AYear % 400 == 0));
} function CovertLunarMonth($magicno){
$m = $magicno;
for ($i = 12; $i >= 1; $i--){
$size = $m % 2;
if ($size == 0)
$this->LMDay[$i] = 29;
else
$this->LMDay[$i] = 30;
$m = floor($m / 2);
}
} function ProcessMagicStr($yy){
$yy = $yy - 1911;
$magicstr = $this->LongLife[$yy];
$this->InterMonth = substr($magicstr,2);
$LunarMonth = substr($magicstr,2,4);
$this->CovertLunarMonth($LunarMonth);
$dsize = substr($magicstr,6,1);
switch ($dsize) {
case 0 :
$this->InterMonthDays = 0;
break;
case 1 :
$this->InterMonthDays = 29;
break;
case 2 :
$this->InterMonthDays = 30;
break;
}
$this->SLRangeDay = substr($magicstr,7,2);
} function DaysPerLunarMonth($LYear,$LMonth){
$this->ProcessMagicStr($LYear);
if ($LMonth < 0)
return $this->InterMonthDays;
else
return $this->LMDay[$LMonth];
} function Solar2Lunar($SYear,$SMonth,$SDay){
if( !(1912 <= $SYear && $SYear <= 2012) ){
return false;
}
$day = 0;
if ($this->isLeapYear($SYear))
$this->SMDay[2] = 29;
$this->ProcessMagicStr($SYear);
if ($SMonth == 1)
$day = $SDay;
else {
for($i = 1; $i <= $SMonth-1; $i++)
$day = $day + $this->SMDay[$i];
$day = $day + $SDay;
}
if ($day <= $this->SLRangeDay) {
$day = $day - $this->SLRangeDay;
$this->processmagicstr($SYear-1);
for ($i = 12; $i >= 1; $i--){
$day = $day + $this->LMDay[$i];
if ($day > 0)
break;
}
$LYear = $SYear - 1;
$LMonth = $i;
$LDay = $day;
} else {
$day = $day - $this->SLRangeDay;
for($i = 1; $i <= $this->InterMonth-1; $i++){
$day = $day - $this->LMDay[$i];
if ($day <= 0)
break;
}
if ($day <= 0) {
$LYear = $SYear;
$LMonth = $i;
$LDay = $day + $this->LMDay[$i];
} else {
$day = $day - $this->LMDay[$this->InterMonth];
if ($day <= 0) {
$LYear = $SYear;
$LMonth = $this->InterMonth;
$LDay = $day + $this->LMDay[$this->InterMonth];
} else {
$this->LMDay[$this->InterMonth] = $this->InterMonthDays;
for ($i = $this->InterMonth; $i <= 12; $i++){
$day = $day - $this->LMDay[$i];
if ($day <= 0)
break;
}
if ($i == $this->InterMonth)
$LMonth = 0 - $this->InterMonth;
else
$LMonth = $i;
$LYear = $SYear;
$LDay = $day + $this->LMDay[$i];
}
}
}
return mktime(0,$LMonth,$LDay,$LYear);
} function Lunar2Solar($LYear,$LDay){
if( !(1912 <= $LYear && $LYear <= 2012) ){
return false;
}
$day = 0;
$SYear = $LYear;
if ($this->isLeapYear($SYear))
$this->SMDay[2] = 29;
$this->processmagicstr($SYear);
if ($LMonth < 0)
$day = $this->LMDay[$this->InterMonth];
if ($LMonth <> 1)
for ($i = 1; $i <= $LMonth-1; $i++)
$day = $day + $this->LMDay[$i];
$day = $day + $LDay + $this->SLRangeDay;
if (($this->InterMonth <> 13) and ($this->InterMonth < $LMonth))
$day = $day + $this->InterMonthDays;
for ($i = 1; $i <= 12; $i++){
$day = $day - $this->SMDay[$i];
if ($day <= 0)
break;
}
if ($day > 0) {
$SYear = $SYear + 1;
if ($this->isLeapYear($SYear))
$this->SMDay[2] = 29;
for ($i = 1; $i <= 12; $i++){
$day = $day - $this->SMDay[$i];
if ($day <= 0)
break;
}
}
$day = $day + $this->SMDay[$i];
$SMonth = $i;
$SDay = $day;
return mktime(0,$SDay,$SYear);
}
}
?>


使用方法
代码如下:
$lunar = new Lunar();
$date = $lunar->getLar('1983-10-5',0);
echo date("Y-m-d",$date);
// 农历1983-8-29转公历
$date = $lunar->getLar('1983-8-29',1);
echo date("Y-m-d",$date);

代码如下:
PHP
class Lunar {
var $MIN_YEAR = 1891;
var $MAX_YEAR = 2100;
var $lunarInfo = array(
array(0,9,21936),array(6,1,9656),array(0,17,9584),21168),array(5,26,43344),13,59728),
array(0,27296),array(3,22,44368),10,43856),array(8,19304),19,19168),8,42352),
array(5,29,21096),16,53856),4,55632),array(4,25,27304),22176),39632),
array(2,19176),42200),18,42192),53840),54568),14,46400),3,54944),array(2,23,38608),11,38320),array(7,18872),20,18800),42160),45656),27216),5,27968),24,44456),11104),38256),18808),25776),54432),59984),27976),23248),37744),37600),51560),51536),27,55888),15,46416),43736),9680),37584),51544),46248),27808),21928),19872),42416),21176),12,
array(8,19296),
array(4,21088),21,59696),23208),19152),53864),46752),18864),42168),array(10,
array(6,44448),43872),
array(3,27432),23232),37736),51552),54440),46240),array(9,19360),43312),29864),19880),42208),54576),23200),27472),array(11,53848),54560),55968),46496),22224),19160),43600),46376),27936),27424),43744),51568),42704),21224),21200),43352),21920),42448),43320),26928),29336),21104),42216),53584),55592),54560)
);
/**
* 将阳历转换为阴历
* @param year 公历-年
* @param month 公历-月
* @param date 公历-日
*/
function convertSolarToLunar($year,$date){
//debugger;
$yearData = $this->lunarInfo[$year-$this->MIN_YEAR];
if($year==$this->MIN_YEAR&&$month<=2&&$date<=9){
return array(1891,'正月','初一','辛卯','兔');
}
return $this->getLunarByBetween($year,$this->getDaysBetweenSolar($year,$date,$yearData[1],$yearData[2]));
} function convertSolarMonthToLunar($year,$month) {
$yearData = $this->lunarInfo[$year-$this->MIN_YEAR];
if($year==$this->MIN_YEAR&&$month<=2&&$date<=9){
return array(1891,'兔');
}
$month_days_ary = array(31,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,$i,$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,$date){
$yearData = $this->lunarInfo[$year-$this->MIN_YEAR];
$between = $this->getDaysBetweenLunar($year,$date);
$res = mktime(0,$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,$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,1);
}
for($k=0,$klen=16-count($bitArray);$k<$klen;$k++){
array_unshift($bitArray,'0');
}
$bitArray = array_slice($bitArray,($leapMonth==0?12:13));
for($i=0; $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,$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,$year);
$b = mktime(0,$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,'初一');
$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,$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'=>'一','2'=>'二','3'=>'三','4'=>'四','5'=>'五','6'=>'六','7'=>'七','8'=>'八','9'=>'九','10'=>'十 ');
$monthHash=array('0'=>'','1'=>'正月','2'=>'二月','3'=>'三月','4'=>'四月','5'=>'五月','6'=>'六月','7'=>'七月','8'=>'八月','9'=>'九月','10'=>'十月','11'=>'冬月','12'=>'腊月');
$res='';
if($isMonth){
$res = $monthHash[$num];
}else{
if($num<=10){
$res = '初'.$dateHash[$num];
}else if($num>10&&$num<20){
$res = '十'.$dateHash[$num-10];
}else if($num==20){
$res = "二十";
}else if($num>20&&$num<30){
$res = "廿".$dateHash[$num-20];
}else if($num==30){
$res = "三十";
}
}
return $res;
}
}
$lunar = new Lunar();
$month = $lunar->convertLunarToSolar(2012,1);
print_r($month);
exit;

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...