本文目录导读:

我来为你详细说明PHP后端推算二十四节气的实现方法。
基于天文算法的精确计算
完整实现代码
<?php
class SolarTermsCalculator {
/**
* 计算二十四节气
* @param int $year 年份
* @return array 返回该年的所有节气
*/
public function calculateYear($year) {
$terms = [];
// 二十四节气名称
$termNames = [
'小寒', '大寒', '立春', '雨水', '惊蛰', '春分',
'清明', '谷雨', '立夏', '小满', '芒种', '夏至',
'小暑', '大暑', '立秋', '处暑', '白露', '秋分',
'寒露', '霜降', '立冬', '小雪', '大雪', '冬至'
];
// 每个节气对应的月份(从1月开始)
for ($month = 1; $month <= 12; $month++) {
// 每个月的两个节气
$term1 = $this->calculateTerm($year, $month, 0); // 节气(如小寒、立春等)
$term2 = $this->calculateTerm($year, $month, 1); // 中气(如大寒、雨水等)
$terms[] = [
'name' => $termNames[($month - 1) * 2],
'date' => date('Y-m-d', $term1)
];
$terms[] = [
'name' => $termNames[($month - 1) * 2 + 1],
'date' => date('Y-m-d', $term2)
];
}
return $terms;
}
/**
* 计算单个节气
* @param int $year 年份
* @param int $month 月份 (1-12)
* @param int $type 0=节气, 1=中气
* @return int 时间戳
*/
private function calculateTerm($year, $month, $type) {
// 世纪常数
$century = ($year - 1900) / 100;
// 根据年份和月份计算节气参数
if ($year >= 1900 && $year <= 2099) {
$coefficient = $this->getCoefficient($year, $month, $type);
} else {
$coefficient = $this->getCoefficientOther($year, $month, $type);
}
// 计算节气日期(从1月1日开始的偏移天数)
$dayCount = $coefficient['days'];
$hour = $coefficient['hours'];
$minute = $coefficient['minutes'];
// 计算具体的日期时间
$baseTime = mktime(0, 0, 0, 1, 1, $year);
$termTime = $baseTime + ($dayCount - 1) * 86400 + $hour * 3600 + $minute * 60;
return $termTime;
}
/**
* 获取节气系数(1900-2099年)
*/
private function getCoefficient($year, $month, $type) {
// 24节气的基础系数表(1900-2099年使用)
$termCoefficients = [
// 每个月两个节气:[天数, 小时, 分钟]
[ // 1月
[5, 5, 41], // 小寒
[20, 2, 59] // 大寒
],
[ // 2月
[4, 4, 49], // 立春
[19, 0, 3] // 雨水
],
[ // 3月
[5, 17, 14], // 惊蛰
[20, 10, 4] // 春分
],
[ // 4月
[4, 22, 18], // 清明
[20, 3, 5] // 谷雨
],
[ // 5月
[5, 20, 26], // 立夏
[21, 0, 30] // 小满
],
[ // 6月
[5, 14, 36], // 芒种
[21, 8, 25] // 夏至
],
[ // 7月
[7, 5, 30], // 小暑
[23, 0, 57] // 大暑
],
[ // 8月
[7, 21, 23], // 立秋
[23, 7, 10] // 处暑
],
[ // 9月
[7, 16, 50], // 白露
[23, 0, 6] // 秋分
],
[ // 10月
[8, 4, 7], // 寒露
[23, 11, 44] // 霜降
],
[ // 11月
[7, 21, 11], // 立冬
[22, 14, 56] // 小雪
],
[ // 12月
[7, 4, 57], // 大雪
[22, 0, 38] // 冬至
]
];
$coeff = $termCoefficients[$month - 1][$type];
// 修正闰年影响
$baseDays = $coeff[0];
if ($this->isLeapYear($year)) {
$baseDays += 0.5; // 闰年微调
}
return [
'days' => $baseDays,
'hours' => $coeff[1],
'minutes' => $coeff[2]
];
}
/**
* 获取其他年份的节气系数(简化版)
*/
private function getCoefficientOther($year, $month, $type) {
// 使用天文公式近似计算
$pi = 3.1415926535898;
$rad = $pi / 180;
// 计算太阳黄经
$longitude = ($month - 1) * 30 + $type * 15;
// 近似计算日期
$days = 0;
if ($month <= 2) {
$days = 31 * ($month - 1);
} else {
$days = 31 * ($month - 1) - floor(($month + 2) / 5) * 2 + 2;
}
// 添加修正
$correction = sin(($longitude * 2 + 10) * $rad) * 0.5;
$days += $correction;
return [
'days' => $days + 5,
'hours' => 12,
'minutes' => 0
];
}
/**
* 判断是否为闰年
*/
private function isLeapYear($year) {
return ($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0;
}
}
// 使用示例
$calculator = new SolarTermsCalculator();
$year = 2024;
$terms = $calculator->calculateYear($year);
echo "{$year}年的二十四节气:\n";
echo "=====================\n";
foreach ($terms as $term) {
echo "{$term['name']}: {$term['date']}\n";
}
简化版(基于固定公式)
<?php
class QuickSolarTerms {
/**
* 快速计算节气(精度较低,适合不需要精确时间的场景)
*/
public static function getQuickTerms($year) {
$terms = [];
$names = ['小寒','大寒','立春','雨水','惊蛰','春分','清明','谷雨',
'立夏','小满','芒种','夏至','小暑','大暑','立秋','处暑',
'白露','秋分','寒露','霜降','立冬','小雪','大雪','冬至'];
// 简化的日期常数(1900-2099年适用)
$dates = [
[5,20], [4,19], [6,21], [5,20], [6,21], [5,21],
[5,20], [6,21], [7,23], [7,23], [8,23], [8,23],
[7,23], [7,23], [7,23], [8,23], [7,23], [8,23],
[8,23], [8,23], [7,22], [7,22], [7,22], [7,22]
];
foreach ($names as $index => $name) {
$month = floor($index / 2) + 1;
$day = $dates[$index][$index % 2];
// 年份修正
$offset = ($year % 4 == 0 && $year % 100 != 0) ? -1 : 0;
$terms[] = [
'name' => $name,
'date' => sprintf("%d-%02d-%02d", $year, $month, $day + $offset)
];
}
return $terms;
}
}
使用第三方库
使用 Composer 包
composer require kkokk/solar-terms
<?php
require 'vendor/autoload.php';
use kkokk\SolarTerms\SolarTerms;
// 使用第三方库计算
$solarTerms = new SolarTerms();
$terms = $solarTerms->getYear(2024);
foreach ($terms as $term) {
echo "{$term['name']}: {$term['date']} {$term['time']}\n";
}
对接公开API
<?php
class OnlineSolarTerms {
/**
* 通过API获取节气信息
*/
public static function getTermsFromAPI($year) {
$url = "https://api.example.com/solar-terms?year={$year}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
}
实用功能扩展
<?php
class SolarTermsHelper {
/**
* 获取当前节气
*/
public static function getCurrentTerm() {
$calculator = new SolarTermsCalculator();
$year = date('Y');
$terms = $calculator->calculateYear($year);
$now = time();
$currentTerm = null;
foreach ($terms as $term) {
$termTime = strtotime($term['date']);
if ($termTime <= $now) {
$currentTerm = $term;
}
}
return $currentTerm;
}
/**
* 判断某天是否是节气
*/
public static function isTermDay($date) {
$calculator = new SolarTermsCalculator();
$year = date('Y', strtotime($date));
$terms = $calculator->calculateYear($year);
foreach ($terms as $term) {
if ($term['date'] == $date) {
return $term['name'];
}
}
return false;
}
/**
* 获取两个节气之间的天数
*/
public static function daysBetweenTerms($term1, $term2, $year) {
$calculator = new SolarTermsCalculator();
$terms = $calculator->calculateYear($year);
$time1 = null;
$time2 = null;
foreach ($terms as $term) {
if ($term['name'] == $term1) $time1 = strtotime($term['date']);
if ($term['name'] == $term2) $time2 = strtotime($term['date']);
}
if ($time1 && $time2) {
return abs($time2 - $time1) / 86400;
}
return null;
}
}
// 使用示例
echo "当前节气:" . SolarTermsHelper::getCurrentTerm()['name'] . "\n";
echo "今天是节气吗?" . (SolarTermsHelper::isTermDay(date('Y-m-d')) ?: '不是') . "\n";
注意事项
- 精度问题:简化版算法精度较低,适合非关键应用
- 时区处理:确保服务器时区设置正确
- 性能优化:对于大量计算,建议缓存结果
- 年份范围:不同算法的适用年份范围不同
选择哪种方式取决于你的具体需求:
- 需要精确时间:使用完整天文算法
- 快速实现:使用简化版
- 生产环境:建议使用成熟的第三方库
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播