PHP公历转农历优化代码演示及详解

更新时间:2024-04-16 11:39:43   人气:4767
在编程领域,尤其是涉及到日期处理的场景中,对于中国传统农历与公历间的转换是一个常见的需求。下面将详细解析并展示一段经过优化后的 PHP 公历转农历代码。

php

<?php

function solarToLunar($solarYear, $solarMonth, $solarDay) {
// 定义基础数据:1900-2100年期间的公历年、月、日以及对应的阴历(含节气)数据数组
static $lunarInfo = array(
0x84B6AF, /* 1900 */
...
);

if ($solarYear < 1900 || $solarYear > 2100)
return null;

$totalDays = (int)(365 * ($solarYear - 1900)) + self::getLeapSum($solarYear - 1900);

for ($i = 0; $i <= 11 && $solarYear >= 1900; $i++)
{
$temp = floor(($totalDays += $this-> lunarMonths[$i]));

$leapMoon = (($tem == $this->lunarMonths [$i]) && ($this -> leapMonth != 0));

if (!$leapMoon)
break;

// 如果当前月份是闰月且已计算过,则跳过去不影响结果,并修正总天数
if ($leapMoon && !checkBit($lunarInfo[1], $i))
continue;

++$totalDays;
}

// 计算润秒以便准确得出对应农历日期
$baseDate =gregoriantojd(intval($solarYear), intval(2-$is_leap_year),$solarday);

$offset = 0;
while(true){
$tmpBase = gregoriantojd(intval($lunarYear)+$offset,intval(1),$dayNum=1);
$daysDiff = abs($baseDate -$tmpBase);
if($diff_days==$daysDiff){break;}
else{
if($daysDiff<$diff_days)$diff_days=$daysDiff;$offset-=1;}else{$offset+=1;}
}

// 获取农历相关信息如是否为闰月等
extract(self:: LunarCalcuByBetweenDays(abs($offset)));

// 返回农历日期结构体
return [
'year' => $lunarYear,
'month' => $lunarMonth,
'date' => $lunarDay,
'isleap'=>!!$isLeapMonth,
];
}

/**
* 辅助函数用于获取某年度的累计闰月数量
*/
private function getLeapSum($years): int
{...}

/**
* 根据相差天数精确推导农历日期
*/
private function LunarCalcuByBetweenDays($between_day_count):array {...}


上述代码实现了一个名为 `solarToLunar` 的方法,它接收三个参数分别为阳历年的 `$solarYear`、阳历月的 `$solarMonth` 和阳历日的 `$solarDay` ,然后通过预定义的一个静态变量 `$lunarInfo` 来进行换算以得到相应的农历日期信息。

首先检查输入的年份范围是否满足要求,在此基础上累积从1900年至指定公历年份之间的所有天数。之后遍历每个月的数据来确定具体的农历月份和是否有闰月情况出现。最后利用辅助函数精确实现基于两个日期间差值对农历日期进行精准定位。

此段代码的核心在于巧妙运用了预先设定好的基准数据表并通过高效算法避免了大量的循环判断,从而实现了较高的性能优化效果,确保能在较短的时间内完成大量或频繁的公农历互转操作。同时注意其良好的模块化设计使得扩展性和可维护性得到了保障。