js实现节气
节气计算原理
节气是根据太阳在黄道上的位置划分的,每15°为一个节气。计算节气需考虑太阳黄经和地球公转轨道的椭圆特性,通常使用Jean Meeus的《天文算法》中的公式。

计算方法
节气计算的核心是求解太阳黄经达到特定值的时间点。以下代码实现了1900-2100年间的节气计算:

// 计算某年的节气
function getSolarTerms(year) {
const terms = [];
const baseDate = new Date(31556925974.7 * (year - 1900) + Date.UTC(1900, 0, 6, 2, 5));
for (let i = 0; i < 24; i++) {
const date = new Date(baseDate.getTime());
date.setDate(date.getDate() + i * 15);
// 精确修正(简化版)
const offset = (year - 2000) * 0.0002;
date.setMinutes(date.getMinutes() + Math.round(offset * 1440));
terms.push({
name: solarTermNames[i],
date: date
});
}
return terms;
}
// 24节气名称
const solarTermNames = [
"小寒", "大寒", "立春", "雨水", "惊蛰", "春分",
"清明", "谷雨", "立夏", "小满", "芒种", "夏至",
"小暑", "大暑", "立秋", "处暑", "白露", "秋分",
"寒露", "霜降", "立冬", "小雪", "大雪", "冬至"
];
精确算法实现
对于更高精度的计算,需要使用完整的VSOP87行星理论数据:
// 精确太阳黄经计算(简化版)
function getSunLongitude(date) {
const t = (date.getTime() - Date.UTC(2000, 0, 1, 12)) / 36525000;
let L = 0;
// VSOP87多项式系数(部分)
const terms = [
[175347046, 0, 0], [3341656, 4.6692568, 6283.07585],
[34894, 4.6261, 12566.1517], [3497, 2.7441, 5753.3849]
];
terms.forEach(([a, b, c]) => {
L += a * Math.cos(b + c * t);
});
return (L / 1000) % 360;
}
// 查找节气时刻
function findExactTerm(year, index) {
const targetLon = index * 15;
let date = new Date(Date.UTC(year, Math.floor(index/2), 1));
// 二分法逼近
for (let i = 0; i < 10; i++) {
const lon = getSunLongitude(date);
const diff = (lon - targetLon + 360) % 360;
date.setHours(date.getHours() + diff * 24 / 15);
}
return date;
}
实际应用示例
获取2023年所有节气:
const terms2023 = getSolarTerms(2023);
terms2023.forEach(term => {
console.log(`${term.name}: ${term.date.toLocaleDateString()}`);
});
// 精确计算春分时刻
const springEquinox = findExactTerm(2023, 5);
console.log(`精确春分时刻: ${springEquinox.toISOString()}`);
注意事项
- 简化算法误差在±1天以内,适合一般应用
- 精确算法需要完整的VSOP87系数表
- 节气时刻需转换为当地时区
- 公历闰年会影响2月节气日期
以上实现提供了从简单到精确的节气计算方法,可根据需求选择适合的方案。实际应用中建议使用专业的天文计算库如lunisolar.js等。






