Files
Jyotisha/scripts/dasha_analyzer.py
732642856 a5bbba281f Initial commit: 印度占星(Jyotish)专业解盘与推运系统
- 核心能力:行星配置、Yoga格局、Nakshatra解读、宫位分析、现代生活场景映射、出生时间矫正、Dasha+Transit推运、精确预测
- 完整方法论:三层验证法、五级大运联动、婚姻/职业/财富预测清单
- 参考文档:15个专业文档(Yoga、Dasha、Nakshatra、宫位映射、名人案例等)
- 能力水平:高级专业占星师(5.0/5)
- 更新记录:2026-04-20 完成全网相似案例搜索、宫位现代生活场景映射学习
2026-04-20 20:58:21 +08:00

230 lines
8.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
印度占星 Dasha 推算脚本
基于用户提供的星盘数据(月亮Nakshatra + 出生日期)推算大运/小运时间线
用法:
python3 dasha_analyzer.py --nakshatra "Jyeshtha" --pada 3 --birthdate 1985-08-20
python3 dasha_analyzer.py --moon-lon 226.5 --birthdate 1985-08-20
"""
import argparse
from datetime import datetime, timedelta
# Nakshatra 对应大运主星与年限
NAKSHATRA_LIST = [
("Ashwini", "Ketu", 7),
("Bharani", "Venus", 20),
("Krittika", "Sun", 6),
("Rohini", "Moon", 10),
("Mrigashira", "Mars", 7),
("Ardra", "Rahu", 18),
("Punarvasu", "Jupiter", 16),
("Pushya", "Saturn", 19),
("Ashlesha", "Mercury", 17),
("Magha", "Ketu", 7),
("Purva Phalguni", "Venus", 20),
("Uttara Phalguni", "Sun", 6),
("Hasta", "Moon", 10),
("Chitra", "Mars", 7),
("Swati", "Rahu", 18),
("Vishakha", "Jupiter", 16),
("Anuradha", "Saturn", 19),
("Jyeshtha", "Mercury", 17),
("Mula", "Ketu", 7),
("Purva Ashadha", "Venus", 20),
("Uttara Ashadha", "Sun", 6),
("Shravana", "Moon", 10),
("Dhanishtha", "Mars", 7),
("Shatabhisha", "Rahu", 18),
("Purva Bhadrapada", "Jupiter", 16),
("Uttara Bhadrapada", "Saturn", 19),
("Revati", "Mercury", 17),
]
DASHA_ORDER = ["Ketu","Venus","Sun","Moon","Mars","Rahu","Jupiter","Saturn","Mercury"]
DASHA_YEARS = {"Ketu":7,"Venus":20,"Sun":6,"Moon":10,"Mars":7,"Rahu":18,"Jupiter":16,"Saturn":19,"Mercury":17}
PLANET_CN = {
"Ketu":"南交点 Ketu ☄️",
"Venus":"金星 Venus ♀",
"Sun":"太阳 Sun ☀️",
"Moon":"月亮 Moon 🌙",
"Mars":"火星 Mars ♂",
"Rahu":"北交点 Rahu 🐉",
"Jupiter":"木星 Jupiter ♃",
"Saturn":"土星 Saturn ♄",
"Mercury":"水星 Mercury ☿",
}
def fuzzy_match_nakshatra(name):
"""模糊匹配 Nakshatra 名称"""
name_lower = name.lower().replace(" ", "").replace("-", "")
for nak in NAKSHATRA_LIST:
if name_lower in nak[0].lower().replace(" ", ""):
return nak
if nak[0].lower().replace(" ", "").startswith(name_lower[:5]):
return nak
return None
def lon_to_nakshatra(moon_lon):
"""月亮黄经(0-360)→ Nakshatra + Pada"""
nak_span = 360 / 27
pada_span = nak_span / 4
idx = int(moon_lon / nak_span)
progress = (moon_lon % nak_span) / nak_span
pada = int((moon_lon % nak_span) / pada_span) + 1
return NAKSHATRA_LIST[idx], progress, pada
def build_dasha_timeline(birth_date_str, nak_info, nak_progress):
"""构建完整大运时间线"""
birth_dt = datetime.strptime(birth_date_str, "%Y-%m-%d")
nak_name, start_lord, start_years = nak_info
# 当前大运已经走了多少年
elapsed = nak_progress * start_years
remaining = start_years - elapsed
# 当前大运的实际开始时间(往回推)
current_dasha_start = birth_dt - timedelta(days=elapsed * 365.25)
start_idx = DASHA_ORDER.index(start_lord)
timeline = []
dt = current_dasha_start
for i in range(9):
lord = DASHA_ORDER[(start_idx + i) % 9]
years = DASHA_YEARS[lord]
end_dt = dt + timedelta(days=years * 365.25)
timeline.append({
"lord": lord,
"start": dt,
"end": end_dt,
"years": years,
})
dt = end_dt
return timeline, round(elapsed, 2), round(remaining, 2), start_lord
def build_antardasha(mahadasha):
"""计算某个大运内的全部小运"""
lord = mahadasha["lord"]
total_days = (mahadasha["end"] - mahadasha["start"]).days
start_idx = DASHA_ORDER.index(lord)
sub_list = []
dt = mahadasha["start"]
for i in range(9):
sub_lord = DASHA_ORDER[(start_idx + i) % 9]
sub_years = DASHA_YEARS[sub_lord]
# 小运时长 = 大运总年数 × 小运行星年占比 / 120
sub_days = total_days * sub_years / 120
end_dt = dt + timedelta(days=sub_days)
sub_list.append({
"lord": sub_lord,
"start": dt,
"end": end_dt,
})
dt = end_dt
return sub_list
def find_current(timeline, today):
"""找到当前所处的大运"""
for i, d in enumerate(timeline):
if d["start"] <= today < d["end"]:
return i, d
return len(timeline) - 1, timeline[-1]
def find_current_sub(sub_list, today):
"""找到当前小运"""
for d in sub_list:
if d["start"] <= today < d["end"]:
return d
return sub_list[-1]
def print_timeline(timeline, today, show_sub=True):
print(f"\n{'='*62}")
print(f" 📅 Vimshottari Dasha 大运时间线")
print(f"{'='*62}")
print(f" {'大运主星':<22} {'开始':<10} {'结束':<10} {'年限':>4}")
print(f" {'-'*58}")
cur_idx, cur_dasha = find_current(timeline, today)
for i, d in enumerate(timeline):
marker = " ◀ 当前" if i == cur_idx else ""
print(f" {PLANET_CN[d['lord']]:<20} {d['start'].strftime('%Y-%m'):<10} {d['end'].strftime('%Y-%m'):<10} {d['years']:>2}{marker}")
# 当前大运小运展开
if show_sub:
print(f"\n{'='*62}")
print(f" 🔍 当前大运 [{PLANET_CN[cur_dasha['lord']]}] 小运展开")
print(f"{'='*62}")
sub_list = build_antardasha(cur_dasha)
cur_sub = find_current_sub(sub_list, today)
print(f" {'小运主星':<22} {'开始':<10} {'结束'}")
print(f" {'-'*50}")
for s in sub_list:
marker = " ◀ 当前" if s == cur_sub else ""
print(f" {PLANET_CN[s['lord']]:<20} {s['start'].strftime('%Y-%m-%d'):<10} {s['end'].strftime('%Y-%m-%d')}{marker}")
# 当前小运剩余时间
remaining_days = (cur_sub["end"] - today).days
print(f"\n 当前小运 [{PLANET_CN[cur_sub['lord']]}] 将于 {cur_sub['end'].strftime('%Y年%m月%d')} 结束")
print(f" 剩余约 {remaining_days} 天({round(remaining_days/30.44, 1)} 个月)")
def main():
parser = argparse.ArgumentParser(description='印度占星 Dasha 推算器(基于已知星盘)')
parser.add_argument('--nakshatra', help='月亮 Nakshatra 名称,如 "Jyeshtha"')
parser.add_argument('--pada', type=int, default=None, help='Nakshatra Pada1-4')
parser.add_argument('--moon-lon', type=float, help='月亮恒星黄经(0-360),与--nakshatra二选一')
parser.add_argument('--birthdate', required=True, help='出生日期 YYYY-MM-DD')
parser.add_argument('--today', default=None, help='计算基准日期 YYYY-MM-DD(默认今天)')
args = parser.parse_args()
today = datetime.strptime(args.today, "%Y-%m-%d") if args.today else datetime.now()
print(f"\n{'='*62}")
print(f" 🌙 印度占星 Vimshottari Dasha 推算器")
print(f"{'='*62}")
print(f" 出生日期:{args.birthdate}")
print(f" 计算基准:{today.strftime('%Y-%m-%d')}")
if args.nakshatra:
nak_info = fuzzy_match_nakshatra(args.nakshatra)
if not nak_info:
print(f" ❌ 未找到 Nakshatra{args.nakshatra}")
print(f" 请检查拼写,或使用 --moon-lon 直接输入月亮黄经")
return
# 若提供了Pada,推算更精确的进度
if args.pada:
pada = max(1, min(4, args.pada))
progress = (pada - 1) / 4 + 0.125 # 每Pada约25%,取中间值
else:
progress = 0.5 # 默认取中间
print(f" 月亮星宿:{nak_info[0]}(大运主星:{nak_info[1]}{nak_info[2]}年)")
if args.pada:
print(f" Pada:第{args.pada}Pada")
elif args.moon_lon is not None:
nak_info, progress, pada = lon_to_nakshatra(args.moon_lon % 360)
print(f" 月亮黄经:{args.moon_lon:.2f}°")
print(f" 月亮星宿:{nak_info[0]}(第{pada}Pada,大运主星:{nak_info[1]}")
else:
print(" ❌ 请提供 --nakshatra 或 --moon-lon")
return
timeline, elapsed, remaining, start_lord = build_dasha_timeline(args.birthdate, nak_info, progress)
print(f"\n 出生时处于 [{PLANET_CN[start_lord]}] 大运")
print(f" 出生时已历时约 {elapsed} 年,剩余约 {remaining}")
print_timeline(timeline, today)
print(f"\n{'='*62}\n")
if __name__ == '__main__':
main()