|
|
|
|
/**
|
|
|
|
|
* System Date Skill
|
|
|
|
|
* 获取当前日期和时间(北京时间 UTC+8)
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取北京时间
|
|
|
|
|
*/
|
|
|
|
|
function getBeijingTime() {
|
|
|
|
|
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) {
|
|
|
|
|
return `农历正月初${lunarDay}`;
|
|
|
|
|
} else {
|
|
|
|
|
return `农历${lunarDay > 30 ? '二月' : '腊月'}${Math.abs(lunarDay - 30)}`;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取当前日期时间(北京时间)
|
|
|
|
|
*/
|
|
|
|
|
function getCurrentDateTime() {
|
|
|
|
|
const beijingNow = getBeijingTime();
|
|
|
|
|
|
|
|
|
|
const year = beijingNow.getFullYear();
|
|
|
|
|
const month = beijingNow.getMonth() + 1;
|
|
|
|
|
const day = beijingNow.getDate();
|
|
|
|
|
const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
|
|
|
|
|
const weekday = `星期${weekdays[beijingNow.getDay()]}`;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
timezone: 'Asia/Shanghai',
|
|
|
|
|
year: year,
|
|
|
|
|
month: month,
|
|
|
|
|
day: day,
|
|
|
|
|
weekday: weekday,
|
|
|
|
|
fullDate: `${year}年${month}月${day}日`,
|
|
|
|
|
lunarDate: getLunarDate(beijingNow),
|
|
|
|
|
isoString: beijingNow.toISOString()
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取相对日期(北京时间)
|
|
|
|
|
*/
|
|
|
|
|
function getRelativeDate(relative = 'today') {
|
|
|
|
|
const beijingNow = getBeijingTime();
|
|
|
|
|
let targetDate = new Date(beijingNow);
|
|
|
|
|
|
|
|
|
|
switch (relative.toLowerCase()) {
|
|
|
|
|
case 'today':
|
|
|
|
|
case '今天':
|
|
|
|
|
break;
|
|
|
|
|
case 'tomorrow':
|
|
|
|
|
case '明天':
|
|
|
|
|
targetDate.setDate(targetDate.getDate() + 1);
|
|
|
|
|
break;
|
|
|
|
|
case 'yesterday':
|
|
|
|
|
case '昨天':
|
|
|
|
|
targetDate.setDate(targetDate.getDate() - 1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const year = targetDate.getFullYear();
|
|
|
|
|
const month = targetDate.getMonth() + 1;
|
|
|
|
|
const day = targetDate.getDate();
|
|
|
|
|
const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
|
|
|
|
|
const weekday = `星期${weekdays[targetDate.getDay()]}`;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
relative: relative,
|
|
|
|
|
year: year,
|
|
|
|
|
month: month,
|
|
|
|
|
day: day,
|
|
|
|
|
weekday: weekday,
|
|
|
|
|
fullDate: `${year}年${month}月${day}日`,
|
|
|
|
|
lunarDate: getLunarDate(targetDate),
|
|
|
|
|
timezone: 'Asia/Shanghai'
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 格式化日期为可读文本
|
|
|
|
|
*/
|
|
|
|
|
function formatDateInfo(dateInfo, includeLunar = true) {
|
|
|
|
|
const lines = [
|
|
|
|
|
`📅 **${dateInfo.fullDate}**`,
|
|
|
|
|
`**星期:** ${dateInfo.weekday}`,
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
if (includeLunar && dateInfo.lunarDate) {
|
|
|
|
|
lines.push(`**农历:** ${dateInfo.lunarDate}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lines.push(`**时区:** ${dateInfo.timezone || 'Asia/Shanghai'}`);
|
|
|
|
|
|
|
|
|
|
return lines.join('\n');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 命令行测试
|
|
|
|
|
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 result = getRelativeDate(arg);
|
|
|
|
|
console.log(formatDateInfo(result));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports = { getCurrentDateTime, getRelativeDate, formatDateInfo, getLunarDate, getBeijingTime };
|