公众授权版:normal · 1000 次 · 有效期至 2026-12-31
副本编号 LY-20261007-AC63(水印指纹已嵌入) 含 README、.gitignore;排除 .DS_Store / __pycache__ / .pytest_cache
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# -*- 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,
|
||||
}
|
||||
Reference in New Issue
Block a user