Files
ZiPingEightChar/scripts/chart/tyme_adapter.py
T
moxiaonian d9da4301cd 公众授权版:normal · 1000 次 · 有效期至 2026-12-31
副本编号 LY-20261007-AC63(水印指纹已嵌入)
含 README、.gitignore;排除 .DS_Store / __pycache__ / .pytest_cache
2026-10-07 17:29:52 +08:00

82 lines
3.3 KiB
Python

# -*- coding: utf-8 -*-
"""tyme4py 唯一接触面:输入真太阳时时刻,返回四柱及派生信息(纯计算,无命理判断)。"""
from datetime import datetime
import tyme4py
from tyme4py.solar import SolarTime, SolarTerm
LIBRARY_VERSION = tyme4py.__version__
_PILLARS = ("year", "month", "day", "hour")
def _solar_time_to_dt(t: SolarTime) -> datetime:
return datetime(t.get_year(), t.get_month(), t.get_day(),
t.get_hour(), t.get_minute(), t.get_second())
def _jie_bounds(cast_dt: datetime) -> tuple:
"""出生时刻前后最近的两个节令(is_jie()),以出生年为中心 ±1 年遍历。"""
prev_jie = next_jie = None
for y in (cast_dt.year - 1, cast_dt.year, cast_dt.year + 1):
for i in range(24):
term = SolarTerm.from_index(y, i)
if not term.is_jie():
continue
t = _solar_time_to_dt(term.get_julian_day().get_solar_time())
if t < cast_dt and (prev_jie is None or t > prev_jie[1]):
prev_jie = (term, t)
elif t > cast_dt and (next_jie is None or t < next_jie[1]):
next_jie = (term, t)
return prev_jie, next_jie
def _hidden(me, earth_branch) -> list:
items = []
for getter in ("get_hide_heaven_stem_main",
"get_hide_heaven_stem_middle",
"get_hide_heaven_stem_residual"):
hs = getattr(earth_branch, getter)()
if hs is not None:
items.append([hs.get_name(), me.get_ten_star(hs).get_name()])
return items
def _shen_sha(solar: SolarTime) -> list:
try:
return [g.get_name() for g in solar.get_lunar_hour().get_lunar_day().get_gods()]
except Exception:
return []
def cast(cast_dt: datetime, gender: str) -> dict:
"""cast_dt:已完成子初换日调整的真太阳时(naive,北京时间语义)。"""
solar = SolarTime.from_ymd_hms(cast_dt.year, cast_dt.month, cast_dt.day,
cast_dt.hour, cast_dt.minute, cast_dt.second)
ec = solar.get_lunar_hour().get_eight_char()
pillars = {k: getattr(ec, f"get_{k}")() for k in _PILLARS}
me = ec.get_day().get_heaven_stem()
prev_jie, next_jie = _jie_bounds(cast_dt)
return {
**{k: {"gan": p.get_heaven_stem().get_name(),
"zhi": p.get_earth_branch().get_name()} for k, p in pillars.items()},
"day_master": me.get_name(),
"ten_god": {k: me.get_ten_star(pillars[k].get_heaven_stem()).get_name()
for k in ("year", "month", "hour")},
"hidden": {k: _hidden(me, pillars[k].get_earth_branch()) for k in _PILLARS},
"terrain": {k: me.get_terrain(pillars[k].get_earth_branch()).get_name()
for k in _PILLARS},
"na_yin": {k: pillars[k].get_sound().get_name() for k in _PILLARS},
"void": {k: "".join(b.get_name() for b in pillars[k].get_extra_earth_branches())
for k in ("day", "hour")},
"shen_sha": _shen_sha(solar),
"prev_jie": {"name": prev_jie[0].get_name(), "time": prev_jie[1]},
"next_jie": {"name": next_jie[0].get_name(), "time": next_jie[1]},
"tai_yuan": ec.get_fetal_origin().get_name(),
"ming_gong": ec.get_own_sign().get_name(),
"library_version": LIBRARY_VERSION,
"raw": ec,
}