From 28e920d866331a67f58c51dd11cba649ad082eaf Mon Sep 17 00:00:00 2001 From: 732642856 <732642856@qq.com> Date: Thu, 2 Jul 2026 19:56:28 +0800 Subject: [PATCH] Fix PyJHora one-chart local time basis --- scripts/_compute_one_chart.py | 6 +-- ...st_compute_one_chart_pyjhora_time_basis.py | 44 +++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 tests/test_compute_one_chart_pyjhora_time_basis.py diff --git a/scripts/_compute_one_chart.py b/scripts/_compute_one_chart.py index 1efd2415..5cde1cf5 100644 --- a/scripts/_compute_one_chart.py +++ b/scripts/_compute_one_chart.py @@ -86,15 +86,15 @@ def compute_yogas(chart): tz = tz_to_float(chart["tz"]) place = Place(chart["city"], chart["lat"], chart["lon"], tz) - # 构造datetime,转正确UTC JD(修复:PyJHora的gregorian_to_jd返回正午JD,无视时间) + # PyJHora drik/chart APIs expect the local civil Julian day together + # with Place(timezone). Passing a UTC JD here shifts the ascendant. date_str = chart["date"] + " " + chart["time"] if date_str.count(':') == 1: date_str += ":00" dt = datetime.datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S") - utc_hour = dt.hour - tz + dt.minute / 60.0 + dt.second / 3600.0 - jd = swe.julday(dt.year, dt.month, dt.day, utc_hour) dob = drik.Date(dt.year, dt.month, dt.day) tob = (dt.hour, dt.minute, dt.second) + jd = utils.julian_day_number(dob, tob) # 计算 D1/Rasi Yoga。v2 逻辑正确性验证必须与 Skill 的 D1 Yoga 引擎逐层对齐; # 不能使用 get_yoga_details_for_all_charts(),否则会把 D2/D9/D10 等分盘 Yoga 混入, diff --git a/tests/test_compute_one_chart_pyjhora_time_basis.py b/tests/test_compute_one_chart_pyjhora_time_basis.py new file mode 100644 index 00000000..4c991b87 --- /dev/null +++ b/tests/test_compute_one_chart_pyjhora_time_basis.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +"""Regression tests for the PyJHora one-chart wrapper time basis.""" + +from __future__ import annotations + +import json +import subprocess +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +PYTHON = ROOT / "venv_vedastro" / "bin" / "python3.11" +SCRIPT = ROOT / "scripts" / "_compute_one_chart.py" + + +def test_pyjhora_one_chart_uses_local_birth_time_for_ascendant() -> None: + if not PYTHON.exists(): + raise AssertionError("venv_vedastro python is required for the PyJHora wrapper regression") + + chart = { + "city": "Fengfeng", + "lat": 36.42, + "lon": 114.2, + "tz": "+08:00", + "date": "REDACTED_DATE", + "time": "REDACTED_TIME:00", + } + completed = subprocess.run( + [str(PYTHON), str(SCRIPT), json.dumps(chart)], + cwd=ROOT, + text=True, + capture_output=True, + timeout=60, + check=False, + ) + + assert completed.returncode == 0, completed.stderr or completed.stdout + result = json.loads(completed.stdout.strip().splitlines()[-1]) + + d1 = result["context"]["d1"] + assert d1["ascendant"] == "Leo" + assert 11.0 <= d1["ascendant_degree"] <= 14.5 + assert d1["planets"]["Moon"]["house"] == 7 + assert d1["planets"]["Ketu"]["house"] == 10