File size: 3,505 Bytes
e4efb8a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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)