PHP Class for Converting Between Solar (Gregorian) and Lunar (Chinese) Calendars
This article presents a PHP class that implements algorithms for converting Gregorian dates to Chinese lunar dates and vice versa, including utilities for leap year detection, month length calculation, zodiac retrieval, and handling of leap months, with complete source code examples and usage demonstration.
The provided PHP class, Lunar , offers a comprehensive set of methods to convert dates between the Gregorian (solar) calendar and the traditional Chinese lunar calendar. It includes functionality to determine leap years, calculate the number of days in both solar and lunar months, retrieve the lunar year name (Heavenly Stems and Earthly Branches), and obtain the zodiac animal for a given lunar year.
Key methods include:
convertSolarToLunar($year, $month, $date) – converts a Gregorian date to its corresponding lunar date.
convertLunarToSolar($year, $month, $date) – converts a lunar date back to the Gregorian calendar.
isLeapYear($year) – checks whether a given year is a leap year.
getSolarMonthDays($year, $month) – returns the number of days in a specific Gregorian month, accounting for leap years.
getLunarMonthDays($year, $month) – returns the number of days in a specific lunar month.
getLunarYearDays($year) – calculates the total number of days in a lunar year.
getLunarYearName($year) – returns the traditional Chinese year name (Heavenly Stem and Earthly Branch).
getYearZodiac($year) – returns the zodiac animal for the lunar year.
The class stores pre‑computed lunar data in the $lunarInfo array, which encodes month lengths, leap month information, and the Gregorian month/day of the lunar new year for each year from 1891 to 2100. Helper methods such as getDaysBetweenSolar and getDaysBetweenLunar compute day offsets needed for the conversions.
Below is the complete source code of the class along with a short usage example that converts the Gregorian date 2017‑03‑09 to its lunar equivalent and prints the result.
<code><?php
class Lunar {
var $MIN_YEAR = 1891;
var $MAX_YEAR = 2100;
var $lunarInfo = array(
array(0,2,9,21936), array(6,1,30,9656), /* ... many more entries ... */ array(0,2,9,54560)
);
/**
* 将阳历转换为阴历
* @param year 公历-年
* @param month 公历-月
* @param date 公历-日
*/
function convertSolarToLunar($year, $month, $date) {
$yearData = $this->lunarInfo[$year - $this->MIN_YEAR];
if ($year == $this->MIN_YEAR && $month <= 2 && $date <= 9) {
return array(1891, '正月', '初一', '辛卯', 1, 1, '兔');
}
return $this->getLunarByBetween($year, $this->getDaysBetweenSolar($year, $month, $date, $yearData[1], $yearData[2]));
}
/**
* 将阴历转换为阳历
* @param year 阴历-年
* @param month 阴历-月,闰月处理:例如如果当年闰五月,那么第二个五月就传六月
* @param date 阴历-日
*/
function convertLunarToSolar($year, $month, $date) {
$yearData = $this->lunarInfo[$year - $this->MIN_YEAR];
$between = $this->getDaysBetweenLunar($year, $month, $date);
$res = mktime(0,0,0,$yearData[1],$yearData[2],$year);
$res = date('Y-m-d', $res + $between * 24 * 60 * 60);
list($year,$month,$day) = explode('-', $res);
return array($year,$month,$day);
}
function isLeapYear($year) {
return (($year % 4 == 0 && $year % 100 != 0) || ($year % 400 == 0));
}
// ... additional methods omitted for brevity ...
}
header("Content-Type:text/html;charset=utf-8");
$lunar = new Lunar();
$month = $lunar->convertSolarToLunar('2017','03','09'); // 将阳历转换为阴历
echo '<pre>';
print_r($month);
?>
</code>This implementation can be integrated into backend systems that require accurate conversion between Gregorian and Chinese lunar dates, such as scheduling applications, cultural event platforms, or historical data processing tools.
php中文网 Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.