fix(ondemand): beyond_next_return compares on one time basis (#175 round 2, BUG-1818)

打回:Mudda 原始段是返照地点的本地时刻,覆盖区间终点却拿 utc 去比,差一个时区偏移。

- 比较两边都改用 coverage.end.local(没有 local 时退回 utc + 返照地点偏移)
- 新增 4 条测试(北京 +08 与纽约 −05 各 ±3 小时);旧代码上 2 条失败
- 未改 scripts/solar_return.py 或任何冻结文件;既有 16 条未动

Tests: 本文件 20 条,连同 transit_window/transit_date/contract/api growth 共 70 条全过。

Co-Authored-By: Grok (agent loop)
This commit is contained in:
jesse-ux
2026-11-09 17:47:07 +08:00
co-authored by Grok (agent loop)
parent 4651a7a486
commit b8a56c48ed
4 changed files with 77 additions and 3 deletions
+10 -2
View File
@@ -14,7 +14,7 @@
from __future__ import annotations
import sys
from datetime import datetime
from datetime import datetime, timedelta
from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple
@@ -250,7 +250,15 @@ def run(body: Dict[str, Any]) -> Dict[str, Any]:
elif abs(float(dasha_year['days']) - NOMINAL_YEAR_DAYS) > 1e-9:
gaps.append({'field': 'nominal_year', 'reason': 'dasha_year_days_not_365_25'})
coverage_end = _parse_moment((coverage_interval.get('end') or {}).get('utc'))
# 原值:用 coverage.end 的 utc 去比(mudda 段是返照地点的本地时刻,两边差一个时区偏移)
# 新值:两边都用本地时刻(coverage.end.local 与 raw_periods 同一地点、同一时区)
# 原因:验收退回(BUG-1818):beyond_next_return 的时区基准必须一致
coverage_end = _parse_moment((coverage_interval.get('end') or {}).get('local'))
if coverage_end is None:
# 没有 local 时才退回 utc + 返照地点偏移,仍在同一基准上比较。
coverage_end_utc = _parse_moment((coverage_interval.get('end') or {}).get('utc'))
if coverage_end_utc is not None:
coverage_end = coverage_end_utc + timedelta(hours=float(profile['tz']))
raw_periods: List[Dict[str, Any]] = []
for item in (mudda.get('raw_periods') or []):
if not isinstance(item, dict):