mirror of
https://github.com/patdelphi/suanming.git
synced 2026-02-28 05:33:11 +08:00
feat: Enhanced lunar calendar display and Zi Shi calculation improvements
- 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
This commit is contained in:
@@ -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*
|
||||
*仅供参考,请理性对待*
|
||||
BIN
debug-error.txt
BIN
debug-error.txt
Binary file not shown.
@@ -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 = {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -327,6 +327,65 @@ const CompleteBaziAnalysis: React.FC<CompleteBaziAnalysisProps> = ({ birthDate,
|
||||
八字:{analysisData.basic_info?.bazi_chart?.complete_chart}
|
||||
</div>
|
||||
|
||||
{/* 农历信息显示 */}
|
||||
{analysisData.basic_info?.lunar_info && (
|
||||
<div className="mb-4 p-4 bg-gradient-to-r from-purple-50 to-pink-50 rounded-lg border border-purple-200">
|
||||
<h4 className="font-bold text-purple-800 mb-3 flex items-center">
|
||||
<span className="mr-2">🌙</span>
|
||||
农历信息
|
||||
</h4>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-3 text-sm">
|
||||
<div className="text-center">
|
||||
<div className="text-purple-700 font-semibold mb-1">农历日期</div>
|
||||
<div className="text-purple-800 font-bold">{analysisData.basic_info.lunar_info.lunar_date}</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-purple-700 font-semibold mb-1">干支年</div>
|
||||
<div className="text-purple-800 font-bold">{analysisData.basic_info.lunar_info.ganzhi_year}</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-purple-700 font-semibold mb-1">生肖</div>
|
||||
<div className="text-purple-800 font-bold">{analysisData.basic_info.lunar_info.zodiac}</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-purple-700 font-semibold mb-1">节气</div>
|
||||
<div className="text-purple-800 font-bold">{analysisData.basic_info.lunar_info.solar_term}</div>
|
||||
</div>
|
||||
</div>
|
||||
{analysisData.basic_info.lunar_info.note && (
|
||||
<p className="text-purple-600 text-xs mt-3 text-center">
|
||||
{analysisData.basic_info.lunar_info.note}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 子时计算说明 */}
|
||||
{analysisData.basic_info?.zishi_calculation_note && (
|
||||
<div className="mb-4 p-4 bg-gradient-to-r from-blue-50 to-indigo-50 rounded-lg border border-blue-200">
|
||||
<h4 className="font-bold text-blue-800 mb-3 flex items-center">
|
||||
<span className="mr-2">⏰</span>
|
||||
子时计算说明
|
||||
</h4>
|
||||
<div className="space-y-3">
|
||||
<div className="bg-white p-3 rounded-lg border border-blue-100">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-blue-700 font-semibold">子时类型</span>
|
||||
<span className="text-blue-800 font-bold px-2 py-1 bg-blue-100 rounded">
|
||||
{analysisData.basic_info.zishi_calculation_note.zishi_type}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-blue-700 text-sm mb-2">
|
||||
<strong>计算方法:</strong>{analysisData.basic_info.zishi_calculation_note.calculation_method}
|
||||
</div>
|
||||
<div className="text-blue-600 text-sm">
|
||||
{analysisData.basic_info.zishi_calculation_note.explanation}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 节气调整提示 */}
|
||||
{analysisData.basic_info?.solar_term_adjustment?.shouldAdjust && (
|
||||
<div className="mb-4 p-3 bg-yellow-50 border border-yellow-200 rounded-lg">
|
||||
|
||||
@@ -643,6 +643,70 @@ const CompleteZiweiAnalysis: React.FC<CompleteZiweiAnalysisProps> = ({ birthDate
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 农历信息显示 */}
|
||||
{analysisData.basic_info?.lunar_info && (
|
||||
<div className="bg-gradient-to-r from-pink-50 to-rose-50 p-4 rounded-lg border border-pink-200">
|
||||
<h4 className="font-bold text-pink-800 mb-3 flex items-center">
|
||||
<Moon className="h-5 w-5 mr-2" />
|
||||
农历信息
|
||||
</h4>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-3 text-sm">
|
||||
<div className="text-center">
|
||||
<div className="text-pink-700 font-semibold mb-1">农历日期</div>
|
||||
<div className="text-pink-800 font-bold">{analysisData.basic_info.lunar_info.lunar_date}</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-pink-700 font-semibold mb-1">干支年</div>
|
||||
<div className="text-pink-800 font-bold">{analysisData.basic_info.lunar_info.ganzhi_year}</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-pink-700 font-semibold mb-1">生肖</div>
|
||||
<div className="text-pink-800 font-bold">{analysisData.basic_info.lunar_info.zodiac}</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-pink-700 font-semibold mb-1">节气</div>
|
||||
<div className="text-pink-800 font-bold">{analysisData.basic_info.lunar_info.solar_term}</div>
|
||||
</div>
|
||||
</div>
|
||||
{analysisData.basic_info.lunar_info.note && (
|
||||
<p className="text-pink-600 text-xs mt-3 text-center">
|
||||
{analysisData.basic_info.lunar_info.note}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 子时计算说明 */}
|
||||
{analysisData.basic_info?.zishi_calculation_note && (
|
||||
<div className="bg-gradient-to-r from-cyan-50 to-blue-50 p-4 rounded-lg border border-cyan-200">
|
||||
<h4 className="font-bold text-cyan-800 mb-3 flex items-center">
|
||||
<Clock className="h-5 w-5 mr-2" />
|
||||
子时计算说明
|
||||
</h4>
|
||||
<div className="space-y-3">
|
||||
<div className="bg-white p-3 rounded-lg border border-cyan-100">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-cyan-700 font-semibold">子时类型</span>
|
||||
<span className="text-cyan-800 font-bold px-2 py-1 bg-cyan-100 rounded">
|
||||
{analysisData.basic_info.zishi_calculation_note.zishi_type}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-cyan-700 text-sm mb-2">
|
||||
<strong>计算方法:</strong>{analysisData.basic_info.zishi_calculation_note.calculation_method}
|
||||
</div>
|
||||
<div className="text-cyan-600 text-sm mb-2">
|
||||
{analysisData.basic_info.zishi_calculation_note.explanation}
|
||||
</div>
|
||||
{analysisData.basic_info.zishi_calculation_note.ziwei_impact && (
|
||||
<div className="text-cyan-600 text-sm">
|
||||
<strong>紫微影响:</strong>{analysisData.basic_info.zishi_calculation_note.ziwei_impact}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 五行局和命宫 */}
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<div className="bg-white p-4 rounded-lg border-l-4 border-indigo-500">
|
||||
|
||||
162
tests/enhanced-features-test.cjs
Normal file
162
tests/enhanced-features-test.cjs
Normal file
@@ -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);
|
||||
});
|
||||
55
tests/user-zishi-test.cjs
Normal file
55
tests/user-zishi-test.cjs
Normal file
@@ -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);
|
||||
}
|
||||
117
tests/zishi-fix-test.cjs
Normal file
117
tests/zishi-fix-test.cjs
Normal file
@@ -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关键区别:晚子时的时柱天干应该用第二天的日干来推算,因此是戊子而不是丙子。');
|
||||
Reference in New Issue
Block a user