fix: 农历日期计算 - 北京时间 UTC+8,2/24=初八,2/25=初九

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

@ -1,67 +1,65 @@
/** /**
* System Date Skill * System Date Skill
* 获取当前日期和时间支持时区 * 获取当前日期和时间北京时间 UTC+8
*/ */
/** /**
* 获取当前日期时间 * 获取北京时间
* @param {string} timezone - 时区 (默认 Asia/Shanghai)
* @returns {Object} 日期时间信息
*/ */
function getCurrentDateTime(timezone = 'Asia/Shanghai') { function getBeijingTime() {
const now = new Date(); const now = new Date();
// UTC 时间 + 8 小时 = 北京时间
const beijingTime = new Date(now.getTime() + (8 * 60 * 60 * 1000));
return beijingTime;
}
/**
* 计算农历日期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 天
// 转换为指定时区 if (lunarDay >= 1 && lunarDay <= 30) {
const options = { return `农历正月初${lunarDay}`;
timeZone: timezone, } else {
year: 'numeric', return `农历${lunarDay > 30 ? '二月' : '腊月'}${Math.abs(lunarDay - 30)}`;
month: 'long', }
day: 'numeric', }
weekday: 'long',
hour: '2-digit', /**
minute: '2-digit', * 获取当前日期时间北京时间
hour12: false */
}; function getCurrentDateTime() {
const beijingNow = getBeijingTime();
const formatter = new Intl.DateTimeFormat('zh-CN', options);
const parts = formatter.formatToParts(now);
const result = {};
parts.forEach(part => {
result[part.type] = part.value;
});
// 计算农历日期(基于 2026 年春节 2 月 17 日) const year = beijingNow.getFullYear();
const springFestival = new Date('2026-02-17'); const month = beijingNow.getMonth() + 1;
const daysSince = Math.floor((now - springFestival) / (1000 * 60 * 60 * 24)) + 1; const day = beijingNow.getDate();
const lunarDate = daysSince > 0 && daysSince <= 30 const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
? `农历正月初${daysSince}` const weekday = `星期${weekdays[beijingNow.getDay()]}`;
: '农历日期需查询黄历';
return { return {
success: true, success: true,
timezone: timezone, timezone: 'Asia/Shanghai',
year: result.year, year: year,
month: result.month, month: month,
day: result.day, day: day,
weekday: result.weekday, weekday: weekday,
hour: result.hour, fullDate: `${year}${month}${day}`,
minute: result.minute, lunarDate: getLunarDate(beijingNow),
fullDate: `${result.year}${parseInt(result.month)}${parseInt(result.day)}`, isoString: beijingNow.toISOString()
lunarDate: lunarDate,
isoString: now.toISOString()
}; };
} }
/** /**
* 获取相对日期 * 获取相对日期北京时间
* @param {string} relative - 相对日期 (today, tomorrow, yesterday)
* @param {string} timezone - 时区
* @returns {Object} 日期信息
*/ */
function getRelativeDate(relative = 'today', timezone = 'Asia/Shanghai') { function getRelativeDate(relative = 'today') {
const now = new Date(); const beijingNow = getBeijingTime();
let targetDate = new Date(now); let targetDate = new Date(beijingNow);
switch (relative.toLowerCase()) { switch (relative.toLowerCase()) {
case 'today': case 'today':
@ -77,39 +75,22 @@ function getRelativeDate(relative = 'today', timezone = 'Asia/Shanghai') {
break; break;
} }
// 计算农历日期 const year = targetDate.getFullYear();
const springFestival = new Date('2026-02-17'); const month = targetDate.getMonth() + 1;
const daysSince = Math.floor((targetDate - springFestival) / (1000 * 60 * 60 * 24)) + 1; const day = targetDate.getDate();
const lunarDate = daysSince > 0 && daysSince <= 30 const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
? `农历正月初${daysSince}` const weekday = `星期${weekdays[targetDate.getDay()]}`;
: '农历日期需查询黄历';
const options = {
timeZone: timezone,
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
};
const formatter = new Intl.DateTimeFormat('zh-CN', options);
const parts = formatter.formatToParts(targetDate);
const result = {};
parts.forEach(part => {
result[part.type] = part.value;
});
return { return {
success: true, success: true,
relative: relative, relative: relative,
year: result.year, year: year,
month: result.month, month: month,
day: result.day, day: day,
weekday: result.weekday, weekday: weekday,
fullDate: `${result.year}${parseInt(result.month)}${parseInt(result.day)}`, fullDate: `${year}${month}${day}`,
lunarDate: lunarDate, lunarDate: getLunarDate(targetDate),
isoString: targetDate.toISOString() timezone: 'Asia/Shanghai'
}; };
} }
@ -126,18 +107,20 @@ function formatDateInfo(dateInfo, includeLunar = true) {
lines.push(`**农历:** ${dateInfo.lunarDate}`); lines.push(`**农历:** ${dateInfo.lunarDate}`);
} }
if (dateInfo.timezone) { lines.push(`**时区:** ${dateInfo.timezone || 'Asia/Shanghai'}`);
lines.push(`**时区:** ${dateInfo.timezone}`);
}
return lines.join('\n'); return lines.join('\n');
} }
// 命令行测试 // 命令行测试
if (require.main === module) { if (require.main === module) {
console.log('=== 北京时间测试 ===');
console.log('今天:', new Date(new Date().getTime() + 8*60*60*1000).toISOString());
console.log('');
const arg = process.argv[2] || 'today'; const arg = process.argv[2] || 'today';
const result = getRelativeDate(arg, 'Asia/Shanghai'); const result = getRelativeDate(arg);
console.log(formatDateInfo(result)); console.log(formatDateInfo(result));
} }
module.exports = { getCurrentDateTime, getRelativeDate, formatDateInfo }; module.exports = { getCurrentDateTime, getRelativeDate, formatDateInfo, getLunarDate, getBeijingTime };

Loading…
Cancel
Save