php農曆演算法)

來源:互聯網
上載者:User

<?php

//農曆用字
$lnlunarcalendar=array(
'tiangan'=>array("未知","甲","乙","丙","丁","戊","己","庚","辛","壬","癸"),
'dizhi'=>array("未知","子年(鼠)","丑年(牛)","寅年(虎)","卯年(兔)","辰年(龍)",
            "巳年(蛇)","午年(馬)","未年(羊)","申年(猴)","酉年(雞)","戌年(狗)","亥年(豬)"),
'month'=>array("閏","正","二","三","四","五","六",
             "七","八","九","十","十一","十二","月"),
'day'=>array("未知","初一","初二","初三","初四","初五","初六","初七","初八","初九","初十",
         "十一","十二","十三","十四","十五","十六","十七","十八","十九","二十",
         "廿一","廿二","廿三","廿四","廿五","廿六","廿七","廿八","廿九","三十")
);

$arr= lunarcalendar( "05" , "2010" );

print_R($arr);

function lunarcalendar ($month, $year) {
global $lnlunarcalendar;
/*Lunar calendar 博大精深的農曆
未經處理資料和演算法思路來自 S&S Lab <a href="http://www.focus-2000.com" target="_blank">http://www.focus-2000.com</a> 可惜網站好像關了
*/
//農曆每月的天數。每個元素為一年。每個元素中的資料為:[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,0,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,29,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=>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,29,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,29,30,30,29,30,30,29,30,29,4,6), 18=>array(0,30,29,29,30,29,30,29,30,30,29,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,30,29,30,29,29,30,29,30,0,10,12), 24=>array(0,29,30,30,29,30,30,29,30,29,30,29,29,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,30,29,29,30,29,30,29,30,29,30,30,30,0,4,4), 28=>array(2,29,30,29,29,30,29,29,30,29,30,30,30,30,5,5), 29=>array(0,29,30,29,29,30,29,29,30,29,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,30,30,29,30,0,1,11), 35=>array(0,29,29,30,29,30,29,30,30,29,30,30,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(7,30,30,29,29,30,29,29,30,29,30,30,29,30,5,3), 39=>array(0,30,30,29,29,30,29,29,30,29,30,29,30,0,6,4), 40=>array(0,30,30,29,30,29,30,29,29,30,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,30,29,30,30,30,29,30,0,2,10), 46=>array(0,30,29,29,30,29,29,30,29,30,30,29,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,30,30,29,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,30,29,30,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=>array(3,29,30,29,30,29,29,30,29,30,29,30,30,30,2,8), 56=>array(0,29,30,29,30,29,29,30,29,30,29,30,30,0,3,9), 57=>array(8,30,29,30,29,30,29,29,30,29,30,29,30,29,4,10), 58=>array(0,30,30,30,29,30,29,29,30,29,30,29,30,0,5,11), 59=>array(0,29,30,30,29,30,29,30,29,30,29,30,29,0,6,12), 60=>array(6,30,29,30,29,30,30,29,30,29,30,29,30,29,7,1), 61=>array(0,30,29,30,29,30,29,30,30,29,30,29,30,0,8,2), 62=>array(0,29,30,29,29,30,29,30,30,29,30,30,29,0,9,3), 63=>array(4,30,29,30,29,29,30,29,30,29,30,30,30,29,10,4), 64=>array(0,30,29,30,29,29,30,29,30,29,30,30,30,0,1,5), 65=>array(0,29,30,29,30,29,29,30,29,29,30,30,29,0,2,6), 66=>array(3,30,30,30,29,30,29,29,30,29,29,30,30,29,3,7), 67=>array(0,30,30,29,30,30,29,29,30,29,30,29,30,0,4,8), 68=>array(7,29,30,29,30,30,29,30,29,30,29,30,29,30,5,9), 69=>array(0,29,30,29,30,29,30,30,29,30,29,30,29,0,6,10), 70=>array(0,30,29,29,30,29,30,30,29,30,30,29,30,0,7,11), 71=>array(5,29,30,29,29,30,29,30,29,30,30,30,29,30,8,12), 72=>array(0,29,30,29,29,30,29,30,29,30,30,29,30,0,9,1), 73=>array(0,30,29,30,29,29,30,29,29,30,30,29,30,0,10,2), 74=>array(4,30,30,29,30,29,29,30,29,29,30,30,29,30,1,3), 75=>array(0,30,30,29,30,29,29,30,29,29,30,29,30,0,2,4), 76=>array(8,30,30,29,30,29,30,29,30,29,29,30,29,30,3,5), 77=>array(0,30,29,30,30,29,30,29,30,29,30,29,29,0,4,6), 78=>array(0,30,29,30,30,29,30,30,29,30,29,30,29,0,5,7), 79=>array(6,30,29,29,30,29,30,30,29,30,30,29,30,29,6,8), 80=>array(0,30,29,29,30,29,30,29,30,30,29,30,30,0,7,9), 81=>array(0,29,30,29,29,30,29,29,30,30,29,30,30,0,8,10), 82=>array(4,30,29,30,29,29,30,29,29,30,29,30,30,30,9,11), 83=>array(0,30,29,30,29,29,30,29,29,30,29,30,30,0,10,12), 84=>array(10,30,29,30,30,29,29,30,29,29,30,29,30,30,1,1), 85=>array(0,29,30,30,29,30,29,30,29,29,30,29,30,0,2,2), 86=>array(0,29,30,30,29,30,30,29,30,29,30,29,29,0,3,3), 87=>array(6,30,29,30,29,30,30,29,30,30,29,30,29,29,4,4), 88=>array(0,30,29,30,29,30,29,30,30,29,30,30,29,0,5,5), 89=>array(0,30,29,29,30,29,29,30,30,29,30,30,30,0,6,6), 90=>array(5,29,30,29,29,30,29,29,30,29,30,30,30,30,7,7), 91=>array(0,29,30,29,29,30,29,29,30,29,30,30,30,0,8,8), 92=>array(0,29,30,30,29,29,30,29,29,30,29,30,30,0,9,9), 93=>array(3,29,30,30,29,30,29,30,29,29,30,29,30,29,10,10), 94=>array(0,30,30,30,29,30,29,30,29,29,30,29,30,0,1,11), 95=>array(8,29,30,30,29,30,29,30,30,29,29,30,29,30,2,12), 96=>array(0,29,30,29,30,30,29,30,29,30,30,29,29,0,3,1), 97=>array(0,30,29,30,29,30,29,30,30,29,30,30,29,0,4,2), 98=>array(5,30,29,29,30,29,29,30,30,29,30,30,29,30,5,3), 99=>array(0,30,29,29,30,29,29,30,29,30,30,30,29,0,6,4), 100=>array(0,30,30,29,29,30,29,29,30,29,30,30,29,0,7,5), 101=>array(4,30,30,29,30,29,30,29,29,30,29,30,29,30,8,6), 102=>array(0,30,30,29,30,29,30,29,29,30,29,30,29,0,9,7), 103=>array(0,30,30,29,30,30,29,30,29,29,30,29,30,0,10,8), 104=>array(2,29,30,29,30,30,29,30,29,30,29,30,29,30,1,9), 105=>array(0,29,30,29,30,29,30,30,29,30,29,30,29,0,2,10), 106=>array(7,30,29,30,29,30,29,30,29,30,30,29,30,30,3,11), 107=>array(0,29,29,30,29,29,30,29,30,30,30,29,30,0,4,12), 108=>array(0,30,29,29,30,29,29,30,29,30,30,29,30,0,5,1), 109=>array(5,30,30,29,29,30,29,29,30,29,30,29,30,30,6,2), 110=>array(0,30,29,30,29,30,29,29,30,29,30,29,30,0,7,3), 111=>array(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,30,29,30,29,30,30,29,30,29,30,29,30,0,10,6), 114=>array(9,29,30,29,30,29,30,29,30,30,29,30,29,30,1,7), 115=>array(0,29,30,29,29,30,29,30,30,30,29,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=>array(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,29,30,29,30,29,30,7,1) );
//農曆天幹
$mten=$lnlunarcalendar['tiangan'];
//農曆地支
$mtwelve=$lnlunarcalendar['dizhi'];
//農曆月份
$mmonth=$lnlunarcalendar['month'];
//農曆日
$mday=$lnlunarcalendar['day'];
//陽曆總天數 至1900年12月21日
$total=69*365+17+11; //1970年1月1日前的就不算了
if ($year=="" || $month=="" || ($year<1970 or $year>2020)) return ''; //超出這個範圍不計算
//計算到所求日期陽曆的總天數-自1900年12月21日始
//先算年的和
for ($y=1970; $y<$year;$y++){
       $total+=365;
       if ($y%4==0) $total ++;
}
//再加當年的幾個月
$total+=gmdate("z",gmmktime(0,0,0,$month,1,$year));
//用農曆的天數累加來判斷是否超過陽曆的天數
$flag1=0; //判斷跳出迴圈的條件
$lcj=0;
while ($lcj<=120){
       $lci=1;
       while ($lci<=13){
         $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<=$daysthismonth; $i++) {
       $possiblelunarday=$fisrtdaylunar+$op-1; //理論上疊加後的農曆日
       if ($possiblelunarday<=$everymonth[$lcj][$lci]) { //在本月的天數範疇內
         $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<=10 && $runyue!=1) $monthssshow.=$mmonth[13]; //只有1個字的月加上‘月’字
         $results[$i]=$monthssshow;
       }
}
return $results;
}

?>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.