Spaces:
Running
Running
| 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: | |
| 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 | |
| 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 | |
| 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 | |
| } | |
| 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) | |