Files
ZiPingEightChar/tests/test_timezone.py
T
moxiaonian b20fd5c3c9 v3.6.2 同步发版:晚子时不再双重换日、港澳时区归位
- 晚子时(真太阳时 23:00–24:00,约 4% 的盘)修正:换日改由 tyme4py provider 原生实现(cast 新增 sect 参数,1=子初 / 2=子正),排盘层不再自行预滚日。3.6.1 及此前会滚两次,日柱多进一天、时柱随之错干——锚点 1973-08-23 23:32 男:旧 癸巳日壬子时 → 正 壬辰日庚子时。已排过的晚子时盘建议重排核对
- --day-boundary 子正 现真正生效(走 sect=2,晚子时日柱算当天),此前只改审计文案不改实际排盘
- data/cities.json 港澳 28 个条目由 Asia/Shanghai 改为 Asia/Hong_Kong(19)、Asia/Macau(9):大陆 1986–1991 行夏令时而港澳 1979 年后无,沿用上海区会把大陆夏令时错加到港澳命主身上
- 修副本环境 `pytest tests/` 收集期中断(test_sync_tool 模块级加载外层 tools/,skipif 挡不住导入),现按设计整模块 skip
- .gitignore 新增 data/.license.json、data/.update_check.json,本机授权与更新缓存不再可能误入仓
- 测试 178 项全绿(副本内 sync 工具 4 项按设计 skip);manifest 1278 文件,ed25519 签名,公钥指纹 3089bc1cc9a453e5…
2026-10-12 19:05:09 +08:00

86 lines
3.4 KiB
Python
Raw 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.
"""历史时区 / 夏令时黄金样本(设计文档 §4.3 / §6.1 C 组)。
逐条读 golden/history_tz.yaml,断言 to_utc 返回的 (utc, audit):
- tz_used / is_dst / dst_offset_min / source:audit 字段逐项相等
- utc_offset_min:钟表时间 − UTC(分钟),验证 UTC 解算本身
"""
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.timezone_resolve import to_utc # noqa: E402
from geo.cities import resolve_location # noqa: E402
AUDIT_KEYS = ("tz_used", "is_dst", "dst_offset_min", "source")
class HistoryTzGoldenTest(unittest.TestCase):
def test_history_tz_yaml(self):
with open(GOLDEN_DIR / "history_tz.yaml", encoding="utf-8") as f:
samples = yaml.safe_load(f)
self.assertGreaterEqual(len(samples), 4, "history_tz.yaml 应有 4 条样本")
for s in samples:
with self.subTest(sample=s["name"], place=s["place"]):
loc = resolve_location(s["place"])
clock = datetime.strptime(s["birth"], "%Y-%m-%d %H:%M")
utc, audit = to_utc(clock, loc)
expect = s["expect"]
for key in AUDIT_KEYS:
if key in expect:
self.assertEqual(
audit[key], expect[key], f"audit[{key!r}] 不符"
)
if "utc_offset_min" in expect:
offset_min = (
clock - utc.replace(tzinfo=None)
).total_seconds() / 60
self.assertAlmostEqual(
offset_min, expect["utc_offset_min"], delta=0.5,
msg=f"UTC 偏移 {offset_min} 分 ≠ 期望 "
f"{expect['utc_offset_min']} 分",
)
class HkMoDstTest(unittest.TestCase):
"""香港/澳门时区回归:1986–1991 中国大陆实行夏令时,港澳 1979 年后无;
cities.json 港澳条目必须为 Asia/Hong_Kong / Asia/Macau,不得随大陆拨快。"""
def test_hongkong_1987_no_dst(self):
loc = resolve_location("香港")
_utc, audit = to_utc(datetime(1987, 7, 5, 5, 0), loc)
self.assertEqual(loc.tz, "Asia/Hong_Kong")
self.assertIs(audit["is_dst"], False)
def test_macau_1987_no_dst(self):
loc = resolve_location("澳门")
_utc, audit = to_utc(datetime(1987, 7, 5, 5, 0), loc)
self.assertEqual(loc.tz, "Asia/Macau")
self.assertIs(audit["is_dst"], False)
def test_mainland_1987_dst_kept(self):
# 回归保护:大陆 1987 年夏令时仍应拨快
loc = resolve_location("北京")
_utc, audit = to_utc(datetime(1987, 7, 5, 5, 0), loc)
self.assertIs(audit["is_dst"], True)
def test_hongkong_1970_historical_dst(self):
# 香港 1949 后的历史夏令时(如 1970 年)应被 IANA 库正确处理
# (1949 前走民国五时区历史表分支,不在此断言范围)
loc = resolve_location("香港")
_utc, audit = to_utc(datetime(1970, 7, 15, 12, 0), loc)
self.assertEqual(audit["tz_used"], "Asia/Hong_Kong")
self.assertIs(audit["is_dst"], True)
if __name__ == "__main__":
unittest.main()