|
|
|
@ -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; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 转换为指定时区
|
|
|
|
/** |
|
|
|
const options = { |
|
|
|
* 计算农历日期(2026 年春节 2 月 17 日 = 正月初一) |
|
|
|
timeZone: timezone, |
|
|
|
*/ |
|
|
|
year: 'numeric', |
|
|
|
function getLunarDate(beijingDate) { |
|
|
|
month: 'long', |
|
|
|
const springFestival = new Date('2026-02-17T00:00:00'); // 春节北京时间
|
|
|
|
day: 'numeric', |
|
|
|
const diffMs = beijingDate.getTime() - springFestival.getTime(); |
|
|
|
weekday: 'long', |
|
|
|
const daysSince = Math.floor(diffMs / (1000 * 60 * 60 * 24)); |
|
|
|
hour: '2-digit', |
|
|
|
const lunarDay = daysSince + 1; // 正月初一是第 1 天
|
|
|
|
minute: '2-digit', |
|
|
|
|
|
|
|
hour12: false |
|
|
|
if (lunarDay >= 1 && lunarDay <= 30) { |
|
|
|
}; |
|
|
|
return `农历正月初${lunarDay}`; |
|
|
|
|
|
|
|
} else { |
|
|
|
const formatter = new Intl.DateTimeFormat('zh-CN', options); |
|
|
|
return `农历${lunarDay > 30 ? '二月' : '腊月'}${Math.abs(lunarDay - 30)}`; |
|
|
|
const parts = formatter.formatToParts(now); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const result = {}; |
|
|
|
/** |
|
|
|
parts.forEach(part => { |
|
|
|
* 获取当前日期时间(北京时间) |
|
|
|
result[part.type] = part.value; |
|
|
|
*/ |
|
|
|
}); |
|
|
|
function getCurrentDateTime() { |
|
|
|
|
|
|
|
const beijingNow = getBeijingTime(); |
|
|
|
|
|
|
|
|
|
|
|
// 计算农历日期(基于 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 }; |
|
|
|
|