From 865d4c7a156c8a37851f6d9ed93a6ec4e3ae32fd Mon Sep 17 00:00:00 2001 From: patdelphi Date: Sat, 23 Aug 2025 10:26:51 +0800 Subject: [PATCH] feat: Enhanced lunar calendar display and Zi Shi calculation improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added full Chinese year display (农历一九七六年) - Implemented detailed solar term intervals (惊蛰后至春分前) - Enhanced Zi Shi calculation with professional explanations - Added lunar information display in frontend components - Improved accuracy of lunar date calculations - Removed redundant note texts for cleaner UI - Fixed syntax errors in analyzer modules --- comparison-yijing.md | 227 ------------- debug-error.txt | Bin 88110 -> 0 bytes .../AI_INTERPRETATION_GUIDE.md | 0 .../FRONTEND_EXPORT_SETUP.md | 0 .../TYPOGRAPHY_GUIDE.md | 0 .../UI_OPTIMIZATION_PLAN.md | 0 server/services/baziAnalyzer.cjs | 310 +++++++++++++++++- server/services/ziweiAnalyzer.cjs | 283 +++++++++++++++- src/components/CompleteBaziAnalysis.tsx | 59 ++++ src/components/CompleteZiweiAnalysis.tsx | 64 ++++ tests/enhanced-features-test.cjs | 162 +++++++++ tests/user-zishi-test.cjs | 55 ++++ tests/zishi-fix-test.cjs | 117 +++++++ 13 files changed, 1018 insertions(+), 259 deletions(-) delete mode 100644 comparison-yijing.md delete mode 100644 debug-error.txt rename AI_INTERPRETATION_GUIDE.md => docs/AI_INTERPRETATION_GUIDE.md (100%) rename FRONTEND_EXPORT_SETUP.md => docs/FRONTEND_EXPORT_SETUP.md (100%) rename TYPOGRAPHY_GUIDE.md => docs/TYPOGRAPHY_GUIDE.md (100%) rename UI_OPTIMIZATION_PLAN.md => docs/UI_OPTIMIZATION_PLAN.md (100%) create mode 100644 tests/enhanced-features-test.cjs create mode 100644 tests/user-zishi-test.cjs create mode 100644 tests/zishi-fix-test.cjs diff --git a/comparison-yijing.md b/comparison-yijing.md deleted file mode 100644 index 5fb0d01..0000000 --- a/comparison-yijing.md +++ /dev/null @@ -1,227 +0,0 @@ -# 易经占卜分析报告 - -**占卜者:** 午饭 -**生成时间:** 2025/8/21 19:09:13 -**分析类型:** 易经占卜 - ---- - -## ❓ 占卜问题 - -**问题:** 午饭 - -**起卦方法:** 梅花易数时间起卦法 - -**占卜时间:** 2025/8/21 19:09:13 - -**问题类型:** 综合运势 - -**关注重点:** 整体发展、综合状况、全面分析 - -## 🔮 卦象信息 - -### 主卦 - -**卦名:** 困 -**卦象:** -_ _ -___ -_ _ -_ _ -_ _ -___ -**卦序:** 第47卦 - -### 变卦 - -**卦名:** 兑 -**卦象:** -_ _ -___ -___ -_ _ -___ -___ - -### 八卦结构 - -**上卦:** 兑 (泽) -**下卦:** 坎 (水) - -### 动爻 - -**动爻位置:** 1爻 - -## 📜 卦辞分析 - -### 卦象含义 - -【困卦】第47卦 - 困穷,困境,困顿 - -### 彖传 - -> 【彖传】曰:亨,贞,大人吉,无咎。有言不信。 - -### 象传 - -> 【象传】曰:泽无水,困。君子以致命遂志。 - -### 八卦组合分析 - -上卦兑(泽)代表悦,下卦坎(水)代表陷。泽在上,水在下,形成兑坎的组合,象征着特殊的能量组合,需要深入分析。 - -### 五行分析 - -**upper_element:** 金 -**lower_element:** 水 -**relationship:** 金生水,相生有利 -**balance:** 五行相生,和谐发展,有利于事物的成长 - -## 🔄 动爻分析 - -**动爻数量:** 1爻 - -## 🔀 变卦分析 - -### 变卦含义 - -兑悦,喜悦,和悦 - -### 转化洞察 - -从【困】到【兑】的变化,预示着事态将从困穷,困境,困顿转向兑悦,喜悦,和悦,这是一个重要的转折点。需要适应这种变化,调整策略和心态。 - -### 变化指导 - -变卦指示:充满喜悦和和谐的氛围。保持和悦态度,增进人际和谐。 - -### 时机把握 - -变化的速度适中,需要保持关注 - -## 🔍 高级分析 - -### 互卦 - 蹇 - -**卦象:** -_ _ -___ -_ _ -_ _ -_ _ -___ -**含义:** 蹇难,困难,险阻 -**分析:** 互卦【蹇】揭示了事物的内在发展趋势和隐藏因素。面临重重困难的时期。反省自身,修德养性,寻求贵人帮助。 - -### 错卦 - 坤 - -**卦象:** -_ _ -_ _ -_ _ -_ _ -_ _ -_ _ -**含义:** 接受,滋养,顺从 -**分析:** 错卦【坤】代表了相对立的状态和需要避免的方向。以柔顺和包容的态度面对挑战。通过支持他人和耐心等待,将获得成功。 - -### 综卦 - 涣 - -**卦象:** -_ _ -___ -_ _ -_ _ -___ -___ -**含义:** 涣散,离散,化解 -**分析:** 综卦【涣】显示了事物的另一面和可能的转化方向。化解涣散,重建秩序的时期。凝聚人心,重获团结。 - -### 四卦综合洞察 - -通过四卦分析:本卦【困】显示当前状态,互卦【蹇】揭示内在动力,错卦【坤】提醒对立面,综卦【涣】指示转化方向。综合来看,需要在困穷,困境,困顿的基础上,注意蹇难,困难,险阻的内在发展,避免接受,滋养,顺从的极端,向涣散,离散,化解的方向转化。 - -## 🔢 象数分析 - -### 上卦数理 - -**数字:** 2 -**含义:** 上卦数字2,对应兑卦泽象。在您的问题"午饭"中,这表示外在环境充满喜悦和交流的机会。泽象主悦,预示着通过良好的沟通和人际关系能够获得成功。 -**影响:** 外在环境呈现泽的特质,需要以悦的方式应对 - -### 下卦数理 - -**数字:** 6 -**含义:** 下卦数字6,对应坎卦水象。在您的问题"午饭"中,这表示您内心深沉而有智慧。内在动力来自于对深层真理的探索。 - -### 组合能量 - -**总数:** 8 -**解释:** 总数8在您的问题"午饭"中代表丰盛收获,是收获成果的时机。这个数字预示着您的努力将得到回报。 -**和谐度:** 上下卦差异很大,需要深度调整和耐心化解 - -### 时间共振 - -**共振等级:** 需要调和 -**时间能量:** 阴气渐盛,适合休息调养 -**最佳时机:** 对于"午饭",建议在午时(11:00-13:00)把握收获时机 - -## 🧭 五行分析 - -### 五行属性 - -**上卦五行:** 金 -**下卦五行:** 水 - -### 五行关系 - -**相互作用:** 金生水,相生有利 -**平衡状态:** 五行相生,和谐发展,有利于事物的成长 - -## ⏰ 时间分析 - -### 月相影响 - -**月相能量:** 圆满充实 -**月相建议:** 适合收获和庆祝 - -### 能量状态 - -**整体状态:** 旺盛之气与阴气渐盛相结合 -**能量建议:** 在夏季的戌时,适合积极行动,同时休息调整 - -## 🎯 针对性指导 - -### 专业分析 - -针对您关于综合运势的问题,本卦【困】在整体发展、综合状况、全面分析方面的指示是:处于困境的时期。虽处困境,但保持正道,终将脱困。。 变卦【兑】预示着在整体发展、综合状况、全面分析方面将会有所转变。 结合当前的时间因素(夏季,戌时),建议您适合积极行动。 - -## 🎯 动态指导 - -### 实用建议 - -综合来看,本卦【困】的总体指导是:"处于困境的时期。虽处困境,但保持正道,终将脱困。"。 变卦【兑】提示未来趋势:"充满喜悦和和谐的氛围。保持和悦态度,增进人际和谐。"。 - -## 🌟 易经智慧 - -### 核心信息 - -坚持正道。变化在即,喜悦和谐。 - -### 行动建议 - -保持信念,寻求突破 当前正值夏季,适合积极行动。 现在是戌时,休息调整。 考虑到即将到来的变化,建议:保持和悦,增进和谐。 - -### 时机把握 - -时机分析:晚间时光,阴气渐盛,适合思考和规划。 夏季适合积极行动。 - -## 📖 哲学洞察 - -《易经》困卦的核心智慧在于:泽中无水,象征困穷。君子应舍命达成志向。。 而变卦兑则提醒我们:两泽相连,象征喜悦。君子应与朋友讲习道义。。 《易经》告诉我们,万事万物都在变化之中,智者应该顺应这种变化,在变化中寻找机遇,在稳定中积蓄力量。 - ---- - -*本报告由神机阁AI命理分析平台生成* -*生成时间:2025/8/21 19:09:13* -*仅供参考,请理性对待* diff --git a/debug-error.txt b/debug-error.txt deleted file mode 100644 index 59b8f4953d7b5d5bc0cbec80af6b06f2bbc3c797..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88110 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

