公众授权版:normal · 1000 次 · 有效期至 2026-12-31
副本编号 LY-20261007-AC63(水印指纹已嵌入) 含 README、.gitignore;排除 .DS_Store / __pycache__ / .pytest_cache
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
"""真太阳时经度修正黄金样本(设计文档 §4.4 / §6.1)。
|
||||
|
||||
数据来源:
|
||||
- golden/longitudes.yaml —— 不同经度城市逐条断言 lon_correction_min
|
||||
- golden/time_boundary.yaml —— 其中带 expect.lon_correction_min 的 A 组样本
|
||||
"""
|
||||
import sys
|
||||
import unittest
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
SKILL_ROOT = Path(__file__).resolve().parents[1]
|
||||
SCRIPTS_DIR = SKILL_ROOT / "scripts"
|
||||
GOLDEN_DIR = Path(__file__).resolve().parent / "golden"
|
||||
if str(SCRIPTS_DIR) not in sys.path:
|
||||
sys.path.insert(0, str(SCRIPTS_DIR))
|
||||
|
||||
from astro.solar_time import to_true_solar_time # noqa: E402
|
||||
from astro.timezone_resolve import to_utc # noqa: E402
|
||||
from geo.cities import resolve_location # noqa: E402
|
||||
|
||||
|
||||
def load_golden(name):
|
||||
with open(GOLDEN_DIR / name, encoding="utf-8") as f:
|
||||
return yaml.safe_load(f)
|
||||
|
||||
|
||||
def true_solar_chain(place, birth):
|
||||
"""数据流 L0-a ~ L0-d:地名 + 钟表时间 → (真太阳时, solar_audit, loc)。"""
|
||||
loc = resolve_location(place)
|
||||
clock = datetime.strptime(birth, "%Y-%m-%d %H:%M")
|
||||
utc, _tz_audit = to_utc(clock, loc)
|
||||
tst, st_audit = to_true_solar_time(utc, loc.lon)
|
||||
return tst, st_audit, loc
|
||||
|
||||
|
||||
class LongitudeCorrectionGoldenTest(unittest.TestCase):
|
||||
def test_longitudes_yaml(self):
|
||||
samples = load_golden("longitudes.yaml")
|
||||
self.assertGreaterEqual(len(samples), 5, "longitudes.yaml 至少需要 5 组样本")
|
||||
for s in samples:
|
||||
with self.subTest(sample=s["name"], place=s["place"]):
|
||||
_tst, audit, loc = true_solar_chain(s["place"], s["birth"])
|
||||
# 城市表经度 sanity check(0.1° 级即够,见文档 §4.1)
|
||||
self.assertAlmostEqual(loc.lon, s["lon"], delta=0.1)
|
||||
self.assertAlmostEqual(
|
||||
audit["lon_correction_min"],
|
||||
s["expect_lon_correction_min"],
|
||||
delta=s["tolerance"],
|
||||
)
|
||||
|
||||
|
||||
class TimeBoundaryGoldenTest(unittest.TestCase):
|
||||
"""文档 §6.1 A 组:乌鲁木齐 / 成都 / 上海。"""
|
||||
|
||||
def test_time_boundary_yaml(self):
|
||||
samples = [
|
||||
s for s in load_golden("time_boundary.yaml")
|
||||
if "lon_correction_min" in s.get("expect", {})
|
||||
]
|
||||
self.assertGreaterEqual(len(samples), 3, "time_boundary.yaml A 组应有 3 条样本")
|
||||
for s in samples:
|
||||
with self.subTest(sample=s["name"], place=s["place"]):
|
||||
tst, audit, _loc = true_solar_chain(s["place"], s["birth"])
|
||||
self.assertAlmostEqual(
|
||||
audit["lon_correction_min"],
|
||||
s["expect"]["lon_correction_min"],
|
||||
delta=s["tolerance"],
|
||||
)
|
||||
if "true_solar_time" in s["expect"]:
|
||||
want = datetime.strptime(
|
||||
s["expect"]["true_solar_time"], "%Y-%m-%d %H:%M"
|
||||
)
|
||||
tol_min = s["expect"].get("true_solar_time_tolerance_min", 3)
|
||||
self.assertLessEqual(
|
||||
abs((tst - want).total_seconds()),
|
||||
tol_min * 60,
|
||||
f"真太阳时 {tst} 与期望 {want} 差距超过 {tol_min} 分钟",
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user