fix(solar-return): thread the birth second into the return instant (BUG-1267, upstream e4a6ac01)
This commit is contained in:
@@ -17030,3 +17030,19 @@
|
||||
- 相关记录:无
|
||||
- 复发自:无
|
||||
- 修复版本:本分支待发布
|
||||
|
||||
## BUG-1267 | 太阳返照丢掉出生秒
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-10-07
|
||||
- 最近更新:2026-10-07
|
||||
- 影响面:`scripts/solar_return.py`、`scripts/cmd_solar_return.py`、全盘与年运接口里的太阳返照
|
||||
- 用户现象:出生秒不是 0 时,返照时刻仍按整分计算
|
||||
- 触发条件:计算太阳返照盘或 Varshaphala 完整报告
|
||||
- 根因:`calc_solar_return_chart` 与 `solar_return_full_report` 的出生时刻只接到分。上游 `e4a6ac01` 把秒传进出生盘。同一提交里的视位置拟合、减 5 秒和交点修正没有启用。Shadbala 方法声明函数只在未移植的 `evidence_labeled_reporting.py`,本仓没有对应函数,文案未改
|
||||
- 修复:上述两个函数、命令行、全盘两处调用和年运接口都传入 `birth_second`。年运接口把秒写在原有参数行上,不增加行数。近似无星历时,秒也进入出生时刻
|
||||
- 验证:`tests/test_solar_return_birth_second.py`。虚构盘秒 40 与秒 0 的返照儒略日相差超过 20 秒,且与上游 `23be1807` 的返照时刻一致
|
||||
- 防复发:上述测试钉住上游时刻
|
||||
- 相关记录:BUG-1220
|
||||
- 复发自:无
|
||||
- 修复版本:本分支待发布
|
||||
|
||||
@@ -43,6 +43,7 @@ def cmd_solar_return(args: Any) -> Dict[str, Any]:
|
||||
args.lat, args.lon, args.tz,
|
||||
args.target_year,
|
||||
ayanamsa_name=getattr(args, 'ayanamsa', None) or DEFAULT_AYANAMSA_NAME,
|
||||
birth_second=int(getattr(args, 'second', 0) or 0),
|
||||
**solar_return_location_kwargs(args),
|
||||
)
|
||||
|
||||
|
||||
@@ -8240,7 +8240,7 @@ class JyotishAPIHandler(BaseHTTPRequestHandler, VedastroEvidenceMixin, SynastryM
|
||||
lon,
|
||||
tz,
|
||||
target_year,
|
||||
ayanamsa_name=_request_ayanamsa(body),
|
||||
ayanamsa_name=_request_ayanamsa(body), birth_second=birth_dt.second,
|
||||
)
|
||||
return {'success': True, 'endpoint': 'annual', 'report': report}
|
||||
|
||||
|
||||
@@ -14671,7 +14671,8 @@ def _tajika_annual_core(args, planet_lons, asc_si, age, mode='all'):
|
||||
sr_cache['sr'] = calc_solar_return_chart(
|
||||
int(args.year), int(args.month), int(args.day), int(args.hour), int(args.minute),
|
||||
float(args.lat), float(args.lon), float(args.tz), int(args.year) + int(age),
|
||||
ayanamsa_name=sr_cache['ayanamsa'], **solar_return_location_kwargs(args),
|
||||
ayanamsa_name=sr_cache['ayanamsa'], birth_second=_arg_second(args),
|
||||
**solar_return_location_kwargs(args),
|
||||
)
|
||||
return sr_cache['sr']
|
||||
|
||||
@@ -16144,6 +16145,7 @@ def cmd_full_reading(args):
|
||||
args.lat, args.lon, args.tz,
|
||||
args.target_year,
|
||||
ayanamsa_name=_current_ayanamsa_name(args),
|
||||
birth_second=_arg_second(args),
|
||||
**_solar_return_location_kwargs(args),
|
||||
)
|
||||
report['modules']['solar_return'] = sr_result
|
||||
|
||||
@@ -314,6 +314,7 @@ def calc_solar_return_chart(
|
||||
return_lat: float | None = None,
|
||||
return_lon: float | None = None,
|
||||
return_tz: float | None = None,
|
||||
birth_second: int = 0,
|
||||
) -> Dict:
|
||||
"""
|
||||
计算太阳返照盘(Varshaphala)。
|
||||
@@ -358,7 +359,7 @@ def calc_solar_return_chart(
|
||||
'hint': '安装swisseph: pip install swisseph',
|
||||
'solar_return_approx': _find_solar_return_approx(
|
||||
_datetime_to_jd_ut(datetime(birth_year, birth_month, birth_day,
|
||||
birth_hour, birth_minute, 0)),
|
||||
birth_hour, birth_minute, birth_second)),
|
||||
0, # birth_sun_lon unknown
|
||||
target_year,
|
||||
annual_tz,
|
||||
@@ -372,6 +373,7 @@ def calc_solar_return_chart(
|
||||
birth_hour, birth_minute,
|
||||
birth_lat, birth_lon, birth_tz,
|
||||
'mean',
|
||||
second=birth_second,
|
||||
ayanamsa_name=ayanamsa_name,
|
||||
)
|
||||
if birth_chart is None:
|
||||
@@ -474,6 +476,7 @@ def solar_return_full_report(
|
||||
return_lat: float | None = None,
|
||||
return_lon: float | None = None,
|
||||
return_tz: float | None = None,
|
||||
birth_second: int = 0,
|
||||
) -> Dict:
|
||||
"""
|
||||
太阳返照盘完整报告(Varshaphala 年运分析)。
|
||||
@@ -503,6 +506,7 @@ def solar_return_full_report(
|
||||
ayanamsa_name=ayanamsa_name,
|
||||
local_timezone_id=local_timezone_id,
|
||||
return_lat=return_lat, return_lon=return_lon, return_tz=return_tz,
|
||||
birth_second=birth_second,
|
||||
)
|
||||
|
||||
if 'error' in sr:
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
"""Solar return keeps the birth second (BUG-1267).
|
||||
|
||||
The expected instant is the return computed from upstream 23be1807 for this
|
||||
fictional chart. Apparent-position fitting and the -5 second offset stay off.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from types import SimpleNamespace
|
||||
|
||||
from scripts.cmd_solar_return import cmd_solar_return
|
||||
from scripts.solar_return import calc_solar_return_chart
|
||||
|
||||
|
||||
FICTIONAL = dict(
|
||||
birth_year=1980, birth_month=6, birth_day=15,
|
||||
birth_hour=8, birth_minute=30,
|
||||
birth_lat=28.6, birth_lon=77.2, birth_tz=5.5,
|
||||
)
|
||||
CMD_ARGS = dict(year=1980, month=6, day=15, hour=8, minute=30, lat=28.6, lon=77.2, tz=5.5)
|
||||
TARGET_YEAR = 2010
|
||||
# Upstream 23be1807 calc_solar_return_chart for this fictional chart, second 40, Lahiri.
|
||||
UPSTREAM_RETURN_ISO = "2010-06-15 19:25:43"
|
||||
|
||||
|
||||
def test_birth_second_moves_the_return_instant() -> None:
|
||||
base = calc_solar_return_chart(**FICTIONAL, target_year=TARGET_YEAR, ayanamsa_name="lahiri", birth_second=0)
|
||||
shifted = calc_solar_return_chart(**FICTIONAL, target_year=TARGET_YEAR, ayanamsa_name="lahiri", birth_second=40)
|
||||
assert "error" not in base and "error" not in shifted
|
||||
assert base["solar_return"]["jd_ut"] != shifted["solar_return"]["jd_ut"]
|
||||
assert abs(shifted["solar_return"]["jd_ut"] - base["solar_return"]["jd_ut"]) > (20 / 86400)
|
||||
|
||||
|
||||
def test_cmd_solar_return_threads_the_second() -> None:
|
||||
direct = calc_solar_return_chart(**FICTIONAL, target_year=TARGET_YEAR, ayanamsa_name="lahiri", birth_second=40)
|
||||
via_cmd = cmd_solar_return(SimpleNamespace(**CMD_ARGS, second=40, target_year=TARGET_YEAR, ayanamsa="lahiri"))
|
||||
assert via_cmd["solar_return"]["jd_ut"] == direct["solar_return"]["jd_ut"]
|
||||
if UPSTREAM_RETURN_ISO is not None:
|
||||
assert str(via_cmd["solar_return"]["dt_ut"]) == UPSTREAM_RETURN_ISO
|
||||
Reference in New Issue
Block a user