BASE_DATE 用 new Date(1900, 0, 31)(本地时间)在 1900 年早期日期上某些 JS 引擎有时区偏差,导致每个农历月初对应公历都比真实少 1 天。改用 Date.UTC(1900, 0, 31) 算时间戳,再用 UTC 字段重新构造本地 Date 对象, 彻底避免歧义。 同时月循环改用 `leapM <= m` 写法(与权威 jjonline/calendar.js 一致), 和 solarToLunar 保持完美互逆。 修复验证(互逆 9 个用例全 OK): - 2026-02-17 ↔ 正月初一 - 2026-06-09 ↔ 农历四月廿四(用户实测发现的差 1 天) - 2023-03-22 ↔ 闰二月初一 - 2023-04-19 ↔ 闰二月廿九 - 2025-07-25 ↔ 闰六月初一 - 2025-08-22 ↔ 闰六月廿九 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+12
-11
@@ -141,12 +141,11 @@ function solarToLunar(solarDate) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 农历转公历(指定年份)
|
||||
* @param {Number} lunarYear
|
||||
* @param {Number} lunarMonth
|
||||
* @param {Number} lunarDay
|
||||
* @param {Boolean} isLeap 是否闰月
|
||||
* @returns {Date}
|
||||
* 农历转公历(指定年份)。算法贴近 jjonline/calendar.js 权威实现。
|
||||
* 关键修正:早期版用 `new Date(1900, 0, 31)`(本地时间)作为 BASE,在 1900 年早期日期
|
||||
* 上某些 JS 引擎有时区偏差,导致每个农历月初对应公历都少 1 天。改用 UTC 时间戳后
|
||||
* 再构造本地 Date 对象,避免歧义。
|
||||
* @returns {Date} 本地视角下的公历日期(getDate 取出来的是该农历日对应的公历日)
|
||||
*/
|
||||
function lunarToSolar(lunarYear, lunarMonth, lunarDay, isLeap) {
|
||||
let offset = 0
|
||||
@@ -156,12 +155,12 @@ function lunarToSolar(lunarYear, lunarMonth, lunarDay, isLeap) {
|
||||
}
|
||||
|
||||
const leapM = _leapMonth(lunarYear)
|
||||
let hasLeap = false
|
||||
let isAdd = false
|
||||
|
||||
for (let m = 1; m < lunarMonth; m++) {
|
||||
if (leapM > 0 && m === leapM && !hasLeap) {
|
||||
if (!isAdd && leapM > 0 && leapM <= m) {
|
||||
offset += _leapDays(lunarYear)
|
||||
hasLeap = true
|
||||
isAdd = true
|
||||
}
|
||||
offset += _monthDays(lunarYear, m)
|
||||
}
|
||||
@@ -172,8 +171,10 @@ function lunarToSolar(lunarYear, lunarMonth, lunarDay, isLeap) {
|
||||
|
||||
offset += lunarDay - 1
|
||||
|
||||
const result = new Date(BASE_DATE.getTime() + offset * 86400000)
|
||||
return result
|
||||
// 用 UTC 计算时间戳避免早期年份时区歧义;再用 UTC 字段构造本地 Date 对象
|
||||
const utc = Date.UTC(1900, 0, 31) + offset * 86400000
|
||||
const d = new Date(utc)
|
||||
return new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate())
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user