作者:
逍遥Sean
简介:一个主修Java的Web网站\游戏服务器后端开发者
主页:https://blog.csdn.net/Ureliable
觉得博主文章不错的话,可以三连支持一下~ 如有需要我的支持,请私信或评论留言!
前言:
接续上篇JavaScript实战 - 农历(阴历)和公历(阳历)之间的转换
前篇的代码只是一个简单的转换历法思路
本篇我将为您展示一个更完整的农历(阴历)和公历(阳历)之间的转换方法。
这种转换涉及到复杂的历法计算和数据源获取,需要考虑到闰年、闰月以及特殊节气等因素。
我将提供一个基于算法的实现示例,而非简单的数据表查找方法。
JavaScript实战 - 农历(阴历)和公历(阳历)之间的转换 基于算法的实现
农历转公历(阴历转阳历)
// 农历转公历函数
function lunarToSolar(lunarYear, lunarMonth, lunarDay) {
// 农历年份对应的基准公历日期
const baseYear = 1900;
const baseMonth = 1;
const baseDay = 31; // 农历1900年正月初一对应的公历日期
// 公历1900年正月初一的JD值(Julian Day)
const baseJD = 2415020.5;
// 计算农历年份到公历年份之间的总天数
let totalDays = 0;
for (let year = baseYear; year < lunarYear; year++) {
totalDays += daysInYear(year); // 计算每一年的天数总和
}
// 加上该年农历月份前面的月份的天数
for (let month = 1; month < lunarMonth; month++) {
totalDays += daysInMonth(lunarYear, month);
}
// 加上农历日期对应的天数
totalDays += lunarDay - 1; // 农历日从1开始,转换为0开始的索引
// 计算对应的公历日期的JD值
let solarJD = baseJD + totalDays;
// 转换为公历日期
let date = jdToDate(solarJD);
return {
year: date.year,
month: date.month,
day: date.day
};
}
// 计算某一年的总天数(公历)
function daysInYear(year) {
if (isLeapYear(year)) {
return 366;
} else {
return 365;
}
}
// 判断某一年是否是闰年(公历)
function isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
}
// 计算某一年某一月的天数(公历)
function daysInMonth(year, month) {
if (month === 2) {
return isLeapYear(year) ? 29 : 28;
} else if ([4, 6, 9, 11].includes(month)) {
return 30;
} else {
return 31;
}
}
// 将JD值转换为公历日期
function jdToDate(jd) {
let Z = Math.floor(jd + 0.5);
let W = Math.floor((Z - 1867216.25) / 36524.25);
let X = Math.floor(W / 4);
let A = Z + 1 + W - X;
let B = A + 1524;
let C = Math.floor((B - 122.1) / 365.25);
let D = Math.floor(365.25 * C);
let E = Math.floor((B - D) / 30.6001);
let day = B - D - Math.floor(30.6001 * E);
let month = E < 14 ? E - 1 : E - 13;
let year = month > 2 ? C - 4716 : C - 4715;
return {
year: year,
month: month,
day: day
};
}
// 示例调用
const lunarYear = 2024;
const lunarMonth = 6;
const lunarDay = 15;
const solarDate = lunarToSolar(lunarYear, lunarMonth, lunarDay);
console.log(`农历 ${lunarYear}年${lunarMonth}月${lunarDay}日 对应的公历日期是:${solarDate.year}年${solarDate.month}月${solarDate.day}日`);
公历转农历(阳历转阴历)
这部分的算法较为复杂,涉及到从公历日期计算到农历日期的转换,包括闰年的判断和每年的闰月情况。以下是一个基本的示例:
// 公历转农历函数
function solarToLunar(solarYear, solarMonth, solarDay) {
// 计算公历日期的JD值
const solarJD = dateToJD(solarYear, solarMonth, solarDay);
// 计算从公历1900年1月31日到该公历日期的总天数
const baseYear = 1900;
const baseMonth = 1;
const baseDay = 31;
const baseJD = 2415020.5; // 公历1900年1月31日对应的JD值
let totalDays = solarJD - baseJD;
// 农历年份
let lunarYear = baseYear;
// 计算农历年份
while (true) {
let daysOfYear = daysInYear(lunarYear);
if (totalDays < daysOfYear) {
break;
}
totalDays -= daysOfYear;
lunarYear++;
}
// 农历月份
let lunarMonth = 1;
let isLeap = false;
// 计算农历月份和日期
while (true) {
let daysOfMonth = daysInMonth(lunarYear, lunarMonth);
if (totalDays < daysOfMonth) {
break;
}
totalDays -= daysOfMonth;
lunarMonth++;
}
return {
lunarYear: lunarYear,
lunarMonth: lunarMonth,
lunarDay: totalDays + 1 // 农历日期从1开始
};
}
// 将公历日期转换为JD值
function dateToJD(year, month, day) {
let A = Math.floor((14 - month) / 12);
let Y = year + 4800 - A;
let M = month + 12 * A - 3;
let JD = day + Math.floor((153 * M + 2) / 5) + 365 * Y + Math.floor(Y / 4) - 32083;
return JD - 0.5; // 返回JD值
}
// 示例调用
const solarYear = 2024;
const solarMonth = 7;
const solarDay = 26;
const lunarDate = solarToLunar(solarYear, solarMonth, solarDay);
console.log(`公历 ${solarYear}年${solarMonth}月${solarDay}日 对应的农历日期是:${lunarDate.lunarYear}年${lunarDate.lunarMonth}月${lunarDate.lunarDay}日`);
注意事项
- 精度问题:这些示例是基于简化的算法和公式,实际应用中可能需要更复杂的计算来处理闰年、闰月、节气等特殊情况。
- 数据源:在实际开发中,可以通过更详细和精确的历法数据来实现更准确的转换。
在实际应用中,您可能需要根据具体需求和环境进一步优化和调整算法。