php实现农历公历日期的相互转换

农历(Lunar calendar)和公历(Gregorian calendar)是两种不同的日历系统。公历是基于太阳和地球的运动来计算时间的,而农历是基于月亮的运动来计算时间的。

农历中的月份是根据月亮的相对位置来确定的,而公历中的月份是固定的。因此,农历和公历中的月份长度是不同的。同时,农历中还有闰月的概念,这是公历中没有的。

转换农历日期到公历日期的过程需要计算农历中的每个月的长度,以及闰月的存在情况。这些信息可以通过农历算法来计算得到。反之,转换公历日期到农历日期也是同样的原理。

简单来说,农历公历日期转换原理就是利用农历算法通过计算月亮的相对位置和地球和太阳的运动来确定农历日期和公历日期之间的对应关系。

凡是涉及日历、日程的程序,或多或少会用到这一功能,本文用php实现农历公历日期的相互转换。

首先定义两个函数,分别为solarToLunar和lunarToSolar。

solarToLunar用于将公历转换为农历。

/**
 * 将公历日期转换为农历日期
 * @param int $year 公历年份
 * @param int $month 公历月份
 * @param int $day 公历日期
 * @return array
 *   array[0] : 农历年份
 *   array[1] : 农历月份
 *   array[2] : 农历日期
 */
function solarToLunar($solarYear, $solarMonth, $solarDay) {
    $lunar_date = array();

    $y = $solarYear;
    $m = $solarMonth;
    $d = $solarDay;
    $x = 0;
    $dx = 0;
    $l = 0;
    $dl = 0;
    $y = ($m == 1 || $m == 2) ? $y - 1 : $y;
    $x = floor(($y - 1) / 4);
    $dx = ($y - 1) % 4;
    $l = floor(($y - 1) / 12);
    $dl = ($y - 1) % 12;
    $sum = floor(365.25 * $y) - floor(7 * $x + 2375006.5) + floor(30.6 * ($m + 1)) + $d - 1;
    $sum -= floor(3 * $l + 1867216.25 / 12) - floor(($dl + 7) / 12) - floor(($dl + 11) * 30.6);
    $lunar_year = floor(($sum + 7) / 291669 * 12 + 101);
    $lunar_month = floor($sum / 291669 * 12 + 1) - $lunar_year * 12;
    $lunar_day = $sum - floor(291669 * ($lunar_month - 1) / 12) + 1;
    $lunar_date = array("year" => $lunar_year, "month" => $lunar_month, "day" => $lunar_day);

    return $lunar_date;
}

lunarToSolar用于将农历转换为公历。

/**
 * 将农历日期转换为公历日期
 * @param int $year 农历年份
 * @param int $month 农历月份,闰月为负数
 * @param int $day 农历日期
 * @return array
 *   array[0] : 公历年份
 *   array[1] : 公历月份
 *   array[2] : 公历日期
 */
function lunarToSolar($year, $month, $day)
{
    $leap_month = getLeapMonth($year);
    // 判断是否为闰月
    if ($month < 0) {
        $month = abs($month);
        $is_leap_month = true;
    } else {
        $is_leap_month = false;
    }
    $lunar_days = getLunarMonthDays($year, $month);
    // 计算农历距离公历元年的天数
    $lunar_offset = getLunarYearDays($year) + getLunarMonthDays($year, $month) + $day - 1;
    // 公历元年为1900年,每年的天数为365天或366天
    $solar_year = 1900;
    $solar_days = 365;
    while ($lunar_offset >= $solar_days) {
        $solar_year++;
        $solar_days = isLeapYear($solar_year) ? 366 : 365;
        $lunar_offset -= $solar_days;
    }
    // 根据天数计算公历月份和日期
    $solar_month = 1;
    while ($lunar_offset >= getSolarMonthDays($solar_year, $solar_month)) {
        $lunar_offset -= getSolarMonthDays($solar_year, $solar_month);
        $solar_month++;
    }
    $solar_day = $lunar_offset + 1;
    return array($solar_year, $solar_month, $solar_day);
}

下面的代码用于辅助实现日期转换。

  1. 定义天干、地支、生肖等数组。

$gan = array("甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸");
$zhi = array("子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥");
$shengxiao = array("鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪");
  1. 利用公式计算天干地支:

$ganIndex = ($lunar_date["year"] - 3) % 10;
$zhiIndex = ($lunar_date["year"] - 3) % 12;
  1. 计算生肖:

$shengxiaoIndex = ($lunar_date["year"] - 4) % 12;
  1. 将天干、地支、生肖拼接成字符串:

$ganzhi = $gan[$ganIndex] . $zhi[$zhiIndex];
$shengxiao = $shengxiao[$shengxiaoIndex];

以上就是实现天干地支和生肖转换的代码。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Evaporator Core

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值