您的位置:首页 > 游戏 > 游戏 > JavaScript实战 - 农历(阴历)和公历(阳历)之间的转换 - 第二弹 基于算法的实现

JavaScript实战 - 农历(阴历)和公历(阳历)之间的转换 - 第二弹 基于算法的实现

2024/10/7 2:31:57 来源:https://blog.csdn.net/Ureliable/article/details/140707275  浏览:    关键词:JavaScript实战 - 农历(阴历)和公历(阳历)之间的转换 - 第二弹 基于算法的实现

作者:逍遥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}`);

注意事项

  • 精度问题:这些示例是基于简化的算法和公式,实际应用中可能需要更复杂的计算来处理闰年、闰月、节气等特殊情况。
  • 数据源:在实际开发中,可以通过更详细和精确的历法数据来实现更准确的转换。

在实际应用中,您可能需要根据具体需求和环境进一步优化和调整算法。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com