Fonction calendrier solaire à calendrier lunaire

1, Idée de conception :

Pour calculer quel jour du calendrier lunaire correspond une heure donnée, nous devons trouver une heure de référence, puis utiliser cette heure de référence pour calculer les heures futures. Calculez d’abord le nombre de jours de différence entre l’heure actuelle et l’heure de référence, puis en trouvant le nombre de jours dans chaque année du calendrier lunaire, calculez à quel jour de l’année correspond l’heure actuelle, et enfin calculez à quelle date appartient à ce mois-là.

2, créez un nouveau fichier Convert.class.php ;

encapsulez la fonction de conversion, le code est le suivant :

<?php
header("Content-type:text/html;charset=utf-8");
class Convert{
    private $animals=array("鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪");
    private $curData=null;//当前阳历时间
    private $ylYeal=0;
    private $ylMonth=0;
    private $yldate=0;
    private $ylDays=0; //当前日期是农历年的第多少天
    private $leap=0;//代表润哪一个月
    private $leapDays=0;//代表闰月的天数
    private $difmonth=0;//当前时间距离参考时间相差多少月
    private $difDay=0;//当前时间距离参考时间相差多少天
    private $tianGan=array("甲","乙","丙","丁","戊","己","庚","辛","壬","癸");
    private $diZhi=array("子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥");
    private $dataInfo=array(0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909
        0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919
        0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929
        0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939
        0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-1949
        0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,//1950-1959
        0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,//1960-1969
        0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,//1970-1979
        0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,//1980-1989
        0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,//1990-1999
        0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,//2000-2009
        0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,//2010-2019
        0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,//2020-2029
        0x05aa0,0x076a3,0x096d0,0x04bd7,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039
        0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049
        /**Add By JJonline@JJonline.Cn**/
        0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50, 0x06b20,0x1a6c4,0x0aae0,//2050-2059
        0x0a2e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,//2060-2069
        0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,//2070-2079
        0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,//2080-2089
        0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,//2090-2099
        0x0d520);
    public function __construct($curData=null){
        if(!empty($curData)){
            $this->curData=$curData;
        }else{
            $this->curData=date('Y-n-j');
        }
        $this->init();
    }
    public function init(){
        $basedate='1900-2-1';//参照日期
        $timezone='PRC';
        $datetime= new DateTime($basedate, new DateTimeZone($timezone));
        $curTime=new DateTime($this->curData, new DateTimeZone($timezone));
        $offset   = ($curTime->format('U') - $datetime->format('U'))/86400; //相差的天数
        $offset=ceil($offset);
        $this->difDay=$offset;
        $offset+=1;//只能使用ceil,不能使用intval或者是floor,因为1900-1-31为正月初一,故需要加1
        for($i=1900; $i<2050 && $offset>0; $i++){
            $temp = $this->getYearDays($i); //计算i年有多少天
            $offset -= $temp ;
            $this->difmonth+=12;
            //判断该年否存在闰月
            if($this->leapMonth($i)>0){
                $this->difmonth+=1;
            }
        }
        if($offset<0){
            $offset += $temp;
            $i--;
            $this->difmonth-=12;
        }
        if($this->leapMonth($i)>0){
            $this->difmonth-=1;
        }
        $this->ylDays=$offset;
        //此时$offset代表是农历该年的第多少天
        $this->ylYeal=$i;//农历哪一年
        //计算月份,依次减去1~12月份的天数,直到offset小于下个月的天数
        $curMonthDays=$this->monthDays($this->ylYeal,1);
        //判断是否该年是否存在闰月以及闰月的天数
        $this->leap=$this->leapMonth($this->ylYeal);
        if($this->leap !=0){
            $this->leapDays=$this->leapDays($this->ylYeal);
        }
        for($i=1;$i<13 && $curMonthDays<$offset;$curMonthDays=$this->monthDays($this->ylYeal,++$i)){
            if($this->leap == $i){ //闰月
                if($offset>$this->leapDays){
                    --$i;
                    $offset-=$this->leapDays;
                    $this->difmonth+=1;
                }else{
                    break;
                }
            }else{
                $offset-=$curMonthDays;
                $this->difmonth+=1;
            }
        }
        $this->ylMonth=$i;
        $this->yldate=$offset;
    }
    /**
     *计算农历y年有多少天
     **/
    public function getYearDays($y){
        $sum = 348;//12*29=348,不考虑小月的情况下
        for($i=0x8000; $i>=0x10; $i>>=1){
            $sum += ($this->dataInfo[$y-1900] & $i)? 1: 0;
        }
        return($sum+$this->leapDays($y));
    }
    /**
     *获取某一年闰月的天数
     **/
    public function leapDays($y){
        if($this->leapMonth($y)){
            return(($this->dataInfo[$y-1900] & 0x10000)? 30: 29);
        } else {
            return(0);
        }
    }
    /**
     *计算哪一月为闰月
     */
    public  function leapMonth($y){
        return ($this->dataInfo[$y-1900] & 0xf);
    }
    /**
     *计算农历y年m月有多少天
     */
    public function monthDays($y,$m){
        return (($this->dataInfo[$y-1900] & (0x10000>>$m))? 30: 29 );
    }
    public function getLyTime(){
        $tmp=array('初','一','二','三','四','五','六','七','八','九','十','廿');
        $dateStr='';
        if($this->ylMonth>10){
            $m2=intval($this->ylMonth -10); //十位
            $dateStr='十'.$tmp[$m2].'月';
        }elseif($this->ylMonth==1){
            $dateStr='正月';
        }else{
            $dateStr=$tmp[$this->ylMonth].'月';
        }
        if($this->yldate <11){
            $dateStr.='初'.$tmp[$this->yldate];
        }else{
            $m1=intval($this->yldate / 10);
            if( $m1 !=3){
                $dateStr.=($m1==1)?'十':'廿';
                $m2=$this->yldate % 10;
                if($m2==0){
                    $dateStr.='十';
                }else{
                    $dateStr.=$tmp[$m2];
                }
            }else{
                $dateStr.='三十';
            }
        }
        return $dateStr;
    }
    /**
     *获取该年对于的天干地支年
     **/
    public function getYGanZhi(){
        $gan=$this->tianGan[($this->ylYeal-4) % 10];
        $zhi=$this->diZhi[($this->ylYeal-4) % 12];
        return $gan.$zhi.'年';
    }
    /**
     *获取该年对于的天干地支月
     **/
    public function getMGanZhi(){
        $gan=$this->tianGan[($this->difmonth+3) % 10];
        $zhi=$this->diZhi[($this->difmonth+1) % 12];
        return $gan.$zhi.'月';
    }
    /**
     *获取该年对于的天干地支日
     **/
    public function getDGanZhi(){
        $gan=$this->tianGan[$this->difDay % 10];
        $zhi=$this->diZhi[($this->difDay+4) % 12];
        return $gan.$zhi.'日';
    }
}

Modifier le code calendrier.php :

Ajouter get requête :

echo "<th onmouseOver='overTh(this)' onmouseOut='outTh(this)'><a href='?convert=$ymd'>{$d}</ a>< ;/th>";

Appelez la classe encapsulée :

<?php
$convert=isset($_GET["convert"])?$_GET["convert"]:date("Y-m-d");
if($convert!=''){
   $c=new Convert($convert);
   $time=$c->getLyTime();
//    echo $convert.'对应的农历时间:'.$time;
}
echo "<tr onmouseOver='overTr(this)'onmouseOut='outTr(this)'><td colspan='7' align='center'>";
echo "<div>$convert 对应的农历时间:$time</div>";

L'effet de l'opération est le suivant :

gif5新文件 (44).gif

Formation continue
||
<?php echo "阳历转阴历";
soumettreRéinitialiser le code
  • Recommandations de cours
  • Téléchargement du didacticiel