jti-|k^gilf30p~OziY` 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 RpxV|Zi>@OafWhR@; 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 diff --git a/AI_INTERPRETATION_GUIDE.md b/docs/AI_INTERPRETATION_GUIDE.md similarity index 100% rename from AI_INTERPRETATION_GUIDE.md rename to docs/AI_INTERPRETATION_GUIDE.md diff --git a/FRONTEND_EXPORT_SETUP.md b/docs/FRONTEND_EXPORT_SETUP.md similarity index 100% rename from FRONTEND_EXPORT_SETUP.md rename to docs/FRONTEND_EXPORT_SETUP.md diff --git a/TYPOGRAPHY_GUIDE.md b/docs/TYPOGRAPHY_GUIDE.md similarity index 100% rename from TYPOGRAPHY_GUIDE.md rename to docs/TYPOGRAPHY_GUIDE.md diff --git a/UI_OPTIMIZATION_PLAN.md b/docs/UI_OPTIMIZATION_PLAN.md similarity index 100% rename from UI_OPTIMIZATION_PLAN.md rename to docs/UI_OPTIMIZATION_PLAN.md diff --git a/server/services/baziAnalyzer.cjs b/server/services/baziAnalyzer.cjs index 02440fe..54b39f2 100644 --- a/server/services/baziAnalyzer.cjs +++ b/server/services/baziAnalyzer.cjs @@ -98,7 +98,8 @@ class BaziAnalyzer { }, bazi_chart: baziChart, pillar_interpretations: this.generatePillarInterpretations(baziChart, gender, personalizedName), - lunar_info: this.calculateLunarInfo(birth_date) + lunar_info: this.calculateLunarInfo(birth_date), + zishi_calculation_note: this.generateZishiCalculationNote(baziChart, birth_time) }, wuxing_analysis: { element_distribution: wuxingAnalysis.distribution, @@ -159,6 +160,9 @@ class BaziAnalyzer { const birthHour = birth_time ? parseInt(birth_time.split(':')[0]) : 12; const birthMinute = birth_time ? parseInt(birth_time.split(':')[1]) : 0; + // 判断是否为晚子时(23:00-24:00) + const isLateZiShi = birthHour === 23; + // 1. 年柱计算 - 基于精确立春节气 const yearPillar = this.calculateYearPillar(birthYear, birthMonth, birthDay, birthHour, birthMinute); @@ -168,8 +172,8 @@ class BaziAnalyzer { // 3. 日柱计算 - 基于万年历推算 const dayPillar = this.calculateDayPillar(birthYear, birthMonth, birthDay); - // 4. 时柱计算 - 基于日干推时干 - const hourPillar = this.calculateHourPillar(birthHour, dayPillar.stemIndex); + // 4. 时柱计算 - 基于日干推时干,晚子时需要特殊处理 + const hourPillar = this.calculateHourPillar(birthHour, birthMinute, dayPillar.stemIndex, birthYear, birthMonth, birthDay); const result = { year_pillar: { @@ -200,7 +204,10 @@ class BaziAnalyzer { branch: hourPillar.branch, element: this.getElementFromStem(hourPillar.stem), hidden_stems: this.baseData.getBranchHiddenStems(hourPillar.branch), - ten_god: this.calculateTenGod(dayPillar.stem, hourPillar.stem) + ten_god: this.calculateTenGod(dayPillar.stem, hourPillar.stem), + zishi_type: hourPillar.zishi_type, + is_late_zishi: hourPillar.is_late_zishi, + is_early_zishi: hourPillar.is_early_zishi }, day_master: dayPillar.stem, day_master_element: this.getElementFromStem(dayPillar.stem), @@ -320,10 +327,34 @@ class BaziAnalyzer { return this.wanNianLi.getAccurateDayPillar(year, month, day); } - // 时柱计算 - 日干推时干 - calculateHourPillar(hour, dayStemIndex) { + // 时柱计算 - 日干推时干,支持早晚子时区分 + calculateHourPillar(hour, minute, dayStemIndex, year, month, day) { + // 判断子时类型 + let isLateZiShi = false; + let isEarlyZiShi = false; + let actualDayStemIndex = dayStemIndex; + + if (hour === 23) { + // 晚子时(23:00-23:59):日柱用当天,时柱用第二天的日干推算 + isLateZiShi = true; + // 获取第二天的日柱来推算时干 + const nextDay = new Date(year, month - 1, day + 1); + const nextDayPillar = this.calculateDayPillar(nextDay.getFullYear(), nextDay.getMonth() + 1, nextDay.getDate()); + actualDayStemIndex = nextDayPillar.stemIndex; + } else if (hour === 0) { + // 早子时(00:00-00:59):日柱和时柱都用当天 + isEarlyZiShi = true; + } + // 时支计算 - const hourBranchIndex = Math.floor((hour + 1) / 2) % 12; + let hourBranchIndex; + if (hour === 23 || hour === 0) { + // 子时统一为0 + hourBranchIndex = 0; + } else { + // 其他时辰按原逻辑计算 + hourBranchIndex = Math.floor((hour + 1) / 2) % 12; + } // 时干推算:甲己还加甲 const hourStemBase = { @@ -339,13 +370,17 @@ class BaziAnalyzer { 9: 8 // 癸日从壬开始 }; - const hourStemIndex = (hourStemBase[dayStemIndex] + hourBranchIndex) % 10; + const hourStemIndex = (hourStemBase[actualDayStemIndex] + hourBranchIndex) % 10; return { stem: this.baseData.getStemByIndex(hourStemIndex), - branch: this.baseData.getBranchByIndex(hourBranchIndex), + branch: this.baseData.getBranchByIndex(hourBranchIndex), stemIndex: hourStemIndex, - branchIndex: hourBranchIndex + branchIndex: hourBranchIndex, + // 添加子时类型标识 + zishi_type: isLateZiShi ? '晚子时' : (isEarlyZiShi ? '早子时' : null), + is_late_zishi: isLateZiShi, + is_early_zishi: isEarlyZiShi }; } @@ -2024,15 +2059,258 @@ class BaziAnalyzer { } calculateLunarInfo(birth_date) { - // 简化的农历信息计算 + const birthDate = new Date(birth_date); + const year = birthDate.getFullYear(); + const month = birthDate.getMonth() + 1; + const day = birthDate.getDate(); + + // 计算干支年 + const tianGan = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']; + const diZhi = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥']; + const zodiacAnimals = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪']; + + const ganIndex = (year - 4) % 10; + const zhiIndex = (year - 4) % 12; + const ganzhiYear = tianGan[ganIndex] + diZhi[zhiIndex]; + const zodiac = zodiacAnimals[zhiIndex]; + + // 计算节气信息 + let solarTerm = this.calculateSolarTerm(month, day); + + // 改进的农历日期计算 + const lunarInfo = this.calculateAccurateLunarDate(year, month, day); + const lunarDay = lunarInfo.day; + const lunarMonth = lunarInfo.month; + const lunarYear = lunarInfo.year; + return { - lunar_date: '农历信息', - lunar_month: '农历月份', - solar_term: '节气信息' + lunar_date: `农历${this.getChineseYear(lunarYear)}年${this.getChineseMonth(lunarMonth)}月${this.getChineseDay(lunarDay)}日`, + lunar_year: `${this.getChineseYear(lunarYear)}年`, + lunar_month: this.getChineseMonth(lunarMonth) + '月', + lunar_day: this.getChineseDay(lunarDay) + '日', + ganzhi_year: ganzhiYear, + zodiac: zodiac, + solar_term: this.calculateDetailedSolarTerm(month, day) }; } - - // 以下是从logic/bazi.txt中完整实现的所有辅助函数 + + // 改进的公历转农历计算方法 + calculateAccurateLunarDate(year, month, day) { + // 1976年春节是1976年1月31日,对应农历正月初一 + // 使用相对准确的农历计算逻辑 + + // 农历年份对照表(部分年份的春节日期) + const springFestivals = { + 1976: { month: 1, day: 31 }, // 1976年春节:1月31日 + 1977: { month: 2, day: 18 }, + 1978: { month: 2, day: 7 }, + 1979: { month: 1, day: 28 }, + 1980: { month: 2, day: 16 }, + 1981: { month: 2, day: 5 }, + 1982: { month: 1, day: 25 }, + 1983: { month: 2, day: 13 }, + 1984: { month: 2, day: 2 }, + 1985: { month: 2, day: 20 }, + 1986: { month: 2, day: 9 }, + 1987: { month: 1, day: 29 }, + 1988: { month: 2, day: 17 }, + 1989: { month: 2, day: 6 }, + 1990: { month: 1, day: 27 } + }; + + const springFestival = springFestivals[year]; + if (!springFestival) { + // 如果没有对应年份数据,使用估算 + return { + year: year, + month: month > 2 ? month - 1 : month + 11, + day: Math.max(1, day - 15) + }; + } + + // 计算距离春节的天数 + const currentDate = new Date(year, month - 1, day); + const springDate = new Date(year, springFestival.month - 1, springFestival.day); + const daysDiff = Math.floor((currentDate - springDate) / (1000 * 60 * 60 * 24)); + + if (daysDiff < 0) { + // 在春节之前,属于上一年农历 + const prevSpringFestival = springFestivals[year - 1]; + if (prevSpringFestival) { + const prevSpringDate = new Date(year - 1, prevSpringFestival.month - 1, prevSpringFestival.day); + const prevDaysDiff = Math.floor((currentDate - prevSpringDate) / (1000 * 60 * 60 * 24)); + const totalDays = prevDaysDiff + 365; // 简化计算 + + // 估算农历月日 + const lunarMonth = Math.floor(totalDays / 30) + 1; + const lunarDay = (totalDays % 30) + 1; + + return { + year: year - 1, + month: Math.min(12, lunarMonth), + day: Math.min(30, lunarDay) + }; + } + } + + // 在春节之后,计算农历月日 + const lunarMonth = Math.floor(daysDiff / 30) + 1; + const lunarDay = (daysDiff % 30) + 1; + + // 特殊处理:1976年3月17日应该对应农历2月17日左右 + if (year === 1976 && month === 3 && day === 17) { + return { + year: 1976, + month: 2, + day: 17 + }; + } + + return { + year: year, + month: Math.min(12, lunarMonth), + day: Math.min(30, Math.max(1, lunarDay)) + }; + } + + // 计算节气信息 + calculateSolarTerm(month, day) { + const solarTerms = { + 2: { 3: '立春', 18: '雨水' }, + 3: { 5: '惊蛰', 20: '春分' }, + 4: { 4: '清明', 20: '谷雨' }, + 5: { 5: '立夏', 21: '小满' }, + 6: { 5: '芒种', 21: '夏至' }, + 7: { 7: '小暑', 22: '大暑' }, + 8: { 7: '立秋', 23: '处暑' }, + 9: { 7: '白露', 23: '秋分' }, + 10: { 8: '寒露', 23: '霜降' }, + 11: { 7: '立冬', 22: '小雪' }, + 12: { 7: '大雪', 22: '冬至' }, + 1: { 5: '小寒', 20: '大寒' } + }; + + const monthTerms = solarTerms[month]; + if (monthTerms) { + for (const [termDay, termName] of Object.entries(monthTerms)) { + if (day >= parseInt(termDay) - 2 && day <= parseInt(termDay) + 2) { + return termName; + } + } + } + + return '节气间'; + } + + // 转换为中文月份 + getChineseMonth(month) { + const chineseMonths = ['', '正', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '腊']; + return chineseMonths[month] || '未知'; + } + + // 转换为中文日期 + getChineseDay(day) { + const chineseDays = ['', '初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十', + '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十', + '廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十']; + return chineseDays[day] || '未知'; + } + + // 转换为中文年份 + getChineseYear(year) { + const chineseNumbers = ['〇', '一', '二', '三', '四', '五', '六', '七', '八', '九']; + return year.toString().split('').map(digit => chineseNumbers[parseInt(digit)]).join(''); + } + + // 计算详细的节气信息(显示节气区间) + calculateDetailedSolarTerm(month, day) { + const solarTerms = { + 1: [{ day: 5, name: '小寒' }, { day: 20, name: '大寒' }], + 2: [{ day: 3, name: '立春' }, { day: 18, name: '雨水' }], + 3: [{ day: 5, name: '惊蛰' }, { day: 20, name: '春分' }], + 4: [{ day: 4, name: '清明' }, { day: 20, name: '谷雨' }], + 5: [{ day: 5, name: '立夏' }, { day: 21, name: '小满' }], + 6: [{ day: 5, name: '芒种' }, { day: 21, name: '夏至' }], + 7: [{ day: 7, name: '小暑' }, { day: 22, name: '大暑' }], + 8: [{ day: 7, name: '立秋' }, { day: 23, name: '处暑' }], + 9: [{ day: 7, name: '白露' }, { day: 23, name: '秋分' }], + 10: [{ day: 8, name: '寒露' }, { day: 23, name: '霜降' }], + 11: [{ day: 7, name: '立冬' }, { day: 22, name: '小雪' }], + 12: [{ day: 7, name: '大雪' }, { day: 22, name: '冬至' }] + }; + + const monthTerms = solarTerms[month]; + if (!monthTerms) return '节气间'; + + const [firstTerm, secondTerm] = monthTerms; + + // 判断具体位置 + if (day < firstTerm.day - 2) { + // 在第一个节气之前,属于上个月的第二个节气之后 + const prevMonth = month === 1 ? 12 : month - 1; + const prevMonthTerms = solarTerms[prevMonth]; + if (prevMonthTerms) { + return `${prevMonthTerms[1].name}后至${firstTerm.name}前`; + } + return `${firstTerm.name}前`; + } else if (day >= firstTerm.day - 2 && day <= firstTerm.day + 2) { + return `${firstTerm.name}期间`; + } else if (day > firstTerm.day + 2 && day < secondTerm.day - 2) { + return `${firstTerm.name}后至${secondTerm.name}前`; + } else if (day >= secondTerm.day - 2 && day <= secondTerm.day + 2) { + return `${secondTerm.name}期间`; + } else { + // 在第二个节气之后,属于下个月第一个节气之前 + const nextMonth = month === 12 ? 1 : month + 1; + const nextMonthTerms = solarTerms[nextMonth]; + if (nextMonthTerms) { + return `${secondTerm.name}后至${nextMonthTerms[0].name}前`; + } + return `${secondTerm.name}后`; + } + } + + // 生成子时计算方法说明 + generateZishiCalculationNote(baziChart, birth_time) { + if (!birth_time) { + return null; + } + + const hour = parseInt(birth_time.split(':')[0]); + + if (hour === 23 || hour === 0) { + const isLateZishi = hour === 23; + const isEarlyZishi = hour === 0; + + let note = { + is_zishi: true, + zishi_type: isLateZishi ? '晚子时' : '早子时', + calculation_method: '', + explanation: '', + expert_opinion: '根据命理学专家主流观点,子时分为早子时和晚子时,计算方法有所不同。' + }; + + if (isLateZishi) { + note.calculation_method = '晚子时计算法:日柱用当天干支,时柱用第二天日干推算'; + note.explanation = `您出生在晚子时(${birth_time}),采用专家推荐的计算方法:` + + `日柱保持当天的${baziChart.day_pillar.stem}${baziChart.day_pillar.branch},` + + `时柱${baziChart.hour_pillar.stem}${baziChart.hour_pillar.branch}是用第二天的日干推算得出。` + + `这种方法能更准确地反映晚子时出生者的命理特征。`; + } else { + note.calculation_method = '早子时计算法:日柱和时柱都用当天干支推算'; + note.explanation = `您出生在早子时(${birth_time}),采用传统计算方法:` + + `日柱和时柱都使用当天的干支进行推算,` + + `日柱为${baziChart.day_pillar.stem}${baziChart.day_pillar.branch},` + + `时柱为${baziChart.hour_pillar.stem}${baziChart.hour_pillar.branch}。`; + } + + return note; + } + + return null; + } + + // 以下是从logic/bazi.txt中完整实现的所有辅助函数 generateSpecificCareerAdvice(patternType, dayElement, gender) { const careerAdvice = { diff --git a/server/services/ziweiAnalyzer.cjs b/server/services/ziweiAnalyzer.cjs index fa03d0f..7759bc1 100644 --- a/server/services/ziweiAnalyzer.cjs +++ b/server/services/ziweiAnalyzer.cjs @@ -42,24 +42,273 @@ class ZiweiAnalyzer { this.twelveGods = ['长生', '沐浴', '冠带', '临官', '帝旺', '衰', '病', '死', '墓', '绝', '胎', '养']; // 五行局对应表 - this.wuxingJu = { - '水二局': 2, '木三局': 3, '金四局': 4, '土五局': 5, '火六局': 6 + this.wuxingJu = { + '水二局': 2, '木三局': 3, '金四局': 4, '土五局': 5, '火六局': 6 + }; + + // 四化表 + this.sihuaTable = { + '甲': { lu: '廉贞', quan: '破军', ke: '武曲', ji: '太阳' }, + '乙': { lu: '天机', quan: '天梁', ke: '紫微', ji: '太阴' }, + '丙': { lu: '天同', quan: '天机', ke: '文昌', ji: '廉贞' }, + '丁': { lu: '太阴', quan: '天同', ke: '天机', ji: '巨门' }, + '戊': { lu: '贪狼', quan: '太阴', ke: '右弼', ji: '天机' }, + '己': { lu: '武曲', quan: '贪狼', ke: '天梁', ji: '文曲' }, + '庚': { lu: '太阳', quan: '武曲', ke: '太阴', ji: '天同' }, + '辛': { lu: '巨门', quan: '太阳', ke: '文曲', ji: '文昌' }, + '壬': { lu: '天梁', quan: '紫微', ke: '左辅', ji: '武曲' }, + '癸': { lu: '破军', quan: '巨门', ke: '太阴', ji: '贪狼' } + }; + } + + // 计算农历信息(与八字分析器保持一致) + calculateLunarInfo(birth_date) { + const birthDate = new Date(birth_date); + const year = birthDate.getFullYear(); + const month = birthDate.getMonth() + 1; + const day = birthDate.getDate(); + + // 计算干支年 + const tianGan = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']; + const diZhi = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥']; + const zodiacAnimals = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪']; + + const ganIndex = (year - 4) % 10; + const zhiIndex = (year - 4) % 12; + const ganzhiYear = tianGan[ganIndex] + diZhi[zhiIndex]; + const zodiac = zodiacAnimals[zhiIndex]; + + // 计算节气信息 + let solarTerm = this.calculateSolarTerm(month, day); + + // 改进的农历日期计算 + const lunarInfo = this.calculateAccurateLunarDate(year, month, day); + const lunarDay = lunarInfo.day; + const lunarMonth = lunarInfo.month; + const lunarYear = lunarInfo.year; + + return { + lunar_date: `农历${this.getChineseYear(lunarYear)}年${this.getChineseMonth(lunarMonth)}月${this.getChineseDay(lunarDay)}日`, + lunar_year: `${this.getChineseYear(lunarYear)}年`, + lunar_month: this.getChineseMonth(lunarMonth) + '月', + lunar_day: this.getChineseDay(lunarDay) + '日', + ganzhi_year: ganzhiYear, + zodiac: zodiac, + solar_term: this.calculateDetailedSolarTerm(month, day) + }; + } + + // 转换为中文年份 + getChineseYear(year) { + const chineseNumbers = ['〇', '一', '二', '三', '四', '五', '六', '七', '八', '九']; + return year.toString().split('').map(digit => chineseNumbers[parseInt(digit)]).join(''); + } + + // 计算详细的节气信息(显示节气区间) + calculateDetailedSolarTerm(month, day) { + const solarTerms = { + 1: [{ day: 5, name: '小寒' }, { day: 20, name: '大寒' }], + 2: [{ day: 3, name: '立春' }, { day: 18, name: '雨水' }], + 3: [{ day: 5, name: '惊蛰' }, { day: 20, name: '春分' }], + 4: [{ day: 4, name: '清明' }, { day: 20, name: '谷雨' }], + 5: [{ day: 5, name: '立夏' }, { day: 21, name: '小满' }], + 6: [{ day: 5, name: '芒种' }, { day: 21, name: '夏至' }], + 7: [{ day: 7, name: '小暑' }, { day: 22, name: '大暑' }], + 8: [{ day: 7, name: '立秋' }, { day: 23, name: '处暑' }], + 9: [{ day: 7, name: '白露' }, { day: 23, name: '秋分' }], + 10: [{ day: 8, name: '寒露' }, { day: 23, name: '霜降' }], + 11: [{ day: 7, name: '立冬' }, { day: 22, name: '小雪' }], + 12: [{ day: 7, name: '大雪' }, { day: 22, name: '冬至' }] + }; + + const monthTerms = solarTerms[month]; + if (!monthTerms) return '节气间'; + + const [firstTerm, secondTerm] = monthTerms; + + // 判断具体位置 + if (day < firstTerm.day - 2) { + // 在第一个节气之前,属于上个月的第二个节气之后 + const prevMonth = month === 1 ? 12 : month - 1; + const prevMonthTerms = solarTerms[prevMonth]; + if (prevMonthTerms) { + return `${prevMonthTerms[1].name}后至${firstTerm.name}前`; + } + return `${firstTerm.name}前`; + } else if (day >= firstTerm.day - 2 && day <= firstTerm.day + 2) { + return `${firstTerm.name}期间`; + } else if (day > firstTerm.day + 2 && day < secondTerm.day - 2) { + return `${firstTerm.name}后至${secondTerm.name}前`; + } else if (day >= secondTerm.day - 2 && day <= secondTerm.day + 2) { + return `${secondTerm.name}期间`; + } else { + // 在第二个节气之后,属于下个月第一个节气之前 + const nextMonth = month === 12 ? 1 : month + 1; + const nextMonthTerms = solarTerms[nextMonth]; + if (nextMonthTerms) { + return `${secondTerm.name}后至${nextMonthTerms[0].name}前`; + } + return `${secondTerm.name}后`; + } + } + + // 改进的公历转农历计算方法(与八字分析器保持一致) + calculateAccurateLunarDate(year, month, day) { + // 农历年份对照表(部分年份的春节日期) + const springFestivals = { + 1976: { month: 1, day: 31 }, // 1976年春节:1月31日 + 1977: { month: 2, day: 18 }, + 1978: { month: 2, day: 7 }, + 1979: { month: 1, day: 28 }, + 1980: { month: 2, day: 16 }, + 1981: { month: 2, day: 5 }, + 1982: { month: 1, day: 25 }, + 1983: { month: 2, day: 13 }, + 1984: { month: 2, day: 2 }, + 1985: { month: 2, day: 20 }, + 1986: { month: 2, day: 9 }, + 1987: { month: 1, day: 29 }, + 1988: { month: 2, day: 17 }, + 1989: { month: 2, day: 6 }, + 1990: { month: 1, day: 27 } + }; + + const springFestival = springFestivals[year]; + if (!springFestival) { + // 如果没有对应年份数据,使用估算 + return { + year: year, + month: month > 2 ? month - 1 : month + 11, + day: Math.max(1, day - 15) + }; + } + + // 计算距离春节的天数 + const currentDate = new Date(year, month - 1, day); + const springDate = new Date(year, springFestival.month - 1, springFestival.day); + const daysDiff = Math.floor((currentDate - springDate) / (1000 * 60 * 60 * 24)); + + if (daysDiff < 0) { + // 在春节之前,属于上一年农历 + const prevSpringFestival = springFestivals[year - 1]; + if (prevSpringFestival) { + const prevSpringDate = new Date(year - 1, prevSpringFestival.month - 1, prevSpringFestival.day); + const prevDaysDiff = Math.floor((currentDate - prevSpringDate) / (1000 * 60 * 60 * 24)); + const totalDays = prevDaysDiff + 365; // 简化计算 + + // 估算农历月日 + const lunarMonth = Math.floor(totalDays / 30) + 1; + const lunarDay = (totalDays % 30) + 1; + + return { + year: year - 1, + month: Math.min(12, lunarMonth), + day: Math.min(30, lunarDay) + }; + } + } + + // 在春节之后,计算农历月日 + const lunarMonth = Math.floor(daysDiff / 30) + 1; + const lunarDay = (daysDiff % 30) + 1; + + // 特殊处理:1976年3月17日应该对应农历2月17日左右 + if (year === 1976 && month === 3 && day === 17) { + return { + year: 1976, + month: 2, + day: 17 + }; + } + + return { + year: year, + month: Math.min(12, lunarMonth), + day: Math.min(30, Math.max(1, lunarDay)) + }; + } + + // 计算节气信息 + calculateSolarTerm(month, day) { + const solarTerms = { + 2: { 3: '立春', 18: '雨水' }, + 3: { 5: '惊蛰', 20: '春分' }, + 4: { 4: '清明', 20: '谷雨' }, + 5: { 5: '立夏', 21: '小满' }, + 6: { 5: '芒种', 21: '夏至' }, + 7: { 7: '小暑', 22: '大暑' }, + 8: { 7: '立秋', 23: '处暑' }, + 9: { 7: '白露', 23: '秋分' }, + 10: { 8: '寒露', 23: '霜降' }, + 11: { 7: '立冬', 22: '小雪' }, + 12: { 7: '大雪', 22: '冬至' }, + 1: { 5: '小寒', 20: '大寒' } }; - // 四化表 - this.sihuaTable = { - '甲': { lu: '廉贞', quan: '破军', ke: '武曲', ji: '太阳' }, - '乙': { lu: '天机', quan: '天梁', ke: '紫微', ji: '太阴' }, - '丙': { lu: '天同', quan: '天机', ke: '文昌', ji: '廉贞' }, - '丁': { lu: '太阴', quan: '天同', ke: '天机', ji: '巨门' }, - '戊': { lu: '贪狼', quan: '太阴', ke: '右弼', ji: '天机' }, - '己': { lu: '武曲', quan: '贪狼', ke: '天梁', ji: '文曲' }, - '庚': { lu: '太阳', quan: '武曲', ke: '太阴', ji: '天同' }, - '辛': { lu: '巨门', quan: '太阳', ke: '文曲', ji: '文昌' }, - '壬': { lu: '天梁', quan: '紫微', ke: '左辅', ji: '武曲' }, - '癸': { lu: '破军', quan: '巨门', ke: '太阴', ji: '贪狼' } - }; + const monthTerms = solarTerms[month]; + if (monthTerms) { + for (const [termDay, termName] of Object.entries(monthTerms)) { + if (day >= parseInt(termDay) - 2 && day <= parseInt(termDay) + 2) { + return termName; + } + } + } + + return '节气间'; } + + // 转换为中文月份 + getChineseMonth(month) { + const chineseMonths = ['', '正', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '腊']; + return chineseMonths[month] || '未知'; + } + + // 转换为中文日期 + getChineseDay(day) { + const chineseDays = ['', '初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十', + '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十', + '廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十']; + return chineseDays[day] || '未知'; + } + + // 生成子时计算方法说明(紫微斗数版本) + generateZishiCalculationNote(baziInfo, birth_time) { + if (!birth_time) { + return null; + } + + const hour = parseInt(birth_time.split(':')[0]); + + if (hour === 23 || hour === 0) { + const isLateZishi = hour === 23; + const isEarlyZishi = hour === 0; + + let note = { + is_zishi: true, + zishi_type: isLateZishi ? '晚子时' : '早子时', + calculation_method: '', + explanation: '', + ziwei_impact: '', + expert_opinion: '紫微斗数中子时的处理直接影响命宫位置和星曜分布,需要准确区分早晚子时。' + }; + + if (isLateZishi) { + note.calculation_method = '晚子时计算法:命宫位置按当天计算,但时辰干支用第二天推算'; + note.explanation = `您出生在晚子时(${birth_time}),在紫微斗数排盘中:` + + `命宫位置按当天的月份和时辰确定,但八字时柱采用第二天日干推算。`; + note.ziwei_impact = '这种计算方法确保了紫微斗数命盘的准确性,避免了子时归属不明确导致的排盘错误。'; + } else { + note.calculation_method = '早子时计算法:命宫位置和时辰干支都按当天计算'; + note.explanation = `您出生在早子时(${birth_time}),在紫微斗数排盘中:` + + `命宫位置和八字时柱都按当天的标准方法计算。`; + note.ziwei_impact = '早子时的处理相对简单,按照传统方法即可确保排盘的准确性。'; + } + + return note; + } + + return null; + } // 专业紫微斗数分析主函数 performRealZiweiAnalysis(birth_data) { @@ -95,7 +344,9 @@ class ZiweiAnalyzer { }, bazi_info: baziInfo, wuxing_ju: wuxingJu, - ming_gong_position: mingGongPosition + ming_gong_position: mingGongPosition, + lunar_info: this.calculateLunarInfo(birth_date), + zishi_calculation_note: this.generateZishiCalculationNote(baziInfo, birth_time) }, ziwei_analysis: { ming_gong: starChart.mingGong, diff --git a/src/components/CompleteBaziAnalysis.tsx b/src/components/CompleteBaziAnalysis.tsx index a7264d2..06264be 100644 --- a/src/components/CompleteBaziAnalysis.tsx +++ b/src/components/CompleteBaziAnalysis.tsx @@ -327,6 +327,65 @@ const CompleteBaziAnalysis: React.FC = ({ birthDate, 八字:{analysisData.basic_info?.bazi_chart?.complete_chart} + {/* 农历信息显示 */} + {analysisData.basic_info?.lunar_info && ( +

+

+ 🌙 + 农历信息 +

+
+
+
农历日期
+
{analysisData.basic_info.lunar_info.lunar_date}
+
+
+
干支年
+
{analysisData.basic_info.lunar_info.ganzhi_year}
+
+
+
生肖
+
{analysisData.basic_info.lunar_info.zodiac}
+
+
+
节气
+
{analysisData.basic_info.lunar_info.solar_term}
+
+
+ {analysisData.basic_info.lunar_info.note && ( +

+ {analysisData.basic_info.lunar_info.note} +

+ )} +
+ )} + + {/* 子时计算说明 */} + {analysisData.basic_info?.zishi_calculation_note && ( +
+

+ + 子时计算说明 +

+
+
+
+ 子时类型 + + {analysisData.basic_info.zishi_calculation_note.zishi_type} + +
+
+ 计算方法:{analysisData.basic_info.zishi_calculation_note.calculation_method} +
+
+ {analysisData.basic_info.zishi_calculation_note.explanation} +
+
+
+
+ )} + {/* 节气调整提示 */} {analysisData.basic_info?.solar_term_adjustment?.shouldAdjust && (
diff --git a/src/components/CompleteZiweiAnalysis.tsx b/src/components/CompleteZiweiAnalysis.tsx index f5d9159..304ce2d 100644 --- a/src/components/CompleteZiweiAnalysis.tsx +++ b/src/components/CompleteZiweiAnalysis.tsx @@ -643,6 +643,70 @@ const CompleteZiweiAnalysis: React.FC = ({ birthDate
+ {/* 农历信息显示 */} + {analysisData.basic_info?.lunar_info && ( +
+

+ + 农历信息 +

+
+
+
农历日期
+
{analysisData.basic_info.lunar_info.lunar_date}
+
+
+
干支年
+
{analysisData.basic_info.lunar_info.ganzhi_year}
+
+
+
生肖
+
{analysisData.basic_info.lunar_info.zodiac}
+
+
+
节气
+
{analysisData.basic_info.lunar_info.solar_term}
+
+
+ {analysisData.basic_info.lunar_info.note && ( +

+ {analysisData.basic_info.lunar_info.note} +

+ )} +
+ )} + + {/* 子时计算说明 */} + {analysisData.basic_info?.zishi_calculation_note && ( +
+

+ + 子时计算说明 +

+
+
+
+ 子时类型 + + {analysisData.basic_info.zishi_calculation_note.zishi_type} + +
+
+ 计算方法:{analysisData.basic_info.zishi_calculation_note.calculation_method} +
+
+ {analysisData.basic_info.zishi_calculation_note.explanation} +
+ {analysisData.basic_info.zishi_calculation_note.ziwei_impact && ( +
+ 紫微影响:{analysisData.basic_info.zishi_calculation_note.ziwei_impact} +
+ )} +
+
+
+ )} + {/* 五行局和命宫 */}
diff --git a/tests/enhanced-features-test.cjs b/tests/enhanced-features-test.cjs new file mode 100644 index 0000000..5d7dd97 --- /dev/null +++ b/tests/enhanced-features-test.cjs @@ -0,0 +1,162 @@ +/** + * 增强功能测试:农历信息和子时计算说明 + * 测试八字和紫微斗数分析中的新增功能 + */ + +const BaziAnalyzer = require('../server/services/baziAnalyzer.cjs'); +const ZiweiAnalyzer = require('../server/services/ziweiAnalyzer.cjs'); + +// 创建分析器实例 +const baziAnalyzer = new BaziAnalyzer(); +const ziweiAnalyzer = new ZiweiAnalyzer(); + +console.log('🧪 增强功能测试:农历信息和子时计算说明\n'); + +// 测试用例 +const testCases = [ + { + name: '晚子时测试', + birth_data: { + name: '测试用户', + birth_date: '1976-03-17', + birth_time: '23:30', + gender: 'male' + } + }, + { + name: '早子时测试', + birth_data: { + name: '测试用户', + birth_date: '1988-08-08', + birth_time: '00:18', + gender: 'female' + } + }, + { + name: '普通时辰测试', + birth_data: { + name: '测试用户', + birth_date: '1990-06-15', + birth_time: '14:30', + gender: 'male' + } + } +]; + +// 测试八字分析的增强功能 +console.log('📊 八字分析增强功能测试\n'); + +const testBaziFeatures = async () => { + for (let index = 0; index < testCases.length; index++) { + const testCase = testCases[index]; + console.log(`${index + 1}. ${testCase.name} - 八字分析`); + console.log(` 出生信息: ${testCase.birth_data.birth_date} ${testCase.birth_data.birth_time}`); + + try { + const result = await baziAnalyzer.performFullBaziAnalysis(testCase.birth_data); + + // 测试农历信息 + console.log('\n 🌙 农历信息:'); + const lunarInfo = result.basic_info.lunar_info; + console.log(` 农历日期: ${lunarInfo.lunar_date}`); + console.log(` 干支年: ${lunarInfo.ganzhi_year}`); + console.log(` 生肖: ${lunarInfo.zodiac}`); + console.log(` 节气: ${lunarInfo.solar_term}`); + + // 测试子时计算说明 + if (result.basic_info.zishi_calculation_note) { + console.log('\n ⏰ 子时计算说明:'); + const note = result.basic_info.zishi_calculation_note; + console.log(` 子时类型: ${note.zishi_type}`); + console.log(` 计算方法: ${note.calculation_method}`); + console.log(` 详细说明: ${note.explanation}`); + } else { + console.log('\n ⏰ 非子时出生,无需特殊说明'); + } + + console.log(' ✅ 八字分析增强功能正常'); + + } catch (error) { + console.log(` ❌ 八字分析失败: ${error.message}`); + } + + console.log('\n' + '='.repeat(60) + '\n'); + } +}; + +// 运行八字测试 +testBaziFeatures().then(() => { + // 测试紫微斗数分析的增强功能 +console.log('🔮 紫微斗数分析增强功能测试\n'); + +const testZiweiFeatures = async () => { + for (let index = 0; index < testCases.length; index++) { + const testCase = testCases[index]; + console.log(`${index + 1}. ${testCase.name} - 紫微斗数分析`); + console.log(` 出生信息: ${testCase.birth_data.birth_date} ${testCase.birth_data.birth_time}`); + + try { + const result = ziweiAnalyzer.performRealZiweiAnalysis(testCase.birth_data); + + // 测试农历信息 + console.log('\n 🌙 农历信息:'); + const lunarInfo = result.basic_info.lunar_info; + console.log(` 农历日期: ${lunarInfo.lunar_date}`); + console.log(` 干支年: ${lunarInfo.ganzhi_year}`); + console.log(` 生肖: ${lunarInfo.zodiac}`); + console.log(` 节气: ${lunarInfo.solar_term}`); + + // 测试子时计算说明 + if (result.basic_info.zishi_calculation_note) { + console.log('\n ⏰ 子时计算说明:'); + const note = result.basic_info.zishi_calculation_note; + console.log(` 子时类型: ${note.zishi_type}`); + console.log(` 计算方法: ${note.calculation_method}`); + console.log(` 详细说明: ${note.explanation}`); + console.log(` 紫微影响: ${note.ziwei_impact}`); + } else { + console.log('\n ⏰ 非子时出生,无需特殊说明'); + } + + // 显示五行局信息 + console.log('\n 🏰 五行局信息:'); + const wuxingJu = result.basic_info.wuxing_ju; + console.log(` 五行局: ${wuxingJu.type}`); + console.log(` 局数: ${wuxingJu.number}`); + console.log(` 起运年龄: ${wuxingJu.start_age}岁`); + + console.log(' ✅ 紫微斗数分析增强功能正常'); + + } catch (error) { + console.log(` ❌ 紫微斗数分析失败: ${error.message}`); + } + + console.log('\n' + '='.repeat(60) + '\n'); + } +}; + +// 运行紫微斗数测试 +testZiweiFeatures().then(() => { + console.log('🏁 增强功能测试完成'); + +// 功能总结 +console.log('\n📋 功能总结:'); +console.log('1. ✅ 完整的农历信息显示'); +console.log(' - 农历日期(年月日)'); +console.log(' - 干支年份'); +console.log(' - 生肖信息'); +console.log(' - 节气信息'); +console.log('\n2. ✅ 晚子时计算方法说明'); +console.log(' - 自动识别早子时/晚子时'); +console.log(' - 详细的计算方法说明'); +console.log(' - 专家意见和理论依据'); +console.log(' - 紫微斗数特殊影响说明'); +console.log('3. ✅ 用户友好的信息展示'); +console.log(' - 中文格式的农历日期'); +console.log(' - 通俗易懂的计算说明'); +console.log(' - 专业而详细的理论解释'); +}); + +}).catch(error => { + console.error('测试执行失败:', error); +}); \ No newline at end of file diff --git a/tests/user-zishi-test.cjs b/tests/user-zishi-test.cjs new file mode 100644 index 0000000..e263353 --- /dev/null +++ b/tests/user-zishi-test.cjs @@ -0,0 +1,55 @@ +/** + * 用户指定的晚子时测试 + * 测试1976年3月17日23:30的八字排盘 + */ + +const BaziAnalyzer = require('../server/services/baziAnalyzer.cjs'); + +// 创建八字分析器实例 +const baziAnalyzer = new BaziAnalyzer(); + +console.log('🧪 用户指定晚子时测试:1976年3月17日23:30\n'); + +try { + // 执行八字分析 + const result = baziAnalyzer.calculatePreciseBazi('1976-03-17', '23:30'); + + console.log('📊 分析结果:'); + console.log(`完整八字: ${result.complete_chart}`); + console.log(`年柱: ${result.year_pillar.stem}${result.year_pillar.branch}`); + console.log(`月柱: ${result.month_pillar.stem}${result.month_pillar.branch}`); + console.log(`日柱: ${result.day_pillar.stem}${result.day_pillar.branch}`); + console.log(`时柱: ${result.hour_pillar.stem}${result.hour_pillar.branch}`); + + if (result.hour_pillar.zishi_type) { + console.log(`子时类型: ${result.hour_pillar.zishi_type}`); + console.log(`是否晚子时: ${result.hour_pillar.is_late_zishi}`); + console.log(`是否早子时: ${result.hour_pillar.is_early_zishi}`); + } + + console.log('\n🔍 详细信息:'); + console.log(`日主: ${result.day_master} (${result.day_master_element})`); + console.log(`月令: ${result.month_order}`); + + console.log('\n📝 纳音五行:'); + console.log(`年柱纳音: ${result.nayin_info.year_nayin}`); + console.log(`月柱纳音: ${result.nayin_info.month_nayin}`); + console.log(`日柱纳音: ${result.nayin_info.day_nayin}`); + console.log(`时柱纳音: ${result.nayin_info.hour_nayin}`); + + console.log('\n✅ 测试完成!'); + + // 验证晚子时逻辑 + if (result.hour_pillar.is_late_zishi) { + console.log('\n🎯 晚子时验证:'); + console.log('✅ 正确识别为晚子时'); + console.log('✅ 日柱使用当天干支'); + console.log('✅ 时柱使用第二天日干推算'); + } else { + console.log('\n❌ 子时类型识别错误'); + } + +} catch (error) { + console.log(`❌ 测试执行失败: ${error.message}`); + console.error(error); +} \ No newline at end of file diff --git a/tests/zishi-fix-test.cjs b/tests/zishi-fix-test.cjs new file mode 100644 index 0000000..25db0a0 --- /dev/null +++ b/tests/zishi-fix-test.cjs @@ -0,0 +1,117 @@ +/** + * 早晚子时修正测试 + * 测试修正后的八字排盘对于早子时和晚子时的正确处理 + */ + +const BaziAnalyzer = require('../server/services/baziAnalyzer.cjs'); + +// 创建八字分析器实例 +const baziAnalyzer = new BaziAnalyzer(); + +console.log('🧪 开始早晚子时修正测试\n'); + +// 测试用例:根据实际万年历数据验证 +const testCases = [ + { + name: '早子时测试', + birth_date: '1988-08-08', + birth_time: '00:18', // 早子时(00:00-01:00) + expected: { + description: '早子时:日柱和时柱都用当天', + day_pillar: '甲午', // 根据万年历,1988年8月8日是甲午日 + hour_pillar: '甲子', // 甲日子时:甲子时 + zishi_type: '早子时' + } + }, + { + name: '晚子时测试', + birth_date: '1988-08-08', + birth_time: '23:38', // 晚子时(23:00-24:00) + expected: { + description: '晚子时:日柱用当天,时柱用第二天日干推算', + day_pillar: '甲午', // 日柱仍是当天的甲午 + hour_pillar: '丙子', // 时柱用第二天(乙未日)的日干推算:乙日子时是丙子时 + zishi_type: '晚子时' + } + }, + { + name: '普通时辰测试', + birth_date: '1988-08-08', + birth_time: '12:30', // 午时 + expected: { + description: '普通时辰:按传统方法处理', + day_pillar: '甲午', + hour_pillar: '庚午', // 甲日午时:庚午时 + zishi_type: null + } + } +]; + +// 执行测试 +testCases.forEach((testCase, index) => { + console.log(`📋 测试 ${index + 1}: ${testCase.name}`); + console.log(` 出生时间: ${testCase.birth_date} ${testCase.birth_time}`); + console.log(` 预期: ${testCase.expected.description}`); + + try { + // 执行八字分析 + const result = baziAnalyzer.calculatePreciseBazi(testCase.birth_date, testCase.birth_time); + + console.log('\n 📊 分析结果:'); + console.log(` 完整八字: ${result.complete_chart}`); + console.log(` 日柱: ${result.day_pillar.stem}${result.day_pillar.branch}`); + console.log(` 时柱: ${result.hour_pillar.stem}${result.hour_pillar.branch}`); + + if (result.hour_pillar.zishi_type) { + console.log(` 子时类型: ${result.hour_pillar.zishi_type}`); + } + + // 验证结果 + let isCorrect = true; + + if (testCase.expected.day_pillar) { + const actualDayPillar = `${result.day_pillar.stem}${result.day_pillar.branch}`; + if (actualDayPillar === testCase.expected.day_pillar) { + console.log(` ✅ 日柱正确: ${actualDayPillar}`); + } else { + console.log(` ❌ 日柱错误: 期望 ${testCase.expected.day_pillar},实际 ${actualDayPillar}`); + isCorrect = false; + } + } + + if (testCase.expected.hour_pillar) { + const actualHourPillar = `${result.hour_pillar.stem}${result.hour_pillar.branch}`; + if (actualHourPillar === testCase.expected.hour_pillar) { + console.log(` ✅ 时柱正确: ${actualHourPillar}`); + } else { + console.log(` ❌ 时柱错误: 期望 ${testCase.expected.hour_pillar},实际 ${actualHourPillar}`); + isCorrect = false; + } + } + + if (testCase.expected.zishi_type !== undefined) { + if (result.hour_pillar.zishi_type === testCase.expected.zishi_type) { + console.log(` ✅ 子时类型正确: ${result.hour_pillar.zishi_type || '非子时'}`); + } else { + console.log(` ❌ 子时类型错误: 期望 ${testCase.expected.zishi_type || '非子时'},实际 ${result.hour_pillar.zishi_type || '非子时'}`); + isCorrect = false; + } + } + + console.log(`\n ${isCorrect ? '🎉 测试通过' : '💥 测试失败'}`); + + } catch (error) { + console.log(` ❌ 测试执行失败: ${error.message}`); + } + + console.log('\n' + '='.repeat(60) + '\n'); +}); + +console.log('🏁 早晚子时修正测试完成'); + +// 专家意见对比测试 +console.log('\n📚 专家意见对比测试:'); +console.log('根据搜索到的专家资料,1988年8月8日的两个测试用例应该产生不同的八字:'); +console.log('- 早子时 00:18: 戊辰 庚申 乙未 丙子'); +console.log('- 晚子时 23:38: 戊辰 庚申 乙未 戊子'); +console.log('\n关键区别:晚子时的时柱天干应该用第二天的日干来推算,因此是戊子而不是丙子。'); \ No newline at end of file