PHP Lunar Calendar Gregorian Calendar Conversion
- /*
- Written by Yang Haixi, School of Computer Science and Engineering, Qujing Normal University, Yunnan Province
- 2009-9-3
- */
- class Lunar
- {
- private $_SMDay = array(1 => 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);//Define the number of days in the Gregorian calendar month
- private $_LStart = 1950;//The lunar calendar starts in 1950
- private $_LMDay = array(
- //Difference: the number of days from the first day of the first lunar month of the year to January 1 of the Gregorian calendar; 1~12: the number of days in the lunar month; leap: if there is a leap month, record the number of ordinary days in the month
- //Difference 1 2 3 4 5 6 7 8 9 10 11 12 leap
- array(47,29,30,30,29,30,30,29,29,30,29,30,29),
- array(36,30, 29,30,30,29,30,29,30,29,30,29,30),
- array(6,29,30,29,30,59,29,30,30,29,30,29, 30,29), //May 29 Leap May 30
- array(44,29,30,29,29,30,30,29,30,30,29,30,29),
- array(33,30 ,29,30,29,29,30,29,30,30,29,30,30),
- array(23,29,30,59,29,29,30,29,30,29,30,30 ,30,29), //March 29 Leap March 30
- array(42,29,30,29,30,29,29,30,29,30,29,30,30),
- array(30, 30,29,30,29,30,29,29,59,30,29,30,29,30), //August 30 Leap August 29
- array(48,30,30,30,29,30 ,29,29,30,29,30,29,30),
- array(38,29,30,30,29,30,29,30,29,30,29,30,29),
- array(27 ,30,29,30,29,30,59,30,29,30,29,30,29,30), //June 30 Leap June 29
- array(45,30,29,30,29, 30,29,30,30,29,30,29,30),
- array(35,29,30,29,29,30,29,30,30,29,30,30,29),
- array( 24,30,29,30,58,30,29,30,29,30,30,30,29,29), //April 29 Leap April 29
- array(43,30,29,30,29 ,29,30,29,30,29,30,30,30),
- array(32,29,30,29,30,29,29,30,29,29,30,30,29),
- array (20,30,30,59,30,29,29,30,29,29,30,30,29,30), //March 30 Leap March 29
- array(39,30,30,29, 30,30,29,29,30,29,30,29,30),
- array(29,29,30,29,30,30,29,59,30,29,30,29,30,30) , //July 30 Leap July 29
- array(47,29,30,29,30,29,30,30,29,30,29,30,29),
- array(36,30,29,29 ,30,29,30,30,29,30,30,29,30),
- array(26,29,30,29,29,59,30,29,30,30,30,29,30,30 ), //May 30 Leap May 29
- array(45,29,30,29,29,30,29,30,29,30,30,29,30),
- array(33,30,29, 30,29,29,30,29,29,30,30,29,30),
- array(22,30,30,29,59,29,30,29,29,30,30,29,30, 30), //April 30 Leap April 29
- array(41,30,30,29,30,29,29,30,29,29,30,29,30),
- array(30,30,30 ,29,30,29,30,29,59,29,30,29,30,30), //August 30 Leap August 29
- array(48,30,29,30,30,29,30, 29,30,29,30,29,29),
- array(37,30,29,30,30,29,30,30,29,30,29,30,29),
- array(27,30, 29,29,30,29,60,29,30,30,29,30,29,30), //June 30 Leap June 30
- array(46,30,29,29,30,29,30 ,29,30,30,29,30,30),
- array(35,29,30,29,29,30,29,29,30,30,29,30,30),
- array(24,30 ,29,30,58,30,29,29,30,29,30,30,30,29), //April 29 Leap April 29
- array(43,30,29,30,29,29, 30,29,29,30,29,30,30),
- array(32,30,29,30,30,29,29,30,29,29,59,30,30,30), //ten Month 30 Leap October 29
- array(50,29,30,30,29,30,29,30,29,29,30,29,30),
- array(39,29,30,30,29,30 ,30,29,30,29,30,29,29),
- array(28,30,29,30,29,30,59,30,30,29,30,29,29,30), // June 30 Leap June 29
- array(47,30,29,30,29,30,29,30,30,29,30,30,29),
- array(36,30,29,29,30, 29,30,29,30,29,30,30,30),
- array(26,29,30,29,29,59,29,30,29,30,30,30,30,30), / /May 30 Leap May 29
- array(45,29,30,29,29,30,29,29,30,29,30,30,30),
- array(34,29,30,30,29 ,29,30,29,29,30,29,30,30),
- array(22,29,30,59,30,29,30,29,29,30,29,30,29,30), //March 30 Leap March 29
- array(40,30,30,30,29,30,29,30,29,29,30,29,30),
- array(30,29,30,30, 29,30,29,30,59,29,30,29,30,30), //August 30 Leap August 29
- array(49,29,30,29,30,30,29,30,29 ,30,30,29,29),
- array(37,30,29,30,29,30,29,30,30,29,30,30,29),
- array(27,30,29,29 ,30,58,30,30,29,30,30,29,30,29), //May 29 Leap May 29
- array(46,30,29,29,30,29,29,30, 29,30,30,30,29),
- array(35,30,30,29,29,30,29,29,30,29,30,30,29),
- array(23,30,30, 29,59,30,29,29,30,29,30,29,30,30), //April 30 Leap April 29
- array(42,30,30,29,30,29,30,29 ,29,30,29,30,29),
- array(31,30,30,29,30,30,29,30,29,29,30,29,30),
- array(21,29,59 ,30,30,29,30,29,30,29,30,29,30,30), //February 30 Leap February 29
- array(39,29,30,29,30,29,30, 30,29,30,29,30,29),
- array(28,30,29,30,29,30,29,59,30,30,29,30,30,30), //July 30 Leap July 29
- array(48,29,29,30,29,29,30,29,30,30,30,29,30),
- array(37,30,29,29,30,29,29 ,30,29,30,30,29,30),
- array(25,30,30,29,29,59,29,30,29,30,29,30,30,30), //May 30 Leap May 29
- array(44,30,29,30,29,30,29,29,30,29,30,29,30),
- array(33,30,29,30,30,29, 30,29,29,30,29,30,29),
- array(22,30,29,30,59,30,29,30,29,30,29,30,29,30), //four Month 30 Leap April 29
- array(40,30,29,30,29,30,30,29,30,29,30,29,30),
- array(30,29,30,29,30,29 ,30,29,30,59,30,29,30,30), //September 30 Leap September 29
- array(49,29,30,29,29,30,29,30,30,30,29,30,29),
- array(38,30,29,30,29,29,30,29,30, 30,29,30,30),
- array(27,29,30,29,30,29,59,29,30,29,30,30,30,29), //June 29 Leap June 30
- array(46,29,30,29,30,29,29,30,29,30,29,30,30),
- array(35,30,29,30,29,30,29,29,30 ,29,29,30,30),
- array(24,29,30,30,59,30,29,29,30,29,30,29,30,30), //April 30 Leap April 29
- array(42,29,30,30,29,30,29,30,29,30,29,30,29),
- array(31,30,29,30,29,30,30,29, 30,29,30,29,30),
- array(21,29,59,29,30,30,29,30,30,29,30,29,30,30), //February 30 leap day Month 29
- array(40,29,30,29,29,30,29,30,30,29,30,30,29),
- array(28,30,29,30,29,29,59,30 ,29,30,30,30,29,30), //June 30 Leap June 29
- array(47,30,29,30,29,29,30,29,29,30,30,30, 29),
- array(36,30,30,29,30,29,29,30,29,29,30,30,29),
- array(25,30,30,30,29,59,29, 30,29,29,30,30,29,30), //May 30 Leap May 29
- array(43,30,30,29,30,29,30,29,30,29,29,30 ,30),
- array(33,29,30,29,30,30,29,30,29,30,29,30,29),
- array(22,29,30,59,30,29,30 ,30,29,30,29,30,29,30), //March 30 Leap March 29
- array(41,30,29,29,30,29,30,30,29,30,30, 29,30),
- array(30,29,30,29,29,30,29,30,29,30,30,59,30,30), //November 30 Leap November 29
- array (49,29,30,29,29,30,29,30,29,30,30,29,30),
- array(38,30,29,30,29,29,30,29,29,30 ,30,29,30),
- array(27,30,30,29,30,29,59,29,29,30,29,30,30,29), //June 29 Leap June 30
- array(45,30,30,29,30,29,29,30,29,29,30,29,30),
- array(34,30,30,29,30,29,30,29,30, 29,29,30,29),
- array(23,30,30,29,30,59,30,29,30,29,30,29,29,30), //May 30 Leap May 29
- array(42,30,29,30,30,29,30,29,30,30,29,30,29),
- array(31,29,30,29,30,29,30,30,29 ,30,30,29,30),
- array(21,29,59,29,30,29,30,29,30,30,29,30,30,30), //February 30 Leap February 29
- array(40,29,30,29,29,30,29,29,30,30,29,30,30),
- array(29,30,29,30,29,29,30,58, 30,29,30,30,30,29), //July 29 Leap July 29
- array(47,30,29,30,29,29,30,29,29,30,29,30,30 ),
- array(36,30,29,30,29,30,29,30,29,29,30,29,30),
- array(25,30,29,30,30,59,29,30 ,29,29,30,29,30,29), //May 29 Leap May 30
- array(44,29,30,30,29,30,30,29,30,29,29,30, 29),
- array(32,30,29,30,29,30,30,29,30,30,29,30,29),
- array(22,29,30,59,29,30,29, 30,30,29,30,30,29,29), //March 29 Leap March 30
- );
- //Whether it is a leap year
- private function IsLeapYear($AYear){
- return ($AYear % 4 == 0) && (($AYear % 100 != 0) || ($AYear % 400 == 0));
- }
- //The number of days in the month in the Gregorian calendar (year: year; month: month)
- private function GetSMon( $year,$month)
- {
- if($this->IsLeapYear($year) && $month == 2)
- return 29;
- else
- return $this->_SMDay[$month];
- }
- //Lunar calendar name conversion
- private function LYearName($year)
- {
- $Name = array("zero","one","two","three","four","five","six"," seven","eight","nine");
- for($i=0;$i<4;$i++)
- for($k=0;$k<10;$k++)
- if($year[ $i]==$k)
- $tmp.=$Name[$k];
- return $tmp;
- }
-
- private function LMonName($month)
- {
- if($month >=1 && $month <=12 )
- {
- $Name = array( 1=>"正","二","三","四","五","六","七","八"," nine","ten","eleven","twelve");
- return $Name[$month];
- }
- return $month;
- }
-
- private function LDayName($day)
- {
- if( $day >=1 && $day <=30 )
- {
- $Name = array( 1 =>
- "First day of junior high school", "Second day of junior high school", "Third day of junior high school", "Fourth day of junior high school", "Fifth day of junior high school" ","The sixth day of the lunar month","The seventh day of the lunar month","The eighth day of the lunar month","The ninth day of the lunar month","The tenth day of the lunar month",
- "Eleventh","Twelve","Thirteenth","Fourteenth","Tenth "Five", "Sixteen", "Seventeen", "Eighteen", "Nineteen", "Twenty",
- "Twenty-one", "Twenty-two", "Twenty-three", "Twenty-four", " "Twenty-five", "Twenty-six", "Twenty-seven", "Twenty-eight", "Twenty-nine", "Thirty"
- );
- return $Name[$day];
- }
- return $day;
- }
-
- //Convert Gregorian calendar to lunar calendar (Sdate: Gregorian calendar date)
- public function S2L($date)
- {
- list($year, $month, $day) = explode("-", $date);
- if($ year <= 1951 || $month <= 0 || $day <= 0 || $year >= 2051 ) return false;
- //Get the number of days from the query date to January 1st of the current year
- $date1 = strtotime($year."-01-01");//January 1 of the current year
- $date2 = strtotime($year."-".$month."-".$day);
- $days=round (($date2-$date1)/3600/24);
- $days += 1;
- //Get the corresponding annual lunar calendar data and turn it into an array Larray
- $Larray = $this->_LMDay[$year - $this- >_LStart];
- if($days <= $Larray[0])
- {
- $Lyear = $year - 1;
- $days = $Larray[0] - $days;
- $Larray = $this- >_LMDay[$Lyear - $this->_LStart];
- if($days < $Larray[12])
- {
- $Lmonth = 12;
- $Lday = $Larray[12] - $days;
- }
- else
- {
- $Lmonth = 11;
- $days = $days - $Larray[12];
- $Lday = $Larray[11] - $days;
- }
- }
- else
- {
- $Lyear = $ year;
- $days = $days - $Larray[0];
- for($i = 1;$i <= 12;$i++)
- {
- if($days > $Larray[$i]) $ days = $days - $Larray[$i];
- else
- {
- if ($days > 30){
- $days = $days - $Larray[13];
- $Ltype = 1;
- }
-
- $ Lmonth = $i;
- $Lday = $days;
- break;
- }
- }
- }
- return mktime(0, 0, 0, $Lmonth, $Lday, $Lyear);
- //$Ldate = $Lyear. "-".$Lmonth."-".$Lday;
- //$Ldate = $this->LYearName($Lyear)."Year".$this->LMonName($Lmonth)."Month". $this->LDayName($Lday);
- //if($Ltype) $Ldate.="(Leap)";
- //return $Ldate;
- }
- //Convert lunar calendar to Gregorian calendar (date: lunar calendar date; type: whether it is a leap month)
- public function L2S($date,$type = 0)
- {
- list($year, $month, $day) = split("-",$date);
- if($year < = 1951 || $month <= 0 || $day <= 0 || $year >= 2051 ) return false;
- $Larray = $this->_LMDay[$year - $this->_LStart ];
- if($type == 1 && count($Larray)<=12 ) return false;//Request to query leap month, but no leap month is found
- //If the lunar calendar being queried is a leap month and the lunar calendar array of the year contains a leap month Get the data
- if($Larray[$month]>30 && $type == 1 && count($Larray) >=13) $day = $Larray[13] + $day;
- //Get the year The number of days from the lunar date to January 1 of the Gregorian calendar
- $days = $day;
- for($i=0;$i<=$month-1;$i++)
- $days += $Larray[$i];
- //When querying the lunar date is more than one year from January 1 of the Gregorian calendar
- if($days > 366 || ($this->GetSMon($month,2)!=29 && $days>365 ))
- {
- $Syear = $year +1;
- if($this->GetSMon($month,2)!=29)
- $days-=366;
- else
- $days-=365;
- if($days > $this->_SMDay[1])
- {
- $Smonth = 2;
- $Sday = $days - $this->_SMDay[1];
- }
- else
- {
- $Smonth = 1;
- $Sday = $days;
- }
- }
- else
- {
- $Syear =$year;
- for($i=1;$i<=12;$i++)
- {
- if($days > $this- >GetSMon($Syear,$i))
- $days-=$this->GetSMon($Syear,$i);
- else
- {
- $Smonth = $i;
- $Sday = $days;
- break ;
- }
- }
- }
- return mktime(0, 0, 0, $Smonth, $Sday, $Syear);
- //$Sdate = $Syear."-".$Smonth."-".$Sday;
- //return $Sdate;
- }
- }
- ?>
Copy code
- require_once 'Lunar.php';
- $today = date("Y-m-d");
- $lunar = new Lunar();
- //Gregorian calendar to lunar calendar
- $nl = date("Y-m-d ",$lunar->S2L($today));
- //Convert lunar calendar to Gregorian calendar
- $gl = date("Y-m-d",$lunar->L2S($nl));
- echo "Today's Gregorian calendar is:$ today
";
- echo "The conversion to the lunar calendar is: $nl
";
- echo "The conversion to the Gregorian calendar is: $gl
";
- ?>
Copy Code
|