php 农历

php 农历

  1. function lunarcalendar ($month$year) {      
  2.     global $lnlunarcalendar;      
  3.     /*Lunar calendar 博大精深的农历    
  4.     原始数据和算法思路来自javascript版的农历算法    
  5.     */     
  6.     //农历每月的天数。每个元素为一年。每个元素中的数据为:[0]是闰月在哪个月,0为无闰月;[1]到[13]是每年12或13个月的每月天数;[14]是当年的天干次序,[15]是当年的地支次序       
  7.     $everymonth=array(   
  8.         0=>array(8,0,0,0,0,0,0,0,0,0,0,0,29,30,7,1),   
  9.         1=>array(0,29,30,29,29,30,29,30,29,30,30,30,29,0,8,2),   
  10.         2=>array(0,30,29,30,29,29,30,29,30,29,30,30,30,0,9,3),   
  11.         3=>array(5,29,30,29,30,29,29,30,29,29,30,30,29,30,10,4),   
  12.         4=>array(0,30,30,29,30,29,29,30,29,29,30,30,29,0,1,5),   
  13.         5=>array(0,30,30,29,30,30,29,29,30,29,30,29,30,0,2,6),   
  14.         6=>array(4,29,30,30,29,30,29,30,29,30,29,30,29,30,3,7),   
  15.         7=>array(0,29,30,29,30,29,30,30,29,30,29,30,29,0,4,8),   
  16.         8=>array(0,30,29,29,30,30,29,30,29,30,30,29,30,0,5,9),   
  17.         9=>array(2,29,30,29,29,30,29,30,29,30,30,30,29,30,6,10),   
  18.         10=>array(0,29,30,29,29,30,29,30,29,30,30,30,29,0,7,11),   
  19.         11=>array(6,30,29,30,29,29,30,29,29,30,30,29,30,30,8,12),   
  20.         12=>array(0,30,29,30,29,29,30,29,29,30,30,29,30,0,9,1),   
  21.         13=>array(0,30,30,29,30,29,29,30,29,29,30,29,30,0,10,2),   
  22.         14=>array(5,30,30,29,30,29,30,29,30,29,30,29,29,30,1,3),   
  23.         15=>array(0,30,29,30,30,29,30,29,30,29,30,29,30,0,2,4),   
  24.         16=>array(0,29,30,29,30,29,30,30,29,30,29,30,29,0,3,5),   
  25.         17=>array(2,30,29,29,30,29,30,30,29,30,30,29,30,29,4,6),   
  26.         18=>array(0,30,29,29,30,29,30,29,30,30,29,30,30,0,5,7),   
  27.         19=>array(7,29,30,29,29,30,29,29,30,30,29,30,30,30,6,8),   
  28.         20=>array(0,29,30,29,29,30,29,29,30,30,29,30,30,0,7,9),   
  29.         21=>array(0,30,29,30,29,29,30,29,29,30,29,30,30,0,8,10),   
  30.         22=>array(5,30,29,30,30,29,29,30,29,29,30,29,30,30,9,11),   
  31.         23=>array(0,29,30,30,29,30,29,30,29,29,30,29,30,0,10,12),   
  32.         24=>array(0,29,30,30,29,30,30,29,30,29,30,29,29,0,1,1),   
  33.         25=>array(4,30,29,30,29,30,30,29,30,30,29,30,29,30,2,2),   
  34.         26=>array(0,29,29,30,29,30,29,30,30,29,30,30,29,0,3,3),   
  35.         27=>array(0,30,29,29,30,29,30,29,30,29,30,30,30,0,4,4),   
  36.         28=>array(2,29,30,29,29,30,29,29,30,29,30,30,30,30,5,5),   
  37.         29=>array(0,29,30,29,29,30,29,29,30,29,30,30,30,0,6,6),   
  38.         30=>array(6,29,30,30,29,29,30,29,29,30,29,30,30,29,7,7),   
  39.         31=>array(0,30,30,29,30,29,30,29,29,30,29,30,29,0,8,8),   
  40.         32=>array(0,30,30,30,29,30,29,30,29,29,30,29,30,0,9,9),   
  41.         33=>array(5,29,30,30,29,30,30,29,30,29,30,29,29,30,10,10),   
  42.         34=>array(0,29,30,29,30,30,29,30,29,30,30,29,30,0,1,11),   
  43.         35=>array(0,29,29,30,29,30,29,30,30,29,30,30,29,0,2,12),   
  44.         36=>array(3,30,29,29,30,29,29,30,30,29,30,30,30,29,3,1),   
  45.         37=>array(0,30,29,29,30,29,29,30,29,30,30,30,29,0,4,2),   
  46.         38=>array(7,30,30,29,29,30,29,29,30,29,30,30,29,30,5,3),   
  47.         39=>array(0,30,30,29,29,30,29,29,30,29,30,29,30,0,6,4),   
  48.         40=>array(0,30,30,29,30,29,30,29,29,30,29,30,29,0,7,5),   
  49.         41=>array(6,30,30,29,30,30,29,30,29,29,30,29,30,29,8,6),   
  50.         42=>array(0,30,29,30,30,29,30,29,30,29,30,29,30,0,9,7),   
  51.         43=>array(0,29,30,29,30,29,30,30,29,30,29,30,29,0,10,8),   
  52.         44=>array(4,30,29,30,29,30,29,30,29,30,30,29,30,30,1,9),   
  53.         45=>array(0,29,29,30,29,29,30,29,30,30,30,29,30,0,2,10),   
  54.         46=>array(0,30,29,29,30,29,29,30,29,30,30,29,30,0,3,11),   
  55.         47=>array(2,30,30,29,29,30,29,29,30,29,30,29,30,30,4,12),   
  56.         48=>array(0,30,29,30,29,30,29,29,30,29,30,29,30,0,5,1),   
  57.         49=>array(7,30,29,30,30,29,30,29,29,30,29,30,29,30,6,2),   
  58.         50=>array(0,29,30,30,29,30,30,29,29,30,29,30,29,0,7,3),   
  59.         51=>array(0,30,29,30,30,29,30,29,30,29,30,29,30,0,8,4),   
  60.         52=>array(5,29,30,29,30,29,30,29,30,30,29,30,29,30,9,5),   
  61.         53=>array(0,29,30,29,29,30,30,29,30,30,29,30,29,0,10,6),   
  62.         54=>array(0,30,29,30,29,29,30,29,30,30,29,30,30,0,1,7),   
  63.         55=>array(3,29,30,29,30,29,29,30,29,30,29,30,30,30,2,8),   
  64.         56=>array(0,29,30,29,30,29,29,30,29,30,29,30,30,0,3,9),   
  65.         57=>array(8,30,29,30,29,30,29,29,30,29,30,29,30,29,4,10),   
  66.         58=>array(0,30,30,30,29,30,29,29,30,29,30,29,30,0,5,11),   
  67.         59=>array(0,29,30,30,29,30,29,30,29,30,29,30,29,0,6,12),   
  68.         60=>array(6,30,29,30,29,30,30,29,30,29,30,29,30,29,7,1),   
  69.         61=>array(0,30,29,30,29,30,29,30,30,29,30,29,30,0,8,2),   
  70.         62=>array(0,29,30,29,29,30,29,30,30,29,30,30,29,0,9,3),   
  71.         63=>array(4,30,29,30,29,29,30,29,30,29,30,30,30,29,10,4),   
  72.         64=>array(0,30,29,30,29,29,30,29,30,29,30,30,30,0,1,5),   
  73.         65=>array(0,29,30,29,30,29,29,30,29,29,30,30,29,0,2,6),   
  74.         66=>array(3,30,30,30,29,30,29,29,30,29,29,30,30,29,3,7),   
  75.         67=>array(0,30,30,29,30,30,29,29,30,29,30,29,30,0,4,8),   
  76.         68=>array(7,29,30,29,30,30,29,30,29,30,29,30,29,30,5,9),   
  77.         69=>array(0,29,30,29,30,29,30,30,29,30,29,30,29,0,6,10),   
  78.         70=>array(0,30,29,29,30,29,30,30,29,30,30,29,30,0,7,11),   
  79.         71=>array(5,29,30,29,29,30,29,30,29,30,30,30,29,30,8,12),   
  80.         72=>array(0,29,30,29,29,30,29,30,29,30,30,29,30,0,9,1),   
  81.         73=>array(0,30,29,30,29,29,30,29,29,30,30,29,30,0,10,2),   
  82.         74=>array(4,30,30,29,30,29,29,30,29,29,30,30,29,30,1,3),   
  83.         75=>array(0,30,30,29,30,29,29,30,29,29,30,29,30,0,2,4),   
  84.         76=>array(8,30,30,29,30,29,30,29,30,29,29,30,29,30,3,5),   
  85.         77=>array(0,30,29,30,30,29,30,29,30,29,30,29,29,0,4,6),   
  86.         78=>array(0,30,29,30,30,29,30,30,29,30,29,30,29,0,5,7),   
  87.         79=>array(6,30,29,29,30,29,30,30,29,30,30,29,30,29,6,8),   
  88.         80=>array(0,30,29,29,30,29,30,29,30,30,29,30,30,0,7,9),   
  89.         81=>array(0,29,30,29,29,30,29,29,30,30,29,30,30,0,8,10),   
  90.         82=>array(4,30,29,30,29,29,30,29,29,30,29,30,30,30,9,11),   
  91.         83=>array(0,30,29,30,29,29,30,29,29,30,29,30,30,0,10,12),   
  92.         84=>array(10,30,29,30,30,29,29,30,29,29,30,29,30,30,1,1),   
  93.         85=>array(0,29,30,30,29,30,29,30,29,29,30,29,30,0,2,2),   
  94.         86=>array(0,29,30,30,29,30,30,29,30,29,30,29,29,0,3,3),   
  95.         87=>array(6,30,29,30,29,30,30,29,30,30,29,30,29,29,4,4),   
  96.         88=>array(0,30,29,30,29,30,29,30,30,29,30,30,29,0,5,5),   
  97.         89=>array(0,30,29,29,30,29,29,30,30,29,30,30,30,0,6,6),   
  98.         90=>array(5,29,30,29,29,30,29,29,30,29,30,30,30,30,7,7),   
  99.         91=>array(0,29,30,29,29,30,29,29,30,29,30,30,30,0,8,8),   
  100.         92=>array(0,29,30,30,29,29,30,29,29,30,29,30,30,0,9,9),   
  101.         93=>array(3,29,30,30,29,30,29,30,29,29,30,29,30,29,10,10),   
  102.         94=>array(0,30,30,30,29,30,29,30,29,29,30,29,30,0,1,11),   
  103.         95=>array(8,29,30,30,29,30,29,30,30,29,29,30,29,30,2,12),   
  104.         96=>array(0,29,30,29,30,30,29,30,29,30,30,29,29,0,3,1),   
  105.         97=>array(0,30,29,30,29,30,29,30,30,29,30,30,29,0,4,2),   
  106.         98=>array(5,30,29,29,30,29,29,30,30,29,30,30,29,30,5,3),   
  107.         99=>array(0,30,29,29,30,29,29,30,29,30,30,30,29,0,6,4),   
  108.         100=>array(0,30,30,29,29,30,29,29,30,29,30,30,29,0,7,5),   
  109.         101=>array(4,30,30,29,30,29,30,29,29,30,29,30,29,30,8,6),   
  110.         102=>array(0,30,30,29,30,29,30,29,29,30,29,30,29,0,9,7),   
  111.         103=>array(0,30,30,29,30,30,29,30,29,29,30,29,30,0,10,8),   
  112.         104=>array(2,29,30,29,30,30,29,30,29,30,29,30,29,30,1,9),   
  113.         105=>array(0,29,30,29,30,29,30,30,29,30,29,30,29,0,2,10),   
  114.         106=>array(7,30,29,30,29,30,29,30,29,30,30,29,30,30,3,11),   
  115.         107=>array(0,29,29,30,29,29,30,29,30,30,30,29,30,0,4,12),   
  116.         108=>array(0,30,29,29,30,29,29,30,29,30,30,29,30,0,5,1),   
  117.         109=>array(5,30,30,29,29,30,29,29,30,29,30,29,30,30,6,2),   
  118.         110=>array(0,30,29,30,29,30,29,29,30,29,30,29,30,0,7,3),   
  119.         111=>array(0,30,29,30,30,29,30,29,29,30,29,30,29,0,8,4),   
  120.         112=>array(4,30,29,30,30,29,30,29,30,29,30,29,30,29,9,5),   
  121.         113=>array(0,30,29,30,29,30,30,29,30,29,30,29,30,0,10,6),   
  122.         114=>array(9,29,30,29,30,29,30,29,30,30,29,30,29,30,1,7),   
  123.         115=>array(0,29,30,29,29,30,29,30,30,30,29,30,29,0,2,8),   
  124.         116=>array(0,30,29,30,29,29,30,29,30,30,29,30,30,0,3,9),   
  125.         117=>array(6,29,30,29,30,29,29,30,29,30,29,30,30,30,4,10),   
  126.         118=>array(0,29,30,29,30,29,29,30,29,30,29,30,30,0,5,11),   
  127.         119=>array(0,30,29,30,29,30,29,29,30,29,29,30,30,0,6,12),   
  128.         120=>array(4,29,30,30,30,29,30,29,29,30,29,30,29,30,7,1)   
  129.     );      
  130.     //农历天干       
  131.     $mten=$lnlunarcalendar['tiangan'];      
  132.     //农历地支       
  133.     $mtwelve=$lnlunarcalendar['dizhi'];      
  134.     //农历月份       
  135.     $mmonth=$lnlunarcalendar['month'];      
  136.     //农历日       
  137.     $mday=$lnlunarcalendar['day'];      
  138.     //阳历总天数 至1900年12月21日       
  139.     $total=69*365+17+11; //1970年1月1日前的就不算了       
  140.     if ($year=="" || $month=="" || ($year<1970 or $year>2020)) return ''//超出这个范围不计算       
  141.     //计算到所求日期阳历的总天数-自1900年12月21日始       
  142.     //先算年的和       
  143.     for ($y=1970; $y<$year;$y++){      
  144.         $total+=365;      
  145.         if ($y%4==0) $total ++;      
  146.     }      
  147.     //再加当年的几个月       
  148.     $total+=gmdate("z",gmmktime(0,0,0,$month,1,$year));      
  149.     //用农历的天数累加来判断是否超过阳历的天数       
  150.     $flag1=0; //判断跳出循环的条件       
  151.     $lcj=0;       
  152.     while ($lcj<=120){      
  153.         $lci=1;      
  154.         while ($lci<=13){      
  155.             $mtotal+=$everymonth[$lcj][$lci];      
  156.             if ($mtotal>=$total){      
  157.                 $flag1=1;      
  158.                 break;      
  159.             }      
  160.             $lci++;      
  161.         }      
  162.         if ($flag1==1) break;      
  163.         $lcj++;      
  164.     }      
  165.     //由上,得到的 $lci 为当前农历月, $lcj 为当前农历年       
  166.     //计算所求月份1号的农历日期       
  167.     $fisrtdaylunar=$everymonth[$lcj][$lci]-($mtotal-$total);      
  168.     $results['year']=$mten[$everymonth[$lcj][14]].$mtwelve[$everymonth[$lcj][15]]; //当前是什么年       
  169.     $daysthismonth=gmdate("t",gmmktime(0,0,0,$month,1,$year)); //当前月共几天       
  170.     $op=1;      
  171.     for ($i=1; $i<=$daysthismonth$i++) {      
  172.         $possiblelunarday=$fisrtdaylunar+$op-1; //理论上叠加后的农历日       
  173.         if ($possiblelunarday<=$everymonth[$lcj][$lci]) { //在本月的天数范畴内       
  174.             $results[$i]=$mday[$possiblelunarday];      
  175.             $op+=1;      
  176.         }      
  177.         else { //不在本月的天数范畴内       
  178.             $results[$i]=$mday[1]; //退回到1日       
  179.             $fisrtdaylunar=1;      
  180.             $op=2;      
  181.             $curmonthnum=($everymonth[$lcj][0]!=0) ? 13 : 12; //当年有几个月       
  182.             if ($lci+1>$curmonthnum) { //第13/14个月了,转到下一年       
  183.                 $lci=1;      
  184.                 $lcj=$lcj+1;      
  185.                 //换年头了,把新一年的天干地支也写上       
  186.                 $results['year'].='/'.$mten[$everymonth[$lcj][14]].$mtwelve[$everymonth[$lcj][15]];      
  187.             } else { //还在这年里       
  188.                 $lci=$lci+1;      
  189.                 $lcj=$lcj;      
  190.             }      
  191.         }      
  192.         if ($results[$i]==$mday[1]) { //每月的初一应该显示当月是什么月       
  193.             if ($everymonth[$lcj][0]!=0) { //有闰月的年       
  194.                 $monthss=($lci>$everymonth[$lcj][0]) ? ($lci-1) : $lci//闰月后的月数-1       
  195.                 if ($lci==$everymonth[$lcj][0]+1) { //这个月正好是闰月       
  196.                     $monthssshow=$mmonth[0].$mmonth[$monthss]; //前面加个闰字       
  197.                     $runyue=1;      
  198.                 } else {      
  199.                     $monthssshow=$mmonth[$monthss];      
  200.                 }      
  201.             } else {      
  202.                 $monthss=$lci;      
  203.                 $monthssshow=$mmonth[$monthss];      
  204.             }      
  205.             if ($monthss<=10 && $runyue!=1) $monthssshow.=$mmonth[13]; //只有1个字的月加上‘月’字       
  206.             $results[$i]=$monthssshow;      
  207.         }      
  208.     }      
  209.     return $results;      
  210. }      
  211. //忘了加上这个:       
  212. //农历用字       
  213. $lnlunarcalendar=array(      
  214. 'tiangan'=>array("未知","甲","乙","丙","丁","戊","己","庚","辛","壬","癸"),      
  215. 'dizhi'=>array("未知","子年(鼠)","丑年(牛)","寅年(虎)","卯年(兔)","辰年(龙)",      
  216.                "巳年(蛇)","午年(马)","未年(羊)","申年(猴)","酉年(鸡)","戌年(狗)","亥年(猪)"),      
  217. 'month'=>array("闰","正","二","三","四","五","六",      
  218.               "七","八","九","十","十一","十二","月"),      
  219. 'day'=>array("未知","初一","初二","初三","初四","初五","初六","初七","初八","初九","初十",      
  220.             "十一","十二","十三","十四","十五","十六","十七","十八","十九","二十",      
  221.             "廿一","廿二","廿三","廿四","廿五","廿六","廿七","廿八","廿九","三十")      
  222. );   


原文地址:https://www.cnblogs.com/ghw0501/p/4733844.html