feat: 使用 lunar-javascript 库计算农历 - 专业准确的农历转换

master
Eason (陈医生) 1 month ago
parent f4d300a0c4
commit dfc81bb70e
  1. 62
      skills/system-date/date.js

@ -1,32 +1,34 @@
/**
* System Date Skill
* 获取当前日期和时间北京时间 UTC+8
* 获取当前日期和农历使用 lunar-javascript
*/
const { Solar, Lunar } = require('lunar-javascript');
/**
* 获取北京时间
*/
function getBeijingTime() {
const now = new Date();
// UTC 时间 + 8 小时 = 北京时间
const beijingTime = new Date(now.getTime() + (8 * 60 * 60 * 1000));
return beijingTime;
// UTC + 8 = 北京时间
return new Date(now.getTime() + (8 * 60 * 60 * 1000));
}
/**
* 计算农历日期2026 年春节 2 17 = 正月初一
* 获取农历日期使用专业库
*/
function getLunarDate(beijingDate) {
const springFestival = new Date('2026-02-17T00:00:00'); // 春节北京时间
const diffMs = beijingDate.getTime() - springFestival.getTime();
const daysSince = Math.floor(diffMs / (1000 * 60 * 60 * 24));
const lunarDay = daysSince + 1; // 正月初一是第 1 天
function getLunarInfo(beijingDate) {
// 从公历转换为农历
const solar = Solar.fromDate(beijingDate);
const lunar = solar.getLunar();
if (lunarDay >= 1 && lunarDay <= 30) {
return `农历正月初${lunarDay}`;
} else {
return `农历${lunarDay > 30 ? '二月' : '腊月'}${Math.abs(lunarDay - 30)}`;
}
return {
lunarDate: lunar.toString(), // 如:二〇二六年正月初八
lunarDay: lunar.getDayInChinese(), // 如:初八
lunarMonth: lunar.getMonthInChinese(), // 如:正月
lunarYear: lunar.getYearInChinese(), // 如:二〇二六
isLeap: false // lunar-javascript 需要其他方法判断闰月
};
}
/**
@ -41,6 +43,8 @@ function getCurrentDateTime() {
const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
const weekday = `星期${weekdays[beijingNow.getDay()]}`;
const lunarInfo = getLunarInfo(beijingNow);
return {
success: true,
timezone: 'Asia/Shanghai',
@ -49,7 +53,11 @@ function getCurrentDateTime() {
day: day,
weekday: weekday,
fullDate: `${year}${month}${day}`,
lunarDate: getLunarDate(beijingNow),
lunarDate: lunarInfo.lunarDate,
lunarDay: lunarInfo.lunarDay,
lunarMonth: lunarInfo.lunarMonth,
lunarYear: lunarInfo.lunarYear,
isLeap: lunarInfo.isLeap,
isoString: beijingNow.toISOString()
};
}
@ -81,6 +89,8 @@ function getRelativeDate(relative = 'today') {
const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
const weekday = `星期${weekdays[targetDate.getDay()]}`;
const lunarInfo = getLunarInfo(targetDate);
return {
success: true,
relative: relative,
@ -89,7 +99,11 @@ function getRelativeDate(relative = 'today') {
day: day,
weekday: weekday,
fullDate: `${year}${month}${day}`,
lunarDate: getLunarDate(targetDate),
lunarDate: lunarInfo.lunarDate,
lunarDay: lunarInfo.lunarDay,
lunarMonth: lunarInfo.lunarMonth,
lunarYear: lunarInfo.lunarYear,
isLeap: lunarInfo.isLeap,
timezone: 'Asia/Shanghai'
};
}
@ -105,6 +119,9 @@ function formatDateInfo(dateInfo, includeLunar = true) {
if (includeLunar && dateInfo.lunarDate) {
lines.push(`**农历:** ${dateInfo.lunarDate}`);
if (dateInfo.isLeap) {
lines.push(`**闰月:** 是`);
}
}
lines.push(`**时区:** ${dateInfo.timezone || 'Asia/Shanghai'}`);
@ -114,13 +131,16 @@ function formatDateInfo(dateInfo, includeLunar = true) {
// 命令行测试
if (require.main === module) {
console.log('=== 北京时间测试 ===');
console.log('今天:', new Date(new Date().getTime() + 8*60*60*1000).toISOString());
console.log('');
console.log('=== 农历计算测试(使用 lunar-javascript 库)===\n');
const arg = process.argv[2] || 'today';
const result = getRelativeDate(arg);
console.log(formatDateInfo(result));
console.log('\n详细信息:');
console.log(`农历年:${result.lunarYear}`);
console.log(`农历月:${result.lunarMonth}`);
console.log(`农历日:${result.lunarDay}`);
console.log(`是否闰月:${result.isLeap ? '是' : '否'}`);
}
module.exports = { getCurrentDateTime, getRelativeDate, formatDateInfo, getLunarDate, getBeijingTime };
module.exports = { getCurrentDateTime, getRelativeDate, formatDateInfo, getLunarInfo, getBeijingTime };

Loading…
Cancel
Save