import sys import os import datetime # Add the bundled pyLunarCalendar path to sys.path project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) lunar_path = os.path.join(project_root, 'pyLunarCalendar') if lunar_path not in sys.path and os.path.exists(lunar_path): sys.path.append(lunar_path) import lunar from settings import Config import math class LunarEngine: @staticmethod def get_equation_of_time(dt): """ 计算均时差 (Equation of Time) - 分钟 基于泰勒级数近似 """ day_of_year = dt.timetuple().tm_yday b = 2 * math.pi * (day_of_year - 1) / 365 eot = 229.18 * (0.000075 + 0.001868 * math.cos(b) - 0.032077 * math.sin(b) - 0.014615 * math.cos(2*b) - 0.040849 * math.sin(2*b)) return eot @staticmethod def get_true_solar_time(dt, longitude=Config.DEFAULT_LONGITUDE): """ 根据经度转换真太阳时 北京时间(UTC+8)基于120度经线 """ # 1. 经度差修正 (1度 = 4分钟) long_diff = longitude - 120.0 time_diff = long_diff * 4 # 2. 均时差修正 eot = LunarEngine.get_equation_of_time(dt) # 最终修正量 (分钟) total_correction = time_diff + eot tst = dt + datetime.timedelta(minutes=total_correction) return tst @staticmethod def get_lunar_info(dt=None, longitude=Config.DEFAULT_LONGITUDE): if dt is None: dt = datetime.datetime.now() # 获取真太阳时 tst = LunarEngine.get_true_solar_time(dt, longitude) l = lunar.Lunar(tst) # 提取详细信息 return { "date": dt.strftime("%Y-%m-%d %H:%M:%S"), "tst": tst.strftime("%Y-%m-%d %H:%M:%S"), "location": Config.DEFAULT_LOCATION, "lunar_date": f"{l.lunarYearCn} {l.lunarMonthCn} {l.lunarDayCn}", "lunar_num": f"{l.lunarYear}-{l.lunarMonth}-{l.lunarDay}", "lunar_month_num": l.lunarMonth, "lunar_day_num": l.lunarDay, "week": l.weekDayCn, "bazi": f"{l.year8Char} {l.month8Char} {l.day8Char} {l.twohour8Char}", "solar_term": l.todaySolarTerms, "next_term": f"{l.nextSolarTerm} ({l.nextSolarTermDate[0]}-{l.nextSolarTermDate[1]})", "season": l.lunarSeason, "zodiac": l.chineseYearZodiac, "clash": l.chineseZodiacClash, "nayin": l.get_nayin(), "star28": l.today28Star, "officer12": l.today12DayOfficer, "god_day": l.today12DayGod, "constellation": l.starZodiac, "good_gods": l.goodGodName, "bad_gods": l.badGodName, "lucky_direction": l.get_luckyGodsDirection(), "fetal_god": l.get_fetal_god() if hasattr(l, 'get_fetal_god') else l.get_fetalGod(), "peng_taboo": l.get_pengTaboo(), "suitable": l.goodThing, "unsuitable": l.badThing, "elements": l.get_today5Elements(), "meridians": l.meridians, "phase": l.phaseOfMoon } @staticmethod def get_lunar_by_date(year, month, day, hour=0, minute=0): dt = datetime.datetime(year, month, day, hour, minute) return LunarEngine.get_lunar_info(dt)