0
点赞
收藏
分享

微信扫一扫

php实现根据公历日期计算节气


节气的产生是由于地球的公转和自转的影响,当地球绕太阳公转时,太阳在地球表面上的位置不断变化,这样地球上的每个地点所接受到的阳光量和热量也不断变化,进而导致不同季节不同气候的变化。

公历的每一年分为24个节气,每个节气都对应着一个特定的天文现象,例如春分节气是在太阳到达黄道的那一天,而冬至节气则是在太阳到达黄经270°的那一天。每个节气都代表着一个季节的开始或者结束。

因此,通过计算每一天太阳所在的位置,我们可以得到该天所对应的节气,从而进行日期转节气的计算。

将阴历日期转换为节气

<?php

function getLunarSolarTerm($timestamp) {
$year = date('Y', $timestamp);
$month = date('n', $timestamp);
$day = date('j', $timestamp);

// 计算阴历
$lunar = new Lunar();
$lunar = $lunar->SolarToLunar($year, $month, $day);
$lunar_year = $lunar['lunar_year'];
$lunar_month = $lunar['lunar_month'];
$lunar_day = $lunar['lunar_day'];

// 计算节气
$solarTerm = new SolarTerm();
$solar_term = $solarTerm->getSolarTerm($lunar_year, $lunar_month, $lunar_day);
return $solar_term;
}

$timestamp = strtotime("2023-02-15");
$solar_term = getLunarSolarTerm($timestamp);
echo "The solar term on " . date('Y-m-d', $timestamp) . " is " . $solar_term;

接下来,来构建函数。

function solarToLunar($date) {
$dateArray = explode("-", $date);
$year = intval($dateArray[0]);
$month = intval($dateArray[1]);
$day = intval($dateArray[2]);

// 判断是否是闰年
$isLeap = false;
if (($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0) {
$isLeap = true;
}

// 每个月的天数
$monthDays = array(31, 28 + $isLeap, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

// 计算阴历的天数
$lunarDay = 0;
for ($i = 0; $i < $month - 1; $i++) {
$lunarDay += $monthDays[$i];
}
$lunarDay += $day;

// 将阴历天数转换为阴历月份和日
$lunarMonth = 0;
for ($i = 0; $i < 12; $i++) {
if ($lunarDay <= $monthDays[$i]) {
$lunarMonth = $i + 1;
break;
}
$lunarDay -= $monthDays[$i];
}
$lunar['lunar_year'] = $year;
$lunar['lunar_month'] = $lunarMonth;
$lunar['lunar_day'] = $lunarDay;
return $lunar;
}

注意到,还需要将阴历日期转换为节气。下面提供一个较为粗略的算法,实际上问题比较多。

function getSolarTerm($time) {
$solarTerms = array(
"小寒", "大寒", "立春", "雨水",
"惊蛰", "春分", "清明", "谷雨",
"立夏", "小满", "芒种", "夏至",
"小暑", "大暑", "立秋", "处暑",
"白露", "秋分", "寒露", "霜降",
"立冬", "小雪", "大雪", "冬至"
);

$d = (int)(($time - 31556925974.7 * floor($time / 31556925974.7)) / 36524.2259);
$g = $d + 114;
$solarTermsIndex = floor(($g - 1) * 24 / 365.2422) % 24;

return $solarTerms[$solarTermsIndex];
}

将阳历日期转换为节气

下面是阳历日期转换为节气的函数。

function getSolarTerm($date) {
$dateArray = explode("-", $date);
$year = intval($dateArray[0]);
$month = intval($dateArray[1]);
$day = intval($dateArray[2]);

// 节气表
$solarTermTable = array(
array(array(4,19),array(5,5)),
array(array(5,20),array(6,6)),
array(array(6,21),array(7,7)),
array(array(7,22),array(8,8)),
array(array(8,23),array(9,8)),
array(array(9,23),array(10,8)),
array(array(10,24),array(11,7)),
array(array(11,22),array(12,6)),
array(array(12,22),array(1,5)),
array(array(1,20),array(2,3)),
array(array(2,18),array(3,5)),
array(array(3,21),array(4,5)),
array(array(4,20),array(5,5)),
array(array(5,21),array(6,6)),
array(array(6,22),array(7,7)),
array(array(7,23),array(8,7)),
array(array(8,23),array(9,7)),
array(array(9,23),array(10,7)),
array(array(10,24),array(11,6)),
array(array(11,23),array(12,6)),
array(array(12,21),array(1,4)),
array(array(1,20),array(2,3)),
array(array(2,19),array(3,4)),
array(array(3,21),array(4,4)),
array(array(4,21),array(5,5)),
array(array(5,22),array(6,5)),
array(array(6,22),array(7,7)),
array(array(7,22),array(8,7)),
array(array(8,22),array(9,7)),
array(array(9,22),array(10,7)),
array(array(10,23),array(11,7)),
array(array(11,22),array(12,6)),
array(array(12,21),array(1,5)),
);

$solarTerms = array("小寒","大寒","立春","雨水","惊蛰","春分",
"清明","谷雨","立夏","小满","芒种","夏至",
"小暑","大暑","立秋","处暑","白露","秋分",
"寒露","霜降","立冬","小雪","大雪","冬至");

$idx = intval(($year - 1900) * 24.22 + ($month - 1) * 2);
if ($month == 12) {
if ($day >= $solarTermTable[$idx][1][0]) {
$idx ++;
}
}
else if ($month == 1) {
if ($day < $solarTermTable[$idx][0][0]) {
$idx --;
}
}
else if ($month == $solarTermTable[$idx][1][1]) {
if ($day >= $solarTermTable[$idx][1][0]) {
$idx ++;
}
}
else if ($month == $solarTermTable[$idx][0][1]) {
if ($day < $solarTermTable[$idx][0][0]) {
$idx --;
}
}

return $solarTerms[$idx % 24];
}

通过儒略日法转换节气

此算法基于计算机科学家 Peter Duffett-Smith 的节气计算方法。它通过使用儒略日数(Julian Day Number)来提高准确度,并通过计算与当前节气的距离来确定当前的节气。

function getSolarTerm($time) {
$solarTerms = array(
"小寒", "大寒", "立春", "雨水",
"惊蛰", "春分", "清明", "谷雨",
"立夏", "小满", "芒种", "夏至",
"小暑", "大暑", "立秋", "处暑",
"白露", "秋分", "寒露", "霜降",
"立冬", "小雪", "大雪", "冬至"
);

$d = JulianDayNumber($time) - 2451545.0;
$d0 = 365.2422 * floor($d / 365.2422);
$l = mod($d, 365.2422);
$g = (int)($l / 29.5306);
$t = mod($l, 29.5306);
$b = floor((($g * 6 + $t) * 24 + 12) / 365.2422);
$solarTermsIndex = $g * 2 + $b;

return $solarTerms[$solarTermsIndex];
}

function JulianDayNumber($time) {
$jd = 2440588 + floor($time / 86400);
$f = ($time / 86400.0 - floor($time / 86400.0)) * 86400.0;
$jd = $jd + $f / (3600 + 24) * (3600 + 24) / 3600;
return $jd;
}

function mod($a, $b) {
return $a - floor($a / $b) * $b;
}

举报

相关推荐

0 条评论