python语言卦气正元历 · 丙午定本 · 完整版代码QMQXQZQ
·
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
卦气正元历 · 丙午定本 · 完整内容紧凑版
方案B(太阳黄经驱动)· Python + Tkinter
零外部依赖 · 内置1900-2100年天文数据 · 全部卦辞详解
"""
import tkinter as tk
from tkinter import ttk, font, messagebox, simpledialog
from datetime import datetime, timedelta
from math import sin, cos, radians, pi
import json
import os
# ==================== 内置天文数据库 ====================
LICHUN_DATABASE = {
1900: (2, 4, 20, 39), 1901: (2, 4, 2, 30), 1902: (2, 4, 8, 17), 1903: (2, 4, 14, 5),
1904: (2, 4, 19, 53), 1905: (2, 4, 1, 46), 1906: (2, 4, 7, 34), 1907: (2, 4, 13, 21),
1908: (2, 4, 19, 15), 1909: (2, 4, 1, 6), 1910: (2, 4, 6, 54), 1911: (2, 4, 12, 42),
1912: (2, 4, 18, 31), 1913: (2, 4, 0, 24), 1914: (2, 4, 6, 12), 1915: (2, 4, 12, 0),
1916: (2, 4, 17, 49), 1917: (2, 4, 23, 39), 1918: (2, 4, 5, 27), 1919: (2, 4, 11, 15),
1920: (2, 4, 17, 8), 1921: (2, 4, 23, 0), 1922: (2, 4, 4, 49), 1923: (2, 4, 10, 37),
1924: (2, 4, 16, 30), 1925: (2, 4, 22, 22), 1926: (2, 4, 4, 11), 1927: (2, 4, 9, 59),
1928: (2, 4, 15, 52), 1929: (2, 4, 21, 44), 1930: (2, 4, 3, 33), 1931: (2, 4, 9, 21),
1932: (2, 4, 15, 14), 1933: (2, 4, 21, 6), 1934: (2, 4, 2, 55), 1935: (2, 4, 8, 43),
1936: (2, 4, 14, 36), 1937: (2, 4, 20, 28), 1938: (2, 4, 2, 17), 1939: (2, 4, 8, 5),
1940: (2, 4, 13, 58), 1941: (2, 4, 19, 50), 1942: (2, 4, 1, 39), 1943: (2, 4, 7, 27),
1944: (2, 4, 13, 20), 1945: (2, 4, 19, 12), 1946: (2, 4, 1, 1), 1947: (2, 4, 6, 49),
1948: (2, 4, 12, 42), 1949: (2, 4, 18, 34), 1950: (2, 4, 0, 23), 1951: (2, 4, 6, 11),
1952: (2, 4, 12, 4), 1953: (2, 4, 17, 56), 1954: (2, 4, 23, 45), 1955: (2, 4, 5, 33),
1956: (2, 4, 11, 26), 1957: (2, 4, 17, 18), 1958: (2, 4, 23, 7), 1959: (2, 4, 4, 55),
1960: (2, 4, 10, 48), 1961: (2, 4, 16, 40), 1962: (2, 4, 22, 29), 1963: (2, 4, 4, 17),
1964: (2, 4, 10, 10), 1965: (2, 4, 16, 2), 1966: (2, 4, 21, 51), 1967: (2, 4, 3, 39),
1968: (2, 4, 9, 32), 1969: (2, 4, 15, 24), 1970: (2, 4, 21, 13), 1971: (2, 4, 3, 1),
1972: (2, 4, 8, 54), 1973: (2, 4, 14, 46), 1974: (2, 4, 20, 35), 1975: (2, 4, 2, 23),
1976: (2, 4, 8, 16), 1977: (2, 4, 14, 8), 1978: (2, 4, 19, 57), 1979: (2, 4, 1, 45),
1980: (2, 4, 7, 38), 1981: (2, 4, 13, 30), 1982: (2, 4, 19, 19), 1983: (2, 4, 1, 7),
1984: (2, 4, 7, 0), 1985: (2, 4, 12, 52), 1986: (2, 4, 18, 41), 1987: (2, 4, 0, 29),
1988: (2, 4, 6, 22), 1989: (2, 4, 12, 14), 1990: (2, 4, 18, 3), 1991: (2, 4, 23, 51),
1992: (2, 4, 5, 44), 1993: (2, 4, 11, 36), 1994: (2, 4, 17, 25), 1995: (2, 4, 23, 13),
1996: (2, 4, 5, 6), 1997: (2, 4, 10, 58), 1998: (2, 4, 16, 47), 1999: (2, 4, 22, 35),
2000: (2, 4, 4, 28), 2001: (2, 4, 10, 20), 2002: (2, 4, 16, 9), 2003: (2, 4, 21, 57),
2004: (2, 4, 3, 50), 2005: (2, 4, 9, 42), 2006: (2, 4, 15, 31), 2007: (2, 4, 21, 19),
2008: (2, 4, 3, 12), 2009: (2, 4, 9, 4), 2010: (2, 4, 14, 53), 2011: (2, 4, 20, 41),
2012: (2, 4, 2, 34), 2013: (2, 4, 8, 26), 2014: (2, 4, 14, 15), 2015: (2, 4, 20, 3),
2016: (2, 4, 1, 56), 2017: (2, 4, 7, 48), 2018: (2, 4, 13, 37), 2019: (2, 4, 19, 25),
2020: (2, 4, 1, 18), 2021: (2, 3, 22, 59), 2022: (2, 4, 4, 51), 2023: (2, 4, 10, 43),
2024: (2, 4, 16, 27), 2025: (2, 3, 22, 10), 2026: (2, 4, 4, 2), 2027: (2, 4, 9, 46),
2028: (2, 4, 15, 30), 2029: (2, 3, 21, 20), 2030: (2, 4, 3, 8), 2031: (2, 4, 8, 57),
2032: (2, 4, 14, 49), 2033: (2, 3, 20, 33), 2034: (2, 4, 2, 24), 2035: (2, 4, 8, 13),
2036: (2, 4, 14, 6), 2037: (2, 3, 19, 52), 2038: (2, 4, 1, 41), 2039: (2, 4, 7, 30),
2040: (2, 4, 13, 23), 2041: (2, 3, 19, 7), 2042: (2, 4, 0, 59), 2043: (2, 4, 6, 48),
2044: (2, 4, 12, 43), 2045: (2, 3, 18, 25), 2046: (2, 4, 0, 16), 2047: (2, 4, 6, 5),
2048: (2, 4, 12, 0), 2049: (2, 3, 17, 44), 2050: (2, 3, 23, 35), 2051: (2, 4, 5, 24),
2052: (2, 4, 11, 19), 2053: (2, 3, 17, 0), 2054: (2, 3, 22, 52), 2055: (2, 4, 4, 41),
2056: (2, 4, 10, 38), 2057: (2, 3, 16, 17), 2058: (2, 3, 22, 9), 2059: (2, 4, 3, 58),
2060: (2, 4, 9, 53), 2061: (2, 3, 15, 31), 2062: (2, 3, 21, 23), 2063: (2, 4, 3, 12),
2064: (2, 4, 9, 9), 2065: (2, 3, 14, 46), 2066: (2, 3, 20, 38), 2067: (2, 4, 2, 27),
2068: (2, 4, 8, 24), 2069: (2, 3, 14, 0), 2070: (2, 3, 19, 52), 2071: (2, 4, 1, 41),
2072: (2, 4, 7, 39), 2073: (2, 3, 13, 15), 2074: (2, 3, 19, 7), 2075: (2, 4, 0, 56),
2076: (2, 4, 6, 54), 2077: (2, 3, 12, 28), 2078: (2, 3, 18, 20), 2079: (2, 4, 0, 9),
2080: (2, 4, 6, 9), 2081: (2, 3, 11, 41), 2082: (2, 3, 17, 33), 2083: (2, 3, 23, 22),
2084: (2, 4, 5, 22), 2085: (2, 3, 10, 53), 2086: (2, 3, 16, 45), 2087: (2, 3, 22, 34),
2088: (2, 4, 4, 36), 2089: (2, 3, 10, 5), 2090: (2, 3, 15, 57), 2091: (2, 3, 21, 46),
2092: (2, 4, 3, 48), 2093: (2, 3, 9, 17), 2094: (2, 3, 15, 9), 2095: (2, 3, 20, 58),
2096: (2, 4, 3, 0), 2097: (2, 3, 8, 29), 2098: (2, 3, 14, 21), 2099: (2, 3, 20, 10),
2100: (2, 4, 2, 12),
}
# ==================== 核心数据 ====================
GUA_SEQUENCE = [
"坎", "蹇", "屯", "井", "既济", "比", "节", "需",
"艮", "颐", "蛊", "贲", "剥", "损", "大畜", "蒙",
"震", "恒", "丰", "豫", "归妹", "大壮", "解", "小过",
"巽", "家人", "观", "中孚", "小畜", "涣", "渐", "益",
"离", "晋", "睽", "大有", "未济", "旅", "噬嗑", "鼎",
"坤", "临", "泰", "师", "谦", "复", "升", "明夷",
"兑", "夬", "困", "咸", "随", "大过", "革", "萃",
"乾", "讼", "遁", "无妄", "姤", "同人", "否", "履"
]
BA_GUA = ["坎", "艮", "震", "巽", "离", "坤", "兑", "乾"]
# ==================== 新增:无极·太极·寒暑·四季理论体系 ====================
# 宇宙生成论(用于显示)
WUJI_TITLE = "无极——万化之源"
WUJI_DESC = """无极者,先天虚寂,混沌无象,无形无质,无始无终。
阴阳未萌,动静未兆,为太极之母、天地之根、岁时之源。
无极寂,则天地未分;无极动,则太极立生。"""
TAIJI_TITLE = "太极——岁序之根"
TAIJI_DESC = """太极者,由无极而生,阴阳初判、混沌将分,为天地万物之始,亦为一年时序之原。
太极不动,岁时不生;太极一动,阴阳分判,寒暑乃成。
太极统御全年寒暑消长,统领四季更迭,统摄八节枢纽,统贯六十四卦气流转。"""
HANSHU_TITLE = "寒暑——一岁之纲"
HANSHU_DESC = """寒暑相推,是为一年之核心节律:
• 暑为阳之极用,主长、主明、主散,起于立春,盛于夏至,消于立秋
• 寒为阴之极用,主藏、主幽、主聚,起于立秋,盛于冬至,消于立春
寒暑交替,无有间断,乃生四季,乃定八节。"""
# 四季对应表(四象)
SEASONS = [
{"name": "春", "sixiang": "少阳", "angle": 90, "range": "春分前后3气", "desc": "阳长阴消,主生"},
{"name": "夏", "sixiang": "老阳", "angle": 180, "range": "夏至前后3气", "desc": "阳极阴萌,主长"},
{"name": "秋", "sixiang": "少阴", "angle": 270, "range": "秋分前后3气", "desc": "阴长阳消,主收"},
{"name": "冬", "sixiang": "老阴", "angle": 0, "range": "冬至前后3气", "desc": "阴极阳萌,主藏"}
]
# 八节对应八卦(完整版)
JIE_NAMES = ["立春", "春分", "立夏", "夏至", "立秋", "秋分", "立冬", "冬至"]
JIE_GUA_LIST = ["艮", "震", "巽", "离", "坤", "兑", "乾", "坎"]
JIE_ANGLES = [45, 90, 135, 180, 225, 270, 315, 0] # 天环中点角度
JIE_FANGWEI = ["东北", "正东", "东南", "正南", "西南", "正西", "西北", "正北"]
JIE_QIXIANG = ["阳动初启", "阴阳平衡", "阳盛渐布", "阳极阴萌", "阴生初敛", "阴阳平衡", "阴盛潜阳", "阴极阳萌"]
# 八节统摄范围(每节统摄8气)
JIE_RANGES = [
(1, 8, "坎气至需气"), # 立春
(9, 16, "艮气至蒙气"), # 春分
(17, 24, "震气至小过气"), # 立夏
(25, 32, "巽气至益气"), # 夏至
(33, 40, "离气至鼎气"), # 立秋
(41, 48, "坤气至明夷气"), # 秋分
(49, 56, "兑气至萃气"), # 立冬
(57, 64, "乾气至履气") # 冬至
]
# 八节到八卦的映射字典
JIE_TO_GUA = dict(zip(JIE_NAMES, JIE_GUA_LIST))
# ==================== 八刻与四时对应(一日系统)====================
# 四时(一日之四象)
DAY_SISHI = [
{"name": "朝", "sixiang": "少阳", "time_range": "03:00-09:00", "desc": "阳始生"},
{"name": "昼", "sixiang": "老阳", "time_range": "09:00-15:00", "desc": "阳极盛"},
{"name": "夕", "sixiang": "少阴", "time_range": "15:00-21:00", "desc": "阴始生"},
{"name": "夜", "sixiang": "老阴", "time_range": "21:00-03:00", "desc": "阴极盛"}
]
# 八刻详细对应(地支·八卦·方位·时间·天文释义)
KE_DETAILS = [
{"di": "子", "gua": "坎", "fangwei": "正北", "mid": "00:00", "range": "23:00-01:00",
"desc": "子夜寒冷,太阳隐于地球另一侧,对应天球正北"},
{"di": "丑", "gua": "艮", "fangwei": "东北", "mid": "03:00", "range": "02:00-04:00",
"desc": "三更半夜,太阳隐于东北方地下"},
{"di": "卯", "gua": "震", "fangwei": "正东", "mid": "06:00", "range": "05:00-07:00",
"desc": "日出东方,太阳在东方"},
{"di": "辰", "gua": "巽", "fangwei": "东南", "mid": "09:00", "range": "08:00-10:00",
"desc": "早晨升日,太阳在东南方"},
{"di": "午", "gua": "离", "fangwei": "正南", "mid": "12:00", "range": "11:00-13:00",
"desc": "日午炎热,太阳在南方"},
{"di": "未", "gua": "坤", "fangwei": "西南", "mid": "15:00", "range": "14:00-16:00",
"desc": "日晒减弱,太阳在西南方"},
{"di": "酉", "gua": "兑", "fangwei": "正西", "mid": "18:00", "range": "17:00-19:00",
"desc": "太阳下山,太阳在西方"},
{"di": "戌", "gua": "乾", "fangwei": "西北", "mid": "21:00", "range": "20:00-22:00",
"desc": "温暖降温,太阳在西北方"}
]
KE_NAMES = [f"{k['di']}-{k['gua']}" for k in KE_DETAILS]
WUXING = {"坎": "水", "艮": "土", "震": "木", "巽": "木", "离": "火", "坤": "土", "兑": "金", "乾": "金"}
# ==================== 六十四度时间边界表(一日系统)====================
# 生成规则:每度22.5分钟 = 22分30秒
DEGREE_TIMES = []
for i in range(64):
start_minutes = i * 22.5
end_minutes = (i + 1) * 22.5
start_h = int(start_minutes // 60)
start_m = int(start_minutes % 60)
start_s = int((start_minutes % 1) * 60)
end_h = int(end_minutes // 60) % 24
end_m = int(end_minutes % 60)
end_s = int((end_minutes % 1) * 60)
DEGREE_TIMES.append({
"num": i + 1,
"gua": GUA_SEQUENCE[i],
"start": f"{start_h:02d}:{start_m:02d}:{start_s:02d}",
"end": f"{end_h:02d}:{end_m:02d}:{end_s:02d}"
})
# ==================== 六十四气天文特征表(岁序系统)====================
# 以2026年为例的天文特征(可根据年份动态计算,这里提供静态模板)
QI_ASTRONOMY_TEMPLATE = [
# 立春组 (1-8)
{"num": 1, "gua": "坎", "jie": "立春", "start": "02-03 22:09", "end": "02-09 15:06",
"sun_range": "315°~320°", "feature": "阳气始动,但寒气仍盛", "climate": "冬末春初,乍暖还寒", "solar_term": "立春后→雨水前"},
{"num": 2, "gua": "蹇", "jie": "立春", "start": "02-09 15:06", "end": "02-15 08:04",
"sun_range": "320°~325°", "feature": "阳气渐升,阴气渐退", "climate": "冰雪始融,地气渐通", "solar_term": "立春末期→雨水前期"},
{"num": 3, "gua": "屯", "jie": "立春", "start": "02-15 08:04", "end": "02-21 01:02",
"sun_range": "325°~330°", "feature": "雨水将至,草木萌动", "climate": "降水渐增,万物始生", "solar_term": "雨水(02-18)"},
{"num": 4, "gua": "井", "jie": "立春", "start": "02-21 01:02", "end": "02-26 17:59",
"sun_range": "330°~335°", "feature": "雨水渐盛,地气升腾", "climate": "春雨如丝,润物无声", "solar_term": "雨水末期→惊蛰前期"},
{"num": 5, "gua": "既济", "jie": "立春", "start": "02-26 17:59", "end": "03-04 10:57",
"sun_range": "335°~340°", "feature": "惊蛰将至,雷始动", "climate": "冬眠将醒,虫动于土", "solar_term": "惊蛰前"},
{"num": 6, "gua": "比", "jie": "立春", "start": "03-04 10:57", "end": "03-10 03:55",
"sun_range": "340°~345°", "feature": "惊蛰,雷动万物", "climate": "春雷始鸣,蛰虫惊走", "solar_term": "惊蛰(03-05)"},
{"num": 7, "gua": "节", "jie": "立春", "start": "03-10 03:55", "end": "03-15 20:52",
"sun_range": "345°~350°", "feature": "春分将至,昼夜渐平", "climate": "春意渐浓,阴阳渐衡", "solar_term": "惊蛰末期→春分前期"},
{"num": 8, "gua": "需", "jie": "立春", "start": "03-15 20:52", "end": "03-21 13:50",
"sun_range": "350°~355°", "feature": "春分,昼夜平分", "climate": "阴阳平衡,春色正中", "solar_term": "春分(03-20)"},
# 春分组 (9-16)
{"num": 9, "gua": "艮", "jie": "春分", "start": "03-21 13:50", "end": "03-27 06:48",
"sun_range": "355°~0°", "feature": "春分后,阳气渐盛", "climate": "春暖花开,万物生长", "solar_term": "春分末期→清明前期"},
{"num": 10, "gua": "颐", "jie": "春分", "start": "03-27 06:48", "end": "04-01 23:45",
"sun_range": "0°~5°", "feature": "清明将至,气清景明", "climate": "春和景明,万物洁净", "solar_term": "清明前"},
{"num": 11, "gua": "蛊", "jie": "春分", "start": "04-01 23:45", "end": "04-07 16:43",
"sun_range": "5°~10°", "feature": "清明,气清景明", "climate": "草木萌发,春耕正忙", "solar_term": "清明(04-04)"},
{"num": 12, "gua": "贲", "jie": "春分", "start": "04-07 16:43", "end": "04-13 09:41",
"sun_range": "10°~15°", "feature": "清明末期,谷雨将至", "climate": "春深似海,雨润如酥", "solar_term": "清明末期→谷雨前期"},
{"num": 13, "gua": "剥", "jie": "春分", "start": "04-13 09:41", "end": "04-19 02:38",
"sun_range": "15°~20°", "feature": "谷雨将至,雨生百谷", "climate": "春雨绵绵,谷类生长", "solar_term": "谷雨前"},
{"num": 14, "gua": "损", "jie": "春分", "start": "04-19 02:38", "end": "04-24 19:36",
"sun_range": "20°~25°", "feature": "谷雨,雨量渐增", "climate": "雨润百谷,春末夏初", "solar_term": "谷雨(04-20)"},
{"num": 15, "gua": "大畜", "jie": "春分", "start": "04-24 19:36", "end": "04-30 12:34",
"sun_range": "25°~30°", "feature": "谷雨末期,立夏将至", "climate": "春尽夏来,阳气渐旺", "solar_term": "谷雨末期→立夏前期"},
{"num": 16, "gua": "蒙", "jie": "春分", "start": "04-30 12:34", "end": "05-06 05:31",
"sun_range": "30°~35°", "feature": "立夏,夏之始", "climate": "夏意初萌,万物繁茂", "solar_term": "立夏(05-05)"},
# 后续可以继续补充完整...
]
# 为简化,只补充到16,实际使用时可以完整添加所有64气的天文特征
# 这里仅作为模板示例
# ==================== 完整卦义(一日系统)====================
GUA_DAILY_FULL = {
"坎": ("险中存正", "宜谨言慎行,稳渡难关",
"水洊至,习坎。君子以常德行,习教事。处险之时,当心怀诚信,行中正道,不可妄动。险中存正,方能履险如夷。"),
"蹇": ("前路阻滞", "宜停步待时,不强行冒进",
"山上有水,蹇。君子以反身修德。见险而能止,知矣哉!蹇之时用大矣哉。前路虽艰,反身修德,终能济蹇。"),
"屯": ("初萌未稳", "宜稳扎稳打,夯实基础",
"云雷,屯。君子以经纶。刚柔始交而难生,动乎险中。宜建侯而不宁。初生之物,宜慎始慎终。"),
"井": ("安定守恒", "宜守常安身,滋养自身",
"木上有水,井。君子以劳民劝相。改邑不改井,乃以刚中也。往来井井,无丧无得。井养而不穷也。"),
"既济": ("事已功成", "宜守成防骄,谨防后患",
"水在火上,既济。君子以思患而豫防之。初吉终乱,终止则乱,其道穷也。既济之时,戒骄戒躁,思患预防。"),
"比": ("阴气相和", "宜亲善协作,凝聚合力",
"地上有水,比。先王以建万国,亲诸侯。比吉也,比辅也,下顺从也。亲比之道,在于诚信,上下相应。"),
"节": ("节制有度", "宜守界不逾,不纵不弛",
"泽上有水,节。君子以制数度,议德行。节亨,刚柔分而刚得中。苦节不可贞,其道穷也。节而适中,方为正道。"),
"需": ("待时守中", "宜耐心等候,静待良机",
"云上于天,需。君子以饮食宴乐。需,须也,险在前也。刚健而不陷,其义不困穷矣。待时而动,不陷于险。"),
"艮": ("当止则止", "宜静守当下,不妄动妄为",
"兼山,艮。君子以思不出其位。时止则止,时行则行,动静不失其时,其道光明。知止而后有定,定而后能静。"),
"颐": ("养身养心", "宜静养蓄能,调理身心",
"山下有雷,颐。君子以慎言语,节饮食。颐养正也,养正则吉也。天地养万物,圣人养贤以及万民。"),
"蛊": ("微乱初现", "宜及时整饬,肃清隐患",
"山下有风,蛊。君子以振民育德。蛊,事也,有事而后可大,故受之以蛊。振蛊之道,在于育德新民。"),
"贲": ("文饰条理", "宜整理规范,完善细节",
"山下有火,贲。君子以明庶政,无敢折狱。贲亨,柔来而文刚,分刚上而文柔。文明以止,人文也。"),
"剥": ("阳气渐剥", "宜守弱藏锋,保全根本",
"山附于地,剥。上以厚下安宅。剥,剥也,柔变刚也。不利有攸往,小人长也。顺而止之,观象也。"),
"损": ("减损浮华", "宜去繁就简,聚焦核心",
"山下有泽,损。君子以惩忿窒欲。损,损下益上,其道上行。损而有孚,元吉,无咎,可贞,利有攸往。"),
"大畜": ("厚积蓄力", "宜深藏不露,蓄力待发",
"天在山中,大畜。君子以多识前言往行,以畜其德。大畜,刚健笃实辉光,日新其德。不家食吉,养贤也。"),
"蒙": ("蒙昧初开", "宜虚心求教,启智明理",
"山下出泉,蒙。君子以果行育德。蒙亨,以亨行时中也。匪我求童蒙,童蒙求我,志应也。蒙以养正,圣功也。"),
"震": ("警醒而动", "宜振作精神,积极应变",
"洊雷,震。君子以恐惧修省。震来虩虩,恐致福也。笑言哑哑,后有则也。震惊百里,不丧匕鬯,出可以守宗庙社稷。"),
"恒": ("守常不变", "宜坚持初心,始终如一",
"雷风,恒。君子以立不易方。恒,久也。刚上而柔下,雷风相与,巽而动,刚柔皆应,恒。恒亨,无咎,利贞,久于其道也。"),
"丰": ("气盛丰满", "宜戒骄戒躁,稳守成果",
"雷电皆至,丰。君子以折狱致刑。丰,大也。明以动,故丰。王假之,尚大也。勿忧,宜日中。日中则昃,月盈则食。"),
"豫": ("顺时安逸", "宜调养生息,舒展身心",
"雷出地奋,豫。先王以作乐崇德,殷荐之上帝,以配祖考。豫,顺以动,故天地如之,而况建侯行师乎?"),
"归妹": ("归根守静", "宜收敛归心,回归本真",
"泽上有雷,归妹。君子以永终知敝。归妹,天地之大义也。天地不交而万物不兴。归妹,人之终始也。说以动,所归妹也。"),
"大壮": ("气旺势强", "宜慎行不躁,稳中求进",
"雷在天上,大壮。君子以非礼弗履。大壮,大者壮也。刚以动,故壮。大壮利贞,大者正也。正大而天地之情可见矣。"),
"解": ("滞碍消散", "宜舒缓解压,顺势而为",
"雷雨作,解。君子以赦过宥罪。解,险以动,动而免乎险,解。解利西南,往得众也。其来复吉,乃得中也。"),
"小过": ("小错可容", "宜及时修正,不钻牛角",
"山上有雷,小过。君子以行过乎恭,丧过乎哀,用过乎俭。小过,小者过而亨也。过以利贞,与时行也。柔得中,是以小事吉也。"),
"巽": ("谦逊柔顺", "宜顺势借力,委婉成事",
"随风,巽。君子以申命行事。重巽以申命,刚巽乎中正而志行。柔皆顺乎刚,是以小亨,利有攸往,利见大人。"),
"家人": ("内守安定", "宜和睦安稳,稳固根基",
"风自火出,家人。君子以言有物而行有恒。家人,女正位乎内,男正位乎外,男女正,天地之大义也。家有严君焉,父母之谓也。"),
"观": ("静观其变", "宜察势明辨,不妄下决断",
"风行地上,观。先王以省方观民设教。盥而不荐,有孚颙若,下观而化也。观天之神道,而四时不忒。圣人以神道设教,而天下服矣。"),
"中孚": ("诚信守中", "宜定心笃行,坚守信义",
"泽上有风,中孚。君子以议狱缓死。中孚,柔在内而刚得中,说而巽,孚乃化邦也。豚鱼吉,信及豚鱼也。利涉大川,乘木舟虚也。"),
"小畜": ("微积小成", "宜积少成多,稳步积累",
"风行天上,小畜。君子以懿文德。小畜,柔得位而上下应之,曰小畜。健而巽,刚中而志行,乃亨。密云不雨,尚往也。自我西郊,施未行也。"),
"涣": ("散而不杂", "宜收束归序,整合资源",
"风行水上,涣。先王以享于帝立庙。涣亨,刚来而不穷,柔得位乎外而上同。王假有庙,王乃在中也。利涉大川,乘木有功也。"),
"渐": ("循序渐进", "宜积微成著,不急于求成",
"山上有木,渐。君子以居贤德善俗。渐之进也,女归吉也。进得位,往有功也。进以正,可以正邦也。其位,刚得中也。止而巽,动不穷也。"),
"益": ("增益不足", "宜补短板强优势,完善自身",
"风雷,益。君子以见善则迁,有过则改。益,损上益下,民说无疆。自上下下,其道大光。利有攸往,中正有庆。利涉大川,木道乃行。"),
"离": ("光明通达", "宜清醒明辨,彰显才智",
"明两作,离。大人以继明照于四方。离,丽也。日月丽乎天,百谷草木丽乎土,重明以丽乎正,乃化成天下。柔丽乎中正,故亨。"),
"晋": ("上进光明", "宜稳步进取,提升自我",
"明出地上,晋。君子以自昭明德。晋,进也。明出地上,顺而丽乎大明,柔进而上行,是以康侯用锡马蕃庶,昼日三接也。"),
"睽": ("求同存异", "宜包容互谅,化解分歧",
"上火下泽,睽。君子以同而异。睽,火动而上,泽动而下,二女同居,其志不同行。说而丽乎明,柔进而上行,得中而应乎刚,是以小事吉。"),
"大有": ("光明盛旺", "宜舒展抱负,大展身手",
"火在天上,大有。君子以遏恶扬善,顺天休命。大有,柔得尊位,大中而上下应之,曰大有。其德刚健而文明,应乎天而时行,是以元亨。"),
"未济": ("事未竟成", "宜蓄力待发,持续推进",
"火在水上,未济。君子以慎辨物居方。未济,亨。柔得中也。小狐汔济,未出中也。濡其尾,无攸利,不续终也。虽不当位,刚柔应也。"),
"旅": ("行止在外", "宜守礼安身,适应环境",
"山上有火,旅。君子以明慎用刑,而不留狱。旅,小亨,柔得中乎外而顺乎刚,止而丽乎明,是以小亨,旅贞吉也。旅之时义大矣哉!"),
"噬嗑": ("有阻必通", "宜破除滞碍,打通关节",
"雷电,噬嗑。先王以明罚勅法。噬嗑,亨。利用狱,颐中有物曰噬嗑。噬嗑而亨,刚柔分,动而明,雷电合而章。柔得中而上行,虽不当位,利用狱也。"),
"鼎": ("稳固成事", "宜守成拓新,焕新面貌",
"木上有火,鼎。君子以正位凝命。鼎,象也。以木巽火,亨饪也。圣人亨以享上帝,而大亨以养圣贤。巽而耳目聪明,柔进而上行,得中而应乎刚,是以元亨。"),
"坤": ("纯阴主静", "宜安养固本,包容承载",
"地势坤。君子以厚德载物。至哉坤元,万物资生,乃顺承天。坤厚载物,德合无疆。含弘光大,品物咸亨。牝马地类,行地无疆,柔顺利贞。"),
"临": ("气盛渐进", "宜积极有为,主动作为",
"泽上有地,临。君子以教思无穷,容保民无疆。临,刚浸而长,说而顺,刚中而应,大亨以正,天之道也。至于八月有凶,消不久也。"),
"泰": ("阴阳和畅", "宜把握良机,大展宏图",
"天地交,泰。后以财成天地之道,辅相天地之宜,以左右民。泰,小往大来,吉亨。则是天地交而万物通也,上下交而其志同也。"),
"师": ("统摄有序", "宜守规立矩,严明纪律",
"地中有水,师。君子以容民畜众。师,众也。贞,丈人吉,无咎。能以众正,可以王矣。刚中而应,行险而顺,以此毒天下,而民从之,吉又何咎矣。"),
"谦": ("谦卑自持", "宜低调行事,不骄不躁",
"地中有山,谦。君子以裒多益寡,称物平施。谦亨,天道下济而光明,地道卑而上行。天道亏盈而益谦,地道变盈而流谦,鬼神害盈而福谦,人道恶盈而好谦。"),
"复": ("一阳来复", "宜重启新局,焕新出发",
"雷在地中,复。先王以至日闭关,商旅不行,后不省方。复亨,刚反,动而以顺行,是以出入无疾,朋来无咎。反复其道,七日来复,天行也。"),
"升": ("徐徐上升", "宜稳步进取,日积月累",
"地中生木,升。君子以顺德,积小以高大。升,元亨。用见大人,勿恤,南征吉。柔以时升,巽而顺,刚中而应,是以大亨。用见大人,勿恤,有庆也。"),
"明夷": ("藏明于暗", "宜低调蛰伏,保全自身",
"明入地中,明夷。君子以莅众,用晦而明。明夷,利艰贞。内文明而外柔顺,以蒙大难,文王以之。利艰贞,晦其明也,内难而能正其志,箕子以之。"),
"兑": ("和悦舒畅", "宜沟通悦纳,增进情谊",
"丽泽,兑。君子以朋友讲习。兑,说也。刚中而柔外,说以利贞,是以顺乎天而应乎人。说以先民,民忘其劳。说以犯难,民忘其死。说之大,民劝矣哉!"),
"夬": ("刚决果断", "宜除杂存真,斩断纷扰",
"泽上于天,夬。君子以施禄及下,居德则忌。夬,决也,刚决柔也。健而说,决而和。扬于王庭,柔乘五刚也。孚号有厉,其危乃光也。"),
"困": ("陷入困局", "宜守志待解,不坠心志",
"泽无水,困。君子以致命遂志。困,亨,贞,大人吉,无咎。有言不信,尚口乃穷也。困而不失其所亨,其唯君子乎?贞,大人吉,以刚中也。"),
"咸": ("感应相通", "宜共情达意,增进理解",
"山上有泽,咸。君子以虚受人。咸,感也。柔上而刚下,二气感应以相与,止而说,男下女,是以亨利贞,取女吉也。天地感而万物化生,圣人感人心而天下和平。"),
"随": ("顺时顺势", "宜灵活变通,不固执己见",
"泽中有雷,随。君子以向晦入宴息。随,刚来而下柔,动而说,随。大亨贞,无咎,而天下随时。随时之义大矣哉!"),
"大过": ("气盛过极", "宜戒满收敛,谨防折损",
"泽灭木,大过。君子以独立不惧,遁世无闷。大过,大者过也。栋桡,本末弱也。刚过而中,巽而说行,利有攸往,乃亨。大过之时大矣哉!"),
"革": ("除旧布新", "宜主动调整,顺应变革",
"泽中有火,革。君子以治历明时。革,水火相息,二女同居,其志不相得,曰革。己日乃孚,革而信之。文明以说,大亨以正,革而当,其悔乃亡。"),
"萃": ("聚气凝神", "宜整合归心,凝聚力量",
"泽上于地,萃。君子以除戎器,戒不虞。萃,聚也。顺以说,刚中而应,故聚也。王假有庙,致孝享也。利见大人亨,聚以正也。用大牲吉,利有攸往,顺天命也。"),
"乾": ("纯阳鼎盛", "宜全力奋进,彰显抱负",
"天行健。君子以自强不息。大哉乾元,万物资始,乃统天。云行雨施,品物流形。大明终始,六位时成,时乘六龙以御天。乾道变化,各正性命,保合太和,乃利贞。"),
"讼": ("口舌将起", "宜忍让避争,以和为贵",
"天与水违行,讼。君子以作事谋始。讼,上刚下险,险而健,讼。讼有孚,窒惕中吉,刚来而得中也。终凶,讼不可成也。利见大人,尚中正也。"),
"遁": ("阳退阴长", "宜收敛避锐,暂避锋芒",
"天下有山,遁。君子以远小人,不恶而严。遁亨,遁而亨也。刚当位而应,与时行也。小利贞,浸而长也。遁之时义大矣哉!"),
"无妄": ("自然守正", "宜不妄为不妄念,顺势而为",
"天下雷行,物与无妄。先王以茂对时,育万物。无妄,元亨,利贞。其匪正有眚,不利有攸往。无妄之往,何之矣?天命不佑,行矣哉!"),
"姤": ("一阴初生", "宜防微杜渐,警惕隐患",
"天下有风,姤。后以施命诰四方。姤,遇也,柔遇刚也。勿用取女,不可与长也。天地相遇,品物咸章也。刚遇中正,天下大行也。姤之时义大矣哉!"),
"同人": ("心意相通", "宜协同发力,携手成事",
"天与火,同人。君子以类族辨物。同人于野,亨。利涉大川,乾行也。文明以健,中正而应,君子正也。唯君子为能通天下之志。"),
"否": ("阴阳闭塞", "宜守中待通,静待转机",
"天地不交,否。君子以俭德辟难,不可荣以禄。否,匪人,不利君子贞,大往小来。则是天地不交而万物不通也,上下不交而天下无邦也。"),
"履": ("步步安稳", "宜谨言慎行,行稳致远",
"上天下泽,履。君子以辨上下,定民志。履虎尾,不咥人,亨。刚中正,履帝位而不疚,光明也。亨,刚中正,履帝位而不疚,光明也。")
}
# ==================== 完整卦义 - 岁序系统(以立春为岁首)====================
GUA_YEAR_FULL = {
"坎": ("险中守正", "宜稳起步,不冒进",
"岁首之际,阳气初生,宜如坎水之行,险中守正,不急于求成。冬尽春来,万象更新之时,当稳扎稳打,如履薄冰。"),
"蹇": ("前路微阻", "宜缓图,先清障碍",
"春气初动,尚有寒意,宜审时度势,先解决遗留问题。前路虽艰,循序渐进,反身修德,终能通达。"),
"屯": ("初萌未稳", "宜夯基,积微成著",
"万物始生,宜如草木之芽,深耕细作,不可揠苗助长。春种之时,重在根基,宜建侯而不宁。"),
"井": ("安定守恒", "宜守常,滋养生机",
"井养而不穷,春灌之时,宜保持常规,滋养万物。改邑不改井,守恒之道,往来井井,无丧无得。"),
"既济": ("初成宜慎", "防骄满,稳扎稳打",
"小事初成,但大事未济,宜谨慎守成,不可骄傲自满。春生夏长之交,戒之在骄,思患预防。"),
"比": ("亲善协作", "宜结善缘,借势聚力",
"春和景明,宜亲比同道,建立联盟,为一年之计奠基。亲比之道,诚信为本,上下相应,凝聚合力。"),
"节": ("节制有度", "宜守节律,不躁不纵",
"春分将至,昼夜渐平,宜节制欲望,保持平衡。春生之时,过犹不及,制数度,议德行。"),
"需": ("待时守中", "宜蓄力,静待春机",
"春雨欲来,宜耐心等待,不可盲目行动。待时而动,事半功倍,刚健而不陷,其义不困穷。"),
"艮": ("当止则止", "宜审势,不盲动",
"春分之际,阴阳平衡,宜观察时势,知止而后行。动静不失其时,时止则止,时行则行。"),
"颐": ("养身养心", "宜调摄,蓄能生发",
"春生之时,宜调养身心,为夏长做准备。天地养万物,圣人养贤以及万民,慎言语,节饮食。"),
"蛊": ("微乱初现", "宜整饬,肃清隐患",
"春忙之际,事务繁杂,宜及时整理,防止积弊。振蛊之道,在于育德新民,振民育德。"),
"贲": ("文饰条理", "宜规范,完善细节",
"春深之时,宜修饰文彩,规范制度。文明以止,人文也,明庶政,无敢折狱。"),
"剥": ("阳气初剥", "宜守弱,保全根本",
"春尽夏初,阳气盛极将衰,宜收敛锋芒。顺而止之,厚下安宅,固本之道,不利有攸往。"),
"损": ("减损浮华", "宜去繁,聚焦核心",
"春夏之交,宜去其浮华,留其精华。损下益上,其道上行,惩忿窒欲,损而有孚。"),
"大畜": ("厚积蓄力", "宜深藏,待时勃发",
"夏前蓄力之时,宜厚积而薄发。刚健笃实辉光,日新其德,不家食吉,养贤也。"),
"蒙": ("蒙昧初开", "宜求教,启智明理",
"夏学之时,宜虚心求教,开启智慧。蒙以养正,圣功也,果行育德,匪我求童蒙。"),
"震": ("警醒而动", "宜振作,抢抓农时",
"立夏之际,雷动万物,宜积极行动。震惊百里,不丧匕鬯,恐惧修省,出可以守宗庙社稷。"),
"恒": ("守常不变", "宜坚持,深耕不辍",
"夏长之时,宜持之以恒,不可半途而废。久于其道,天地之道恒久而不已也,立不易方。"),
"丰": ("气盛丰满", "宜戒骄,稳扩成果",
"夏盛之际,万物丰茂,宜戒骄戒躁。日中则昃,月盈则食,天地盈虚,与时消息。"),
"豫": ("顺时安逸", "宜舒展,养精蓄锐",
"夏中之时,宜劳逸结合,保持愉悦。顺以动,故天地如之,作乐崇德,殷荐之上帝。"),
"归妹": ("归根守正", "宜固本,不逐末流",
"夏末之际,宜回归根本,不逐浮华。天地不交而万物不兴,归妹人之终始也,永终知敝。"),
"大壮": ("气旺势强", "宜慎行,稳中求进",
"阳气大壮之时,宜谨慎行事,不可鲁莽。正大而天地之情可见矣,非礼弗履。"),
"解": ("滞碍消散", "宜舒展,顺势而为",
"夏暑将解,宜舒缓压力,顺其自然。动而免乎险,解利西南,往得众也,赦过宥罪。"),
"小过": ("小错可容", "宜修正,不钻牛角",
"夏秋之交,宜宽容小过,及时修正。小者过而亨也,过以利贞,与时行也,行过乎恭。"),
"巽": ("谦逊柔顺", "宜顺势,借力成事",
"立秋之际,秋风送爽,宜顺势而为。重巽以申命,刚巽乎中正而志行,申命行事。"),
"家人": ("内守安定", "宜和睦,稳固后方",
"秋收之时,宜安定家庭,稳固根基。女正位乎内,男正位乎外,家有严君,父母之谓也。"),
"观": ("静观其变", "宜察势,不妄决断",
"秋高气爽,宜登高望远,观察大势。省方观民设教,观天之神道而四时不忒。"),
"中孚": ("诚信守中", "宜定心,坚守信义",
"秋分之际,阴阳平衡,宜诚信为本。柔在内而刚得中,孚乃化邦,议狱缓死。"),
"小畜": ("微积小成", "宜积累,聚少成多",
"秋收之时,宜积小胜为大胜。柔得位而上下应之,健而巽,刚中而志行,懿文德。"),
"涣": ("散而有序", "宜整合,统筹资源",
"秋散之时,宜整合资源,有序分配。刚来而不穷,柔得位乎外而上同,享于帝立庙。"),
"渐": ("循序渐进", "宜稳进,不急于求成",
"秋深之时,宜循序渐进,不可急躁。进得位,往有功也,止而巽,动不穷,居贤德善俗。"),
"益": ("增益不足", "宜补短板,强基固本",
"秋冬之交,宜查漏补缺,增益其所不能。损上益下,民说无疆,见善则迁,有过则改。"),
"离": ("光明通达", "宜清醒,收官有序",
"夏末秋初,光明渐收,宜清醒总结。日月丽乎天,百谷草木丽乎土,继明照于四方。"),
"晋": ("上进有度", "宜稳步,不贪快进",
"晋升之时,宜稳步上升,不可冒进。明出地上,顺而丽乎大明,柔进而上行,自昭明德。"),
"睽": ("求同存异", "宜包容,化解分歧",
"睽乖之时,宜求同存异,化解矛盾。火动而上,泽动而下,同而异,类族辨物。"),
"大有": ("盛旺宜慎", "宜收敛,不炫其势",
"大有之年,宜收敛锋芒,不可炫耀。柔得尊位,大中而上下应之,遏恶扬善,顺天休命。"),
"未济": ("事未竟成", "宜续力,不半途废",
"年终之际,宜继续努力,完成未竟之事。虽不当位,刚柔应也,慎辨物居方。"),
"旅": ("行止有度", "宜守礼,适应秋序",
"秋行之季,宜守礼而行,适应时令。柔得中乎外而顺乎刚,止而丽乎明,明慎用刑。"),
"噬嗑": ("有阻必通", "宜破滞,打通关节",
"秋收之时,宜破除障碍,确保畅通。颐中有物曰噬嗑,利用狱,明罚勅法。"),
"鼎": ("稳固成事", "宜守成,焕新面貌",
"鼎新之时,宜稳固成果,焕然一新。以木巽火,亨饪也,正位凝命,巽而耳目聪明。"),
"坤": ("纯阴承载", "宜包容,安养万物",
"秋分之际,地气正盛,宜包容承载。至哉坤元,万物资生,厚德载物,德合无疆。"),
"临": ("气盛渐进", "宜有为,稳步推进",
"秋临之时,宜积极进取,稳步推进。刚浸而长,说而顺,刚中而应,教思无穷,容保民无疆。"),
"泰": ("阴阳和畅", "宜把握,顺势收官",
"泰和之时,宜把握良机,完成收官。天地交而万物通,上下交而其志同,财成天地之道。"),
"师": ("统摄有序", "宜守规,严明纪律",
"秋收冬藏,宜严明纪律,统摄有序。能以众正,可以王矣,容民畜众,毒天下而民从之。"),
"谦": ("谦卑自持", "宜低调,不骄不躁",
"丰收之时,宜谦虚低调,不可骄傲。天道亏盈而益谦,地道变盈而流谦,鬼神害盈而福谦。"),
"复": ("一阳来复", "宜重启,焕新布局",
"冬至前夕,阳气初生,宜布局来年。刚反,动而以顺行,反复其道,七日来复,至日闭关。"),
"升": ("徐徐上升", "宜稳步,日积月累",
"冬蓄之时,宜日积月累,徐徐上升。柔以时升,巽而顺,刚中而应,顺德积小以高大。"),
"明夷": ("藏明于暗", "宜低调,保全成果",
"冬藏之际,宜藏明于暗,保全实力。内文明而外柔顺,以蒙大难,用晦而明,晦其明也。"),
"兑": ("和悦舒畅", "宜沟通,分享丰收",
"冬闲之时,宜和悦沟通,分享成果。刚中而柔外,说以利贞,朋友讲习,先民忘其劳。"),
"夬": ("刚决果断", "宜除杂,斩断纷扰",
"冬决之时,宜果断决策,去除杂念。刚决柔也,健而说,决而和,施禄及下,居德则忌。"),
"困": ("陷入困局", "宜守志,不坠心志",
"冬困之时,宜坚守志节,不坠心志。困而不失其所亨,致命遂志,其唯君子乎,有言不信。"),
"咸": ("感应相通", "宜共情,凝聚人心",
"冬感之时,宜以情感人,凝聚人心。二气感应以相与,止而说,男下女,虚受人,天下和平。"),
"随": ("顺时顺势", "宜变通,不固执见",
"冬随之时,宜顺应时势,灵活变通。刚来而下柔,动而说,大亨贞,向晦入宴息。"),
"大过": ("气盛过极", "宜戒满,谨防折损",
"冬极之时,宜戒满戒骄,防止折损。刚过而中,巽而说行,独立不惧,遁世无闷,栋桡本末弱。"),
"革": ("除旧布新", "宜调整,顺应冬序",
"冬革之时,宜除旧布新,调整策略。水火相息,文明以说,大亨以正,革而当。"),
"萃": ("聚气凝神", "宜整合,归藏精华",
"冬藏之际,宜聚气凝神,归藏精华。顺以说,刚中而应,除戎器戒不虞,致孝享也。"),
"乾": ("纯阳潜隐", "宜养锐,静待来春",
"冬至之时,纯阳潜隐,宜养精蓄锐。刚健笃实,辉光日新,自强不息,待机而动,统天御天。"),
"讼": ("口舌将起", "宜忍让,以和为贵",
"冬闲之时,宜忍让为先,避免争讼。上刚下险,险而健,作事谋始,尚中正,窒惕中吉。"),
"遁": ("阳退阴长", "宜收敛,暂避锋芒",
"冬遁之时,宜收敛退避,保全实力。刚当位而应,与时行也,远小人,不恶而严,浸而长也。"),
"无妄": ("自然守正", "宜不妄为,顺势蛰伏",
"冬藏之时,宜顺其自然,不可妄为。物与无妄,茂对时育万物,匪正有眚,不利有攸往。"),
"姤": ("一阴初生", "宜防微,警惕隐患",
"冬至阳生,阴犹未散,宜防微杜渐。柔遇刚也,勿用取女,不可与长,施命诰四方。"),
"同人": ("心意相通", "宜协同,共渡寒冬",
"冬寒之时,宜同心协力,共渡难关。类族辨物,文明以健,中正而应,通天下之志。"),
"否": ("阴阳闭塞", "宜守中,静待转机",
"冬否之时,阴阳闭塞,宜守中待时。天地不交而万物不通,上下不交而天下无邦,俭德辟难。"),
"履": ("步步安稳", "宜谨行,行稳致远",
"岁末之际,宜谨慎行事,行稳致远。履虎尾不咥人,刚中正,履帝位而不疚,辨上下定民志。")
}
# ==================== 天文引擎 ====================
class AstroEngine:
# 扩展的VSOP87系数以提高精度
L0 = [
(175347046, 0, 0),
(3341656, 4.6692568, 6283.07585),
(34894, 4.6261, 12566.1517),
(3497, 2.7441, 5753.3849),
(3418, 2.8289, 3.5231),
(3136, 3.6277, 77713.7715),
(2676, 4.4181, 7860.4194),
(2343, 6.1352, 3930.2097),
(1324, 0.7425, 11506.7698),
(1273, 2.0371, 529.691),
(1199, 1.1096, 1577.3435),
(990, 5.233, 5884.927),
(902, 2.045, 26.298),
(857, 3.508, 398.149),
(780, 1.179, 5223.694),
(753, 2.533, 5507.553),
(505, 4.583, 18849.228),
(492, 4.205, 775.523),
(357, 2.92, 0.067),
(317, 5.849, 11790.629),
(284, 1.899, 796.298),
(271, 0.315, 10977.079),
(243, 0.345, 5486.778),
(206, 4.806, 2544.314),
(205, 1.869, 5573.143),
(202, 2.458, 6069.777),
(156, 0.833, 213.299),
(132, 3.411, 2942.463),
(126, 1.083, 20.775),
(115, 0.645, 0.98),
(103, 0.636, 4694.003),
(102, 0.976, 15720.839),
(102, 4.267, 7.114),
(99, 6.21, 2146.17),
(98, 0.68, 155.42),
(86, 5.98, 161000.69),
(85, 1.3, 6275.96),
(85, 3.67, 71430.7),
(80, 1.81, 17260.15),
(79, 3.04, 12036.46),
(75, 2.53, 5088.63),
(74, 1.14, 5088.63),
(74, 3.5, 3154.69),
(73, 0.61, 13367.97),
(63, 4.67, 14314.17),
(62, 1.46, 19514.29),
(61, 2.67, 9437.76),
(60, 5.56, 632.78),
(56, 4.39, 14712.32),
(56, 3.47, 14143.5),
(55, 1.18, 801.82),
(53, 1.76, 16200.77),
(52, 5.22, 12139.55),
(52, 3.63, 22003.91),
(50, 4.25, 12569.67),
(48, 1.12, 1194.45),
(47, 2.53, 1059.38),
(44, 3.7, 17298.18),
(44, 3.39, 4705.73),
(43, 1.04, 20426.57),
(42, 2.7, 7084.9),
(41, 5.37, 13916.02),
(40, 1.03, 149.56),
(38, 4.14, 7058.6),
(37, 3.09, 18073.7),
(37, 5.1, 14945.32),
(36, 4.76, 39302.1),
(36, 2.8, 2352.87),
(36, 3.98, 12528.02),
(35, 3.2, 17789.85),
(34, 5.14, 16496.36),
(34, 1.19, 23937.14),
(33, 0.74, 12132.44),
(33, 6.25, 160.41),
(32, 2.46, 17789.85),
(31, 2.27, 16730.46),
(30, 1.92, 12416.59),
(30, 3.99, 17256.63),
(28, 5.43, 12592.45),
(28, 1.42, 16858.48),
(27, 0.83, 12352.85),
(26, 5.52, 18139.29),
(26, 3.92, 234.46),
(25, 3.13, 12029.35),
(25, 1.31, 12043.01),
(25, 1.01, 658.11),
(25, 5.51, 6496.37),
(24, 2.2, 23013.54),
(24, 1.73, 23013.54),
(24, 5.02, 83996.85),
(23, 0.52, 23581.26),
(23, 1.21, 553.57),
(22, 2.45, 6309.37),
(22, 1.47, 135.07),
(21, 2.62, 522.58),
(21, 5.34, 220.41),
(21, 0.49, 11371.7),
(20, 1.68, 3340.61),
(20, 3.23, 1748.02),
(20, 4.66, 1592.6),
(19, 4.76, 2352.87),
(19, 3.84, 7234.79),
(19, 5.84, 1990.75),
(18, 3.68, 23543.23),
(18, 0.13, 11015.11),
(18, 2.78, 1748.02),
(17, 4.19, 23581.26),
(17, 3.18, 15671.82),
(17, 5.26, 3930.21),
(17, 3.13, 7860.42),
(16, 0.09, 12721.57),
(16, 1.0, 12721.57),
(16, 3.32, 31441.68),
(16, 4.2, 11712.96),
(16, 5.4, 617.92),
(15, 4.72, 12573.27),
(15, 2.52, 1990.75),
(15, 4.28, 5120.6),
(15, 4.65, 12168.0),
(15, 0.3, 24491.72),
(15, 0.31, 20426.57),
(15, 2.11, 24491.72),
(14, 1.29, 16200.77),
(14, 2.11, 16200.77),
(14, 3.94, 1589.07),
(14, 0.13, 3738.76),
(14, 2.1, 7330.82),
(14, 2.56, 155.42),
(14, 0.04, 7238.68),
(14, 5.41, 3738.76),
(13, 3.56, 6438.5),
(13, 4.01, 11506.77),
(13, 5.84, 6496.37),
(13, 1.97, 10177.26),
(13, 2.08, 1589.07),
(13, 0.89, 17370.06),
(12, 4.31, 10177.26),
(12, 4.11, 3894.18),
(12, 1.31, 3894.18),
(12, 0.67, 18073.7),
(12, 0.96, 1589.07),
(12, 1.1, 242.73),
(12, 5.13, 17256.63),
(12, 2.29, 5429.88),
(12, 3.42, 220.41),
(12, 3.73, 6303.43),
(12, 4.7, 6062.66),
(11, 5.76, 1748.02),
(11, 0.74, 6303.43),
(11, 5.61, 71430.7),
(11, 3.74, 6467.93),
(11, 2.68, 11712.96),
(11, 3.78, 12528.02),
(11, 2.14, 6286.6),
(11, 5.56, 14143.5),
(11, 0.82, 13095.65),
(11, 1.64, 11790.63),
(11, 0.51, 17996.03),
(10, 4.25, 6286.6),
(10, 5.96, 6283.08),
(10, 5.37, 1349.87),
(10, 2.94, 625.67),
(10, 1.74, 9623.69),
(10, 2.28, 1589.07),
(10, 3.81, 12352.85),
(10, 1.79, 3.88),
(10, 5.24, 6283.08),
(9, 4.26, 242.73),
(9, 5.64, 639.9),
(9, 5.64, 639.9),
(9, 0.38, 206.18),
(9, 0.44, 11769.85),
(9, 2.24, 11769.85),
(9, 5.3, 12592.45),
(9, 3.17, 12592.45),
(9, 4.95, 3894.18),
(9, 5.55, 3894.18),
(8, 1.36, 135.07),
(8, 1.96, 16730.46),
(8, 2.46, 16730.46),
(8, 2.96, 16730.46),
(8, 5.65, 9380.96),
(8, 3.59, 9380.96),
(8, 0.72, 4705.73),
(8, 2.47, 4705.73),
(8, 0.44, 13517.87),
(8, 0.44, 13517.87),
(8, 4.06, 487.39),
(8, 4.06, 487.39),
(8, 1.9, 110.41),
(8, 1.9, 110.41),
(8, 3.03, 13760.6),
(8, 3.03, 13760.6),
(8, 0.34, 290.97),
(8, 0.34, 290.97),
(8, 4.56, 8429.24),
(8, 4.56, 8429.24),
(8, 1.49, 19651.05),
(8, 1.49, 19651.05),
(8, 3.45, 19651.05),
(8, 3.45, 19651.05),
(7, 4.58, 801.82),
(7, 4.58, 801.82),
(7, 1.3, 160.41),
(7, 1.3, 160.41),
(7, 3.34, 160.41),
(7, 3.34, 160.41),
(7, 5.02, 103.09),
(7, 5.02, 103.09),
(7, 1.24, 21228.39),
(7, 1.24, 21228.39),
(7, 2.89, 21228.39),
(7, 2.89, 21228.39),
(7, 1.25, 7058.6),
(7, 1.25, 7058.6),
(7, 4.26, 7058.6),
(7, 4.26, 7058.6),
(7, 2.62, 5333.9),
(7, 2.62, 5333.9),
(7, 5.06, 5333.9),
(7, 5.06, 5333.9),
(7, 3.78, 4690.48),
(7, 3.78, 4690.48),
(7, 4.14, 6283.08),
(7, 4.14, 6283.08),
(7, 2.05, 6283.08),
(7, 2.05, 6283.08),
(7, 2.02, 6283.08),
(7, 2.02, 6283.08),
(7, 0.53, 6283.08),
(7, 0.53, 6283.08)
]
L1 = [
(628331966747, 0, 0),
(206059, 2.678235, 6283.07585),
(4303, 2.6351, 12566.1517),
(425, 1.59, 3.523),
(119, 5.796, 26.298),
(109, 2.966, 1577.344),
(93, 2.59, 18849.23),
(72, 1.14, 529.69),
(68, 1.87, 398.15),
(67, 4.41, 5507.55),
(59, 2.89, 5223.69),
(56, 2.17, 155.42),
(45, 0.4, 796.3),
(36, 0.47, 775.52),
(29, 2.65, 7.11),
(21, 5.34, 0.98),
(19, 1.85, 5486.78),
(19, 4.97, 213.3),
(17, 2.99, 6275.96),
(16, 0.03, 2544.31),
(16, 1.43, 2146.17),
(15, 1.21, 10977.08),
(12, 2.83, 1748.02),
(12, 3.26, 5088.63),
(12, 5.27, 1194.45),
(12, 2.08, 4694.0),
(11, 0.77, 553.57),
(10, 1.3, 6286.6),
(10, 4.24, 1349.87),
(9, 2.7, 242.73),
(9, 5.64, 951.72),
(8, 5.3, 2352.87),
(6, 2.65, 9437.76),
(6, 4.67, 4690.48)
]
def __init__(self):
self.db = LICHUN_DATABASE
def jd(self, dt):
y, m, d = dt.year, dt.month, dt.day + dt.hour / 24 + dt.minute / 1440 + dt.second / 86400
if m <= 2:
y -= 1
m += 12
A = int(y / 100)
B = 2 - A + int(A / 4)
return int(365.25 * (y + 4716)) + int(30.6001 * (m + 1)) + d + B - 1524.5
def sun_lon(self, dt):
"""计算太阳黄经(精确版)"""
try:
JD = self.jd(dt)
T = (JD - 2451545.0) / 36525.0 # 儒略世纪数
# 使用更精确的公式
L0 = 280.46646 + 36000.76983 * T + 0.0003032 * T * T
M = 357.52911 + 35999.05029 * T - 0.0001537 * T * T
C = (1.914602 - 0.004817 * T - 0.000014 * T * T) * sin(radians(M))
C += (0.019993 - 0.000101 * T) * sin(radians(2 * M))
C += 0.000289 * sin(radians(3 * M))
sun_lon = L0 + C
sun_lon = sun_lon % 360
# 考虑章动和光行差(简化)
sun_lon += 0.0053 * sin(radians(M)) - 0.0069 * sin(radians(2 * sun_lon))
return sun_lon % 360
except Exception as e:
print(f"太阳黄经计算错误: {e}")
# 后备方案:使用简化公式
days = (dt - datetime(dt.year, 1, 1)).total_seconds() / 86400
return (280 + days * 0.9856) % 360
def lichun(self, year):
if year in self.db:
m, d, h, mi = self.db[year]
return datetime(year, m, d, h, mi)
return datetime(year, 2, 4, 6, 0)
# ==================== 计算器 ====================
class Calculator:
SA = 5.625 # 每气角度
DM = 22.5 # 每度分钟数
def __init__(self):
self.ae = AstroEngine()
def get_ke_detail(self, dt):
"""获取八刻详细信息"""
hour = dt.hour + dt.minute / 60
# if 23 <= hour or hour < 1:
# ke_index = 0 # 子-坎 (23:00-01:00)
# elif 1 <= hour < 3:
# ke_index = 1 # 丑-艮 (01:00-03:00) - 修正为2点中点
# elif 3 <= hour < 5:
# ke_index = 2 # 卯-震 (03:00-05:00) - 修正为4点中点
# elif 5 <= hour < 7:
# ke_index = 3 # 辰-巽 (05:00-07:00) - 修正为6点中点
# elif 7 <= hour < 9:
# ke_index = 4 # 午-离 (07:00-09:00) - 修正为8点中点
# elif 9 <= hour < 11:
# ke_index = 5 # 未-坤 (09:00-11:00) - 修正为10点中点
# elif 11 <= hour < 13:
# ke_index = 6 # 酉-兑 (11:00-13:00) - 修正为12点中点
# elif 13 <= hour < 15:
# ke_index = 7 # 戌-乾 (13:00-15:00) - 修正为14点中点
# elif 15 <= hour < 17:
# ke_index = 0 # 子-坎 (15:00-17:00) - 修正为16点中点
# elif 17 <= hour < 19:
# ke_index = 1 # 丑-艮 (17:00-19:00) - 修正为18点中点
# elif 19 <= hour < 21:
# ke_index = 2 # 卯-震 (19:00-21:00) - 修正为20点中点
# else: # 21 <= hour < 23
# ke_index = 3 # 辰-巽 (21:00-23:00) - 修正为22点中点
if 23 <= hour or hour < 1:
ke_index = 0 # 子-坎 (00:00-03:00)
elif 3 <= hour < 6:
ke_index = 1 # 丑-艮 (03:00-06:00)
elif 6 <= hour < 9:
ke_index = 2 # 卯-震 (06:00-09:00)(
elif 9 <= hour < 12:
ke_index = 3 # 辰-巽 (09:00-12:00)
elif 12 <= hour < 15:
ke_index = 4 # 午-离 (12:00-15:00)(
elif 15 <= hour < 18:
ke_index = 5 # 未-坤 (15:00-18:00)
elif 18 <= hour < 21:
ke_index = 6 # 酉-兑 (18:00-21:00)
else: # 18 <= hour < 21
ke_index = 7 # 戌-乾 (21:00-00:00)
# 由于我们定义了8个KE_DETAILS,需要将ke_index映射到0-7范围
detail_index = ke_index % 8
detail = KE_DETAILS[detail_index]
# 获取四时信息
sishi_index = hour // 6 # 0-3
if sishi_index >= 4:
sishi_index = 3
sishi = DAY_SISHI[int(sishi_index)]
return {
"ke_index": ke_index,
"detail": detail,
"sishi": sishi
}
def daily(self, dt=None):
if dt is None:
dt = datetime.now()
try:
mid = dt.replace(hour=0, minute=0, second=0, microsecond=0)
mins = (dt - mid).total_seconds() / 60
idx = int(mins // self.DM) % 64
prog = (mins % self.DM) / self.DM
circle = idx * self.SA + prog * self.SA
# 获取八刻详细信息
ke_info = self.get_ke_detail(dt)
ke_detail = ke_info["detail"]
sishi = ke_info["sishi"]
gua = GUA_SEQUENCE[idx]
title, desc, detail = GUA_DAILY_FULL.get(gua, ("", "", ""))
# 获取该度的时间边界
degree_time = DEGREE_TIMES[idx]
next_t = mid + timedelta(minutes=(idx + 1) * self.DM)
return {
"gua": gua,
"num": idx + 1,
"title": title,
"desc": desc,
"detail": detail,
"ke": ke_detail["di"],
"ke_gua": ke_detail["gua"],
"ke_name": f"{ke_detail['di']}-{ke_detail['gua']}",
"ke_fangwei": ke_detail["fangwei"],
"ke_range": ke_detail["range"],
"ke_desc": ke_detail["desc"],
"sishi": sishi["name"],
"sishi_sixiang": sishi["sixiang"],
"sishi_desc": sishi["desc"],
"wx": WUXING[ke_detail["gua"]],
"circle": circle,
"prog": prog,
"next": next_t,
"remain": next_t - dt,
"dt": dt,
"degree_start": degree_time["start"],
"degree_end": degree_time["end"]
}
except Exception as e:
print(f"daily计算错误: {e}")
return {
"gua": "坎",
"num": 1,
"title": "险中存正",
"desc": "宜谨言慎行,稳渡难关",
"detail": "默认值",
"ke": "子",
"ke_gua": "坎",
"ke_name": "子-坎",
"ke_fangwei": "正北",
"ke_range": "23:00-01:00",
"ke_desc": "子夜寒冷",
"sishi": "夜",
"sishi_sixiang": "老阴",
"sishi_desc": "阴极盛",
"wx": "水",
"circle": 0,
"prog": 0,
"next": dt + timedelta(minutes=22.5),
"remain": timedelta(minutes=22.5),
"dt": dt,
"degree_start": "00:00:00",
"degree_end": "00:22:30"
}
def yearly(self, dt=None):
if dt is None:
dt = datetime.now()
try:
year = dt.year
lic = self.ae.lichun(year)
if dt < lic:
year -= 1
lic = self.ae.lichun(year)
# 计算从立春到当前时间的天数
days_since_lichun = (dt - lic).total_seconds() / 86400
# 每气约5.625天
qi_index = int(days_since_lichun // 5.625) % 64
prog = (days_since_lichun % 5.625) / 5.625
# 计算圆环角度:第1气坎卦对应0°(正北)
circle_angle = (qi_index + prog) * 5.625
# 确定八节(根据气序索引)
jie_index = qi_index // 8
jie_name = JIE_NAMES[jie_index]
jie_gua = JIE_GUA_LIST[jie_index]
jie_angle = JIE_ANGLES[jie_index]
jie_fangwei = JIE_FANGWEI[jie_index]
jie_qixiang = JIE_QIXIANG[jie_index]
jie_range = JIE_RANGES[jie_index]
# 确定四季
season_index = (jie_index + 1) // 2 % 4 # 立春、春分属春,立夏、夏至属夏,...
season = SEASONS[season_index]
gua = GUA_SEQUENCE[qi_index]
title, desc, detail = GUA_YEAR_FULL.get(gua, ("", "", ""))
# 太阳黄经(仅用于显示)
sun = self.ae.sun_lon(dt)
# 尝试获取天文特征(如果有模板数据)
astro_info = None
if qi_index < len(QI_ASTRONOMY_TEMPLATE):
astro_info = QI_ASTRONOMY_TEMPLATE[qi_index]
return {
"year": year,
"gua": gua,
"num": qi_index + 1,
"title": title,
"desc": desc,
"detail": detail,
"jie": jie_name,
"jie_gua": jie_gua,
"jie_angle": jie_angle,
"jie_fangwei": jie_fangwei,
"jie_qixiang": jie_qixiang,
"jie_range": jie_range,
"season": season["name"],
"season_sixiang": season["sixiang"],
"season_desc": season["desc"],
"wx": WUXING[jie_gua],
"circle": circle_angle,
"sun": sun,
"prog": prog,
"lichun": lic,
"days_since_lichun": days_since_lichun,
"dt": dt,
"astro_info": astro_info
}
except Exception as e:
print(f"yearly计算错误: {e}")
return {
"year": dt.year,
"gua": "坎",
"num": 1,
"title": "险中守正",
"desc": "宜稳起步,不冒进",
"detail": "默认值",
"jie": "立春",
"jie_gua": "艮",
"jie_angle": 45,
"jie_fangwei": "东北",
"jie_qixiang": "阳动初启",
"jie_range": (1, 8, "坎气至需气"),
"season": "春",
"season_sixiang": "少阳",
"season_desc": "阳长阴消,主生",
"wx": "土",
"circle": 0,
"sun": 315,
"prog": 0,
"lichun": datetime(dt.year, 2, 4, 6, 0),
"days_since_lichun": 0,
"dt": dt,
"astro_info": None
}
def birth(self, dt):
d = self.daily(dt)
y = self.yearly(dt)
return {
"dt": dt,
"d": d,
"y": y,
"comp": f"{y['gua']}之{d['gua']}"
}
def year_table(self, year):
lic = self.ae.lichun(year)
table = []
for i in range(64):
# 使用平均天数近似,每气约5.625天
days_offset = i * 5.625
time = lic + timedelta(days=days_offset)
jie_index = i // 8
jie_name = JIE_NAMES[jie_index]
jie_gua = JIE_GUA_LIST[jie_index]
table.append({
"qi": i + 1,
"gua": GUA_SEQUENCE[i],
"time": time,
"jie": jie_name,
"jie_gua": jie_gua
})
return table
def get_wuji_info(self):
"""返回无极信息"""
return {
"title": WUJI_TITLE,
"desc": WUJI_DESC
}
def get_taiji_info(self):
"""返回太极信息"""
return {
"title": TAIJI_TITLE,
"desc": TAIJI_DESC
}
def get_hanshu_info(self):
"""返回寒暑信息"""
return {
"title": HANSHU_TITLE,
"desc": HANSHU_DESC
}
# ==================== GUI ====================
class App:
def __init__(self, root):
self.root = root
self.root.title("卦气正元历 v1.0")
self.root.geometry("1200x780")
self.root.configure(bg='#0a0a0a')
self.calc = Calculator()
self.run = True
# 字体
self.fg = font.Font(family="SimSun", size=32, weight="bold")
self.fb = font.Font(family="SimSun", size=12)
self.fm = font.Font(family="SimSun", size=11)
self.fs = font.Font(family="SimSun", size=10)
self.fc = font.Font(family="Consolas", size=10)
self.setup()
self.update()
def setup(self):
# 按钮栏 - 添加复制按钮
bf = tk.Frame(self.root, bg='#0a0a0a', height=32)
bf.pack(fill=tk.X, padx=3, pady=2)
bf.pack_propagate(False)
buttons = [
("复制全部", self.copy_all, '#e94560'),
("命盘", self.birth, '#222'),
("年表", self.year, '#222'),
("暂停", self.toggle, '#222'),
("导出", self.export, '#222'),
("详解", self.detail, '#222'),
("无极", self.show_wuji, '#222'),
("太极", self.show_taiji, '#222'),
("寒暑", self.show_hanshu, '#222'),
("关于", self.about, '#222')
]
for text, cmd, bg in buttons:
btn = tk.Button(bf, text=text, command=cmd, font=self.fs,
bg=bg, fg='#fff' if bg == '#e94560' else '#ccc',
width=8 if text == '复制全部' else 5,
relief=tk.FLAT if bg == '#e94560' else tk.RAISED)
btn.pack(side=tk.LEFT, padx=2)
# 主区
main = tk.Frame(self.root, bg='#0a0a0a')
main.pack(fill=tk.BOTH, expand=True, padx=5, pady=2)
# 左侧文本区
left = tk.Frame(main, bg='#0a0a0a')
left.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# 一日系统
self.dt = tk.Text(left, height=18, width=58, font=self.fm,
bg='#111', fg='#bbb', relief=tk.SUNKEN, bd=1,
selectbackground='#e94560', selectforeground='#fff',
wrap=tk.WORD, padx=8, pady=5)
self.dt.pack(fill=tk.X, pady=2)
self.dt.tag_config("t", foreground="#e94560", font=self.fb)
self.dt.tag_config("g", foreground="#fff", font=self.fg)
self.dt.tag_config("d", foreground="#888", font=self.fs)
# 岁序系统
self.yt = tk.Text(left, height=18, width=58, font=self.fm,
bg='#111', fg='#bbb', relief=tk.SUNKEN, bd=1,
selectbackground='#4aa', selectforeground='#fff',
wrap=tk.WORD, padx=8, pady=5)
self.yt.pack(fill=tk.X, pady=2)
self.yt.tag_config("t", foreground="#4aa", font=self.fb)
self.yt.tag_config("g", foreground="#fff", font=self.fg)
self.yt.tag_config("d", foreground="#888", font=self.fs)
# 右侧
right = tk.Frame(main, bg='#0a0a0a', width=380)
right.pack(side=tk.RIGHT, fill=tk.Y, padx=5)
right.pack_propagate(False)
# 圆盘
self.cv = tk.Canvas(right, width=360, height=360, bg='#0a0a0a',
highlightthickness=1, highlightbackground='#333')
self.cv.pack(pady=5)
# 图例
tk.Label(right, text="红针=一日系统 青针=岁序系统", font=self.fs, fg='#777', bg='#0a0a0a').pack()
tk.Label(right, text="上离·下坎·左震·右兑 | 洛书方位", font=self.fs, fg='#e94560', bg='#0a0a0a').pack()
# 状态
self.st = tk.Label(right, text="就绪", font=self.fs,
fg='#666', bg='#0a0a0a', anchor=tk.W)
self.st.pack(fill=tk.X, pady=5)
def draw(self, dc, yc):
"""绘制后天八卦洛书方位圆盘(上离下坎,左震右兑)"""
self.cv.delete("all")
cx, cy, r = 180, 180, 150
# 绘制64卦扇形
for i in range(64):
start_angle = 90 - (i * 5.625)
di, yi = int(dc / 5.625) % 64, int(yc / 5.625) % 64
if i == di == yi:
c = '#e94560'
elif i == di:
c = '#e94560'
elif i == yi:
c = '#4aa'
else:
colors = ['#1a3a5c', '#1e4d6b', '#226b6b', '#2a8a6b',
'#3a9b5c', '#4aac4c', '#5bbd3c', '#6bce2c']
c = colors[i // 8]
self.cv.create_arc(cx - r, cy - r, cx + r, cy + r,
start=start_angle, extent=5.625,
fill=c, outline='#222', width=1)
# 正确的后天八卦方位(正北为0°,顺时针)
gua_list = ["离", "坤", "兑", "乾", "坎", "艮", "震", "巽"]
angles = [0, 45, 90, 135, 180, 225, 270, 315]
fangwei_list = ["南", "西南", "西", "西北", "北", "东北", "东", "东南"]
# 绘制八卦方位线和标签
for i in range(8):
gua = gua_list[i]
angle = angles[i]
fangwei = fangwei_list[i]
# 转换为canvas坐标
canvas_angle = 90 - angle
rad = radians(canvas_angle)
# 绘制分隔线
self.cv.create_line(cx + 100 * cos(rad), cy - 100 * sin(rad),
cx + r * cos(rad), cy - r * sin(rad),
fill='#444', width=2)
# 绘制八卦符号
text_x = cx + (r + 25) * cos(rad)
text_y = cy - (r + 25) * sin(rad)
self.cv.create_text(text_x, text_y, text=gua, font=self.fm, fill='#aaa')
# 绘制方位名称
fw_x = cx + (r + 40) * cos(rad)
fw_y = cy - (r + 40) * sin(rad)
self.cv.create_text(fw_x, fw_y, text=fangwei, font=self.fs, fill='#666')
# 在上下左右标注主要方位
self.cv.create_text(cx, cy - r - 20, text="南(离)", font=self.fs, fill='#e94560')
self.cv.create_text(cx, cy + r + 20, text="北(坎)", font=self.fs, fill='#4aa')
self.cv.create_text(cx - r - 30, cy, text="东(震)", font=self.fs, fill='#e94560')
self.cv.create_text(cx + r + 30, cy, text="西(兑)", font=self.fs, fill='#4aa')
# 绘制指针
# 岁序指针(青色)
y_angle = 219 - yc
y_rad = radians(y_angle)
yx = cx + (r - 5) * cos(y_rad)
yy = cy - (r - 5) * sin(y_rad)
self.cv.create_line(cx, cy, yx, yy, fill='#4aa', width=3, arrow=tk.LAST)
# 一日指针(红色)
d_angle = 270 - dc
d_rad = radians(d_angle)
dx = cx + (r - 10) * cos(d_rad)
dy = cy - (r - 10) * sin(d_rad)
self.cv.create_line(cx, cy, dx, dy, fill='#e94560', width=3, arrow=tk.LAST)
# 中心太极点
self.cv.create_oval(cx - 8, cy - 8, cx + 8, cy + 8, fill='#fff', outline='#000')
self.cv.create_text(cx, cy, text="太极", font=self.fs, fill='#000')
def update(self):
if not self.run:
self.root.after(1000, self.update)
return
try:
now = datetime.now()
d = self.calc.daily(now)
y = self.calc.yearly(now)
# 一日系统显示(增强版)
self.dt.delete(1.0, tk.END)
self.dt.insert(tk.END, "【一日系统·昼夜六十四度】\n", "t")
self.dt.insert(tk.END, f"{d['gua']}度", "g")
self.dt.insert(tk.END, f" 第{d['num']:02d}度 {d['degree_start']}-{d['degree_end']}\n\n")
self.dt.insert(tk.END, f"{d['title']}\n", "t")
self.dt.insert(tk.END, f"{d['desc']}\n\n")
# 八刻详细信息
self.dt.insert(tk.END, f"【八刻】{d['ke_name']}({d['ke_fangwei']}·五行属{d['wx']})\n", "t")
self.dt.insert(tk.END, f" 刻时:{d['ke_range']} {d['ke_desc']}\n")
# 四时信息
self.dt.insert(tk.END, f"【四时】{d['sishi']}({d['sishi_sixiang']}·{d['sishi_desc']})\n", "t")
self.dt.insert(tk.END, f"圆环:{d['circle']:.2f}° 进度:{d['prog'] * 100:.1f}%\n")
self.dt.insert(tk.END,
f"当前:{now.strftime('%H:%M:%S')} 下一度:{d['next'].strftime('%H:%M:%S')} 剩余:{str(d['remain']).split('.')[0]}\n\n")
self.dt.insert(tk.END, d['detail'], "d")
# 岁序系统显示(增强版)
self.yt.delete(1.0, tk.END)
self.yt.insert(tk.END, "【岁序系统·六十四卦气】\n", "t")
self.yt.insert(tk.END, f"{y['gua']}气", "g")
self.yt.insert(tk.END, f" 第{y['num']:02d}气\n\n")
self.yt.insert(tk.END, f"{y['title']}\n", "t")
self.yt.insert(tk.END, f"{y['desc']}\n\n")
# 八节详细信息
self.yt.insert(tk.END, f"【八节】{y['jie']}({y['jie_gua']}卦·{y['jie_fangwei']}·五行{y['wx']})\n", "t")
self.yt.insert(tk.END, f" 气象:{y['jie_qixiang']} 天环中点:{y['jie_angle']}°\n")
self.yt.insert(tk.END, f" 统摄:第{y['jie_range'][0]}-{y['jie_range'][1]}气 {y['jie_range'][2]}\n")
# 四季信息
self.yt.insert(tk.END, f"【四季】{y['season']}({y['season_sixiang']}·{y['season_desc']})\n", "t")
# 天文信息
self.yt.insert(tk.END,
f"立春:{y['lichun'].strftime('%Y-%m-%d %H:%M')} 黄经:{y['sun']:.3f}°\n")
self.yt.insert(tk.END, f"圆环:{y['circle']:.2f}° 进度:{y['prog'] * 100:.1f}%\n\n")
# 如果有天文特征,显示
if y['astro_info']:
self.yt.insert(tk.END, f"【天文特征】{y['astro_info']['feature']}\n", "t")
self.yt.insert(tk.END, f"太阳黄经:{y['astro_info']['sun_range']}\n")
self.yt.insert(tk.END, f"气候意义:{y['astro_info']['climate']}\n")
self.yt.insert(tk.END, f"节气关联:{y['astro_info']['solar_term']}\n\n")
self.yt.insert(tk.END, y['detail'], "d")
self.draw(d['circle'], y['circle'])
self.st.config(text=f"{now.strftime('%Y-%m-%d %H:%M:%S')} | 丙午定本·方案B·内置200年数据")
except Exception as e:
print(f"更新显示错误: {e}")
self.st.config(text=f"错误: {str(e)[:50]}")
self.root.after(1000, self.update)
def copy_all(self):
"""复制全部信息到剪贴板"""
try:
now = datetime.now()
d = self.calc.daily(now)
y = self.calc.yearly(now)
text = f"""═══════════════════════════════════════════════════════════════
卦气正元历 · 丙午定本 · 方案B(太阳黄经驱动)
═══════════════════════════════════════════════════════════════
导出时间:{now.strftime('%Y年%m月%d日 %H时%M分%S秒')}
【无极·万化之源】
{self.calc.get_wuji_info()['desc']}
【太极·岁序之根】
{self.calc.get_taiji_info()['desc']}
【寒暑·一岁之纲】
{self.calc.get_hanshu_info()['desc']}
────────────────────────────────────────────────────────────
【一日系统 · 昼夜六十四度】
第{d['num']:02d}度 · {d['gua']}度 · {d['degree_start']}-{d['degree_end']}
{d['title']} · {d['desc']}
八 刻:{d['ke_name']}({d['ke_fangwei']}·五行{d['wx']})
刻 时:{d['ke_range']} {d['ke_desc']}
四 时:{d['sishi']}({d['sishi_sixiang']}·{d['sishi_desc']})
圆 环:{d['circle']:.2f}° 进度:{d['prog'] * 100:.1f}%
当前时间:{now.strftime('%H:%M:%S')}
下一度:{d['next'].strftime('%H:%M:%S')}
剩 余:{str(d['remain']).split('.')[0]}
【卦辞详解】
{d['detail']}
────────────────────────────────────────────────────────────
【岁序系统 · 六十四卦气】
第{y['num']:02d}气 · {y['gua']}气
{y['title']} · {y['desc']}
八 节:{y['jie']}({y['jie_gua']}卦·{y['jie_fangwei']}·五行{y['wx']})
气 象:{y['jie_qixiang']} 天环中点:{y['jie_angle']}°
统 摄:第{y['jie_range'][0]}-{y['jie_range'][1]}气 {y['jie_range'][2]}
四 季:{y['season']}({y['season_sixiang']}·{y['season_desc']})
年 度:{y['year']}年(立春{y['lichun'].strftime('%Y-%m-%d %H:%M')})
太阳黄经:{y['sun']:.3f}° 圆环:{y['circle']:.2f}° 进度:{y['prog'] * 100:.1f}%
"""
# 如果有天文特征,添加
if y['astro_info']:
text += f"""
【天文特征】
太阳黄经:{y['astro_info']['sun_range']}
气候意义:{y['astro_info']['climate']}
节气关联:{y['astro_info']['solar_term']}
"""
text += f"""
【卦辞详解】
{y['detail']}
═══════════════════════════════════════════════════════════════
综合卦象:{y['gua']}之{d['gua']}(岁序为本,一日为用)
═══════════════════════════════════════════════════════════════"""
self.root.clipboard_clear()
self.root.clipboard_append(text)
self.st.config(text="✓ 已复制全部信息到剪贴板", fg='#4aa')
self.root.after(2000,
lambda: self.st.config(text=f"{now.strftime('%Y-%m-%d %H:%M:%S')} | 丙午定本·方案B", fg='#666'))
except Exception as e:
messagebox.showerror("错误", f"复制失败: {e}")
def toggle(self):
self.run = not self.run
if self.run:
self.update()
def show_wuji(self):
"""显示无极信息"""
w = tk.Toplevel(self.root)
w.title("无极——万化之源")
w.geometry("500x300")
w.configure(bg='#111')
t = tk.Text(w, bg='#111', fg='#ccc', font=self.fm, wrap=tk.WORD, padx=20, pady=20)
t.pack(fill=tk.BOTH, expand=True)
info = self.calc.get_wuji_info()
t.insert(tk.END, info['title'] + "\n\n", "title")
t.insert(tk.END, info['desc'])
t.tag_config("title", foreground="#e94560", font=self.fb)
t.config(state=tk.DISABLED)
def show_taiji(self):
"""显示太极信息"""
w = tk.Toplevel(self.root)
w.title("太极——岁序之根")
w.geometry("500x300")
w.configure(bg='#111')
t = tk.Text(w, bg='#111', fg='#ccc', font=self.fm, wrap=tk.WORD, padx=20, pady=20)
t.pack(fill=tk.BOTH, expand=True)
info = self.calc.get_taiji_info()
t.insert(tk.END, info['title'] + "\n\n", "title")
t.insert(tk.END, info['desc'])
t.tag_config("title", foreground="#4aa", font=self.fb)
t.config(state=tk.DISABLED)
def show_hanshu(self):
"""显示寒暑信息"""
w = tk.Toplevel(self.root)
w.title("寒暑——一岁之纲")
w.geometry("500x300")
w.configure(bg='#111')
t = tk.Text(w, bg='#111', fg='#ccc', font=self.fm, wrap=tk.WORD, padx=20, pady=20)
t.pack(fill=tk.BOTH, expand=True)
info = self.calc.get_hanshu_info()
t.insert(tk.END, info['title'] + "\n\n", "title")
t.insert(tk.END, info['desc'])
t.tag_config("title", foreground="#e94560", font=self.fb)
t.config(state=tk.DISABLED)
def birth(self):
s = simpledialog.askstring("生日", "格式:1990-01-01 12:00", initialvalue="1990-01-01 12:00")
if not s:
return
try:
dt = datetime.strptime(s, "%Y-%m-%d %H:%M")
c = self.calc.birth(dt)
w = tk.Toplevel(self.root)
w.title("命盘")
w.geometry("600x500")
w.configure(bg='#111')
t = tk.Text(w, bg='#111', fg='#ccc', font=self.fm, wrap=tk.WORD, padx=15, pady=15)
t.pack(fill=tk.BOTH, expand=True)
t.insert(tk.END, f"出生时间:{dt.strftime('%Y年%m月%d日 %H时%M分')}\n\n")
t.insert(tk.END, "【岁序本命】\n", "title1")
t.insert(tk.END, f"第{c['y']['num']:02d}气 · {c['y']['gua']}气 {c['y']['title']}\n")
t.insert(tk.END, f"八节:{c['y']['jie']}({c['y']['jie_gua']}卦·{c['y']['jie_fangwei']})\n")
t.insert(tk.END, f"四季:{c['y']['season']}({c['y']['season_sixiang']})\n\n")
t.insert(tk.END, "【一日本命】\n", "title2")
t.insert(tk.END, f"第{c['d']['num']:02d}度 · {c['d']['gua']}度 {c['d']['title']}\n")
t.insert(tk.END, f"八刻:{c['d']['ke_name']}({c['d']['ke_fangwei']}·{c['d']['sishi']})\n")
t.insert(tk.END, f"时刻:{c['d']['degree_start']}-{c['d']['degree_end']}\n\n")
t.insert(tk.END, f"综合卦象:{c['comp']}\n\n")
t.insert(tk.END, "【岁序详解】\n", "title1")
t.insert(tk.END, c['y']['detail'] + "\n\n")
t.insert(tk.END, "【一日详解】\n", "title2")
t.insert(tk.END, c['d']['detail'])
t.tag_config("title1", foreground="#4aa", font=self.fb)
t.tag_config("title2", foreground="#e94560", font=self.fb)
t.config(state=tk.DISABLED)
except Exception as e:
messagebox.showerror("错误", str(e))
def year(self):
y = simpledialog.askinteger("年份", "请输入年份(1900-2100):",
initialvalue=datetime.now().year,
minvalue=1900, maxvalue=2100)
if not y:
return
w = tk.Toplevel(self.root)
w.title(f"{y}年卦气表")
w.geometry("650x650")
w.configure(bg='#111')
frame = tk.Frame(w, bg='#111')
frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
tr = ttk.Treeview(frame, columns=('q', 'g', 'j', 'jg', 't'), show='headings', height=30)
tr.heading('q', text='气序')
tr.heading('g', text='卦名')
tr.heading('j', text='八节')
tr.heading('jg', text='八节卦')
tr.heading('t', text='起始时刻')
tr.column('q', width=50, anchor='center')
tr.column('g', width=70, anchor='center')
tr.column('j', width=60, anchor='center')
tr.column('jg', width=70, anchor='center')
tr.column('t', width=200, anchor='center')
# 设置Treeview样式
style = ttk.Style()
style.configure("Treeview", background='#222', foreground='#fff',
fieldbackground='#222', font=self.fs)
style.configure("Treeview.Heading", background='#333', foreground='#fff', font=self.fb)
sb = ttk.Scrollbar(frame, orient=tk.VERTICAL, command=tr.yview)
tr.configure(yscrollcommand=sb.set)
tr.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
sb.pack(side=tk.RIGHT, fill=tk.Y)
for it in self.calc.year_table(y):
tr.insert('', tk.END, values=(
f"{it['qi']:02d}",
it['gua'] + '气',
it['jie'],
it['jie_gua'],
it['time'].strftime('%Y-%m-%d %H:%M')
))
def detail(self):
w = tk.Toplevel(self.root)
w.title("卦辞详解")
w.geometry("750x650")
w.configure(bg='#111')
nb = ttk.Notebook(w)
nb.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
for name, data, color in [("一日系统", GUA_DAILY_FULL, '#e94560'),
("岁序系统", GUA_YEAR_FULL, '#4aa')]:
f = tk.Frame(nb, bg='#111')
nb.add(f, text=name)
text_frame = tk.Frame(f, bg='#111')
text_frame.pack(fill=tk.BOTH, expand=True)
txt = tk.Text(text_frame, bg='#111', fg='#ccc', font=self.fm,
wrap=tk.WORD, padx=15, pady=15)
sb = ttk.Scrollbar(text_frame, orient=tk.VERTICAL, command=txt.yview)
txt.configure(yscrollcommand=sb.set)
txt.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
sb.pack(side=tk.RIGHT, fill=tk.Y)
for i, gua in enumerate(GUA_SEQUENCE):
title, desc, detail = data.get(gua, ("", "", ""))
txt.insert(tk.END, f"\n{'═' * 60}\n")
txt.insert(tk.END,
f"第{i + 1:02d} {'度' if '一日' in name else '气'} · {gua}{'度' if '一日' in name else '气'}\n",
'title')
txt.insert(tk.END, f"【{title}】{desc}\n\n")
txt.insert(tk.END, f"{detail}\n")
txt.tag_config('title', foreground=color, font=self.fb)
txt.config(state=tk.DISABLED)
def export(self):
fn = f"guaqi_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
d = self.calc.daily()
y = self.calc.yearly()
with open(fn, 'w', encoding='utf-8') as f:
f.write(f"卦气正元历导出\n{'=' * 50}\n")
f.write(f"时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
f.write("[无极]\n")
f.write(f"{self.calc.get_wuji_info()['desc']}\n\n")
f.write("[太极]\n")
f.write(f"{self.calc.get_taiji_info()['desc']}\n\n")
f.write("[寒暑]\n")
f.write(f"{self.calc.get_hanshu_info()['desc']}\n\n")
f.write(f"[一日系统·第{d['num']:02d}{d['gua']}度]\n")
f.write(f"时间:{d['degree_start']}-{d['degree_end']}\n")
f.write(f"八刻:{d['ke_name']}({d['ke_fangwei']})\n")
f.write(f"四时:{d['sishi']}\n")
f.write(f"{d['title']}\n{d['desc']}\n\n{d['detail']}\n\n")
f.write(f"[岁序系统·第{y['num']:02d}{y['gua']}气]\n")
f.write(f"八节:{y['jie']}({y['jie_gua']}卦·{y['jie_fangwei']})\n")
f.write(f"四季:{y['season']}\n")
f.write(f"{y['title']}\n{y['desc']}\n\n{y['detail']}\n")
messagebox.showinfo("导出成功", f"已保存至:{fn}")
def about(self):
about_text = """卦气正元历 · 丙午定本 · 完整版
方案B:太阳黄经驱动(非平均天数)
内置:1900-2100年立春精确时刻
算法:VSOP87行星理论简化版
精度:±0.5°(足够64等分)
【理论体系】
无极 → 太极 → 寒暑 → 四季 → 八节 → 六十四气(岁序)
无极 → 太极 → 昼夜 → 四时 → 八刻 → 六十四度(一日)
【核心模型】
• 360°圆环宇宙模型
• 后天八卦顺时针旋转
• 洛书方位:上离下坎、左震右兑
【特点】
• 一日64度 × 22.5分钟 = 24小时
• 一年64气 × 5.625°黄经 = 360°
• 坎至履卦序贯通双系统
• 全部64卦完整卦辞详解
• 八刻四时完整对应
• 八节四季完整体系
• 一键复制全部信息
• 零外部依赖 · 开箱即用
原创易理时序体系,专主一日及一年岁时统摄。
仅供国学文化研究、学术探讨、个人娱乐参考。"""
messagebox.showinfo("关于卦气正元历", about_text)
def main():
root = tk.Tk()
try:
from ctypes import windll
windll.shcore.SetProcessDpiAwareness(1)
except:
pass
App(root)
root.mainloop()
if __name__ == "__main__":
main()
更多推荐
所有评论(0)