python语言基于sxtwl库的五柱十字干支万年历软件代码新QZQ
·
# -*- coding: utf-8 -*-
"""
五柱十字干支万年历 v1.0
基于 sxtwl 库精确计算,修正刻柱算法
支持公元0年 - 9999年(1900-2100年精确节气)
"""
import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
from datetime import datetime, timedelta
import pytz
from itertools import cycle, repeat
try:
from sxtwl import fromSolar
import sxtwl
SXTWL_AVAILABLE = True
except ImportError:
SXTWL_AVAILABLE = False
# ==================== 常量(同上,省略)====================
tian_gan = '甲乙丙丁戊己庚辛壬癸'
di_zhi = '子丑寅卯辰巳午未申酉戌亥'
jqmc = ['小寒', '大寒', '立春', '雨水', '惊蛰', '春分', '清明', '谷雨',
'立夏', '小满', '芒种', '夏至', '小暑', '大暑', '立秋', '处暑',
'白露', '秋分', '寒露', '霜降', '立冬', '小雪', '大雪', '冬至']
lunar_m = ['占位', '正月', '二月', '三月', '四月', '五月', '六月',
'七月', '八月', '九月', '十月', '冬月', '腊月']
jieqi_to_dizhi = {
'立春': '寅', '雨水': '寅', '惊蛰': '卯', '春分': '卯', '清明': '辰', '谷雨': '辰',
'立夏': '巳', '小满': '巳', '芒种': '午', '夏至': '午', '小暑': '未', '大暑': '未',
'立秋': '申', '处暑': '申', '白露': '酉', '秋分': '酉', '寒露': '戌', '霜降': '戌',
'立冬': '亥', '小雪': '亥', '大雪': '子', '冬至': '子', '小寒': '丑', '大寒': '丑'
}
fivetigers = {
tuple(list('甲己')): '丙寅', tuple(list('乙庚')): '戊寅', tuple(list('丙辛')): '庚寅',
tuple(list('丁壬')): '壬寅', tuple(list('戊癸')): '甲寅'
}
fiverats = {
tuple(list('甲己')): '甲子', tuple(list('乙庚')): '丙子', tuple(list('丙辛')): '戊子',
tuple(list('丁壬')): '庚子', tuple(list('戊癸')): '壬子'
}
fivehourses = {
tuple(list('丙辛')): '甲午', tuple(list('丁壬')): '丙午', tuple(list('戊癸')): '戊午',
tuple(list('甲己')): '庚午', tuple(list('乙庚')): '壬午'
}
nayin_dict = {
'甲子': '海中金', '乙丑': '海中金', '丙寅': '炉中火', '丁卯': '炉中火', '戊辰': '大林木', '己巳': '大林木',
'庚午': '路旁土', '辛未': '路旁土', '壬申': '剑锋金', '癸酉': '剑锋金', '甲戌': '山头火', '乙亥': '山头火',
'丙子': '涧下水', '丁丑': '涧下水', '戊寅': '城头土', '己卯': '城头土', '庚辰': '白蜡金', '辛巳': '白蜡金',
'壬午': '杨柳木', '癸未': '杨柳木', '甲申': '泉中水', '乙酉': '泉中水', '丙戌': '屋上土', '丁亥': '屋上土',
'戊子': '霹雳火', '己丑': '霹雳火', '庚寅': '松柏木', '辛卯': '松柏木', '壬辰': '长流水', '癸巳': '长流水',
'甲午': '沙中金', '乙未': '沙中金', '丙申': '山下火', '丁酉': '山下火', '戊戌': '平地木', '己亥': '平地木',
'庚子': '壁上土', '辛丑': '壁上土', '壬寅': '金箔金', '癸卯': '金箔金', '甲辰': '佛灯火', '乙巳': '佛灯火',
'丙午': '天河水', '丁未': '天河水', '戊申': '大驿土', '己酉': '大驿土', '庚戌': '钗钏金', '辛亥': '钗钏金',
'壬子': '桑柘木', '癸丑': '桑柘木', '甲寅': '大溪水', '乙卯': '大溪水', '丙辰': '沙中土', '丁巳': '沙中土',
'戊午': '天上火', '己未': '天上火', '庚申': '石榴木', '辛酉': '石榴木', '壬戌': '大海水', '癸亥': '大海水'
}
xunshou_dict = {
'甲子': '甲子', '乙丑': '甲子', '丙寅': '甲子', '丁卯': '甲子', '戊辰': '甲子', '己巳': '甲子', '庚午': '甲子', '辛未': '甲子', '壬申': '甲子', '癸酉': '甲子',
'甲戌': '甲戌', '乙亥': '甲戌', '丙子': '甲戌', '丁丑': '甲戌', '戊寅': '甲戌', '己卯': '甲戌', '庚辰': '甲戌', '辛巳': '甲戌', '壬午': '甲戌', '癸未': '甲戌',
'甲申': '甲申', '乙酉': '甲申', '丙戌': '甲申', '丁亥': '甲申', '戊子': '甲申', '己丑': '甲申', '庚寅': '甲申', '辛卯': '甲申', '壬辰': '甲申', '癸巳': '甲申',
'甲午': '甲午', '乙未': '甲午', '丙申': '甲午', '丁酉': '甲午', '戊戌': '甲午', '己亥': '甲午', '庚子': '甲午', '辛丑': '甲午', '壬寅': '甲午', '癸卯': '甲午',
'甲辰': '甲辰', '乙巳': '甲辰', '丙午': '甲辰', '丁未': '甲辰', '戊申': '甲辰', '己酉': '甲辰', '庚戌': '甲辰', '辛亥': '甲辰', '壬子': '甲辰', '癸丑': '甲辰',
'甲寅': '甲寅', '乙卯': '甲寅', '丙辰': '甲寅', '丁巳': '甲寅', '戊午': '甲寅', '己未': '甲寅', '庚申': '甲寅', '辛酉': '甲寅', '壬戌': '甲寅', '癸亥': '甲寅'
}
# ==================== 辅助函数 ====================
def jiazi():
return list(map(lambda x: "{}{}".format(tian_gan[x % 10], di_zhi[x % 12]), list(range(60))))
def multi_key_dict_get(d, k):
for keys, v in d.items():
if k in keys:
return v
return None
def new_list(olist, o):
a = olist.index(o)
return olist[a:] + olist[:a]
def repeat_list(n, thelist):
return [repetition for i in thelist for repetition in repeat(i, n)]
# ==================== 节气计算(同上,省略)====================
_JIEQI_CACHE = {}
def get_jieqi_start_date(year, month, day, hour, minute):
current_datetime = datetime(year, month, day, hour, minute)
cache_key = (year, month, day, hour // 4)
if cache_key in _JIEQI_CACHE:
cached = _JIEQI_CACHE[cache_key]
if (current_datetime - cached["cache_time"]).seconds < 86400:
return cached["result"].copy()
if 1900 <= year <= 2100 and SXTWL_AVAILABLE:
try:
day_obj = fromSolar(year, month, day)
if day_obj.hasJieQi():
jq_index = day_obj.getJieQi()
jd = day_obj.getJieQiJD()
t = sxtwl.JD2DD(jd)
result = {"年": t.Y, "月": t.M, "日": t.D, "时": int(t.h), "分": round(t.m),
"节气": jqmc[jq_index - 1], "时间": datetime(t.Y, t.M, t.D, int(t.h), round(t.m))}
_JIEQI_CACHE[cache_key] = {"result": result, "cache_time": current_datetime}
return result.copy()
else:
current_day = day_obj
for _ in range(15):
current_day = current_day.before(1)
if current_day.hasJieQi():
jq_index = current_day.getJieQi()
jd = current_day.getJieQiJD()
t = sxtwl.JD2DD(jd)
result = {"年": t.Y, "月": t.M, "日": t.D, "时": int(t.h), "分": round(t.m),
"节气": jqmc[jq_index - 1], "时间": datetime(t.Y, t.M, t.D, int(t.h), round(t.m))}
_JIEQI_CACHE[cache_key] = {"result": result, "cache_time": current_datetime}
return result.copy()
except:
pass
jieqi_table = [(1, 5, '小寒'), (1, 20, '大寒'), (2, 4, '立春'), (2, 19, '雨水'),
(3, 5, '惊蛰'), (3, 20, '春分'), (4, 4, '清明'), (4, 20, '谷雨'),
(5, 5, '立夏'), (5, 21, '小满'), (6, 5, '芒种'), (6, 21, '夏至'),
(7, 7, '小暑'), (7, 23, '大暑'), (8, 7, '立秋'), (8, 23, '处暑'),
(9, 7, '白露'), (9, 23, '秋分'), (10, 8, '寒露'), (10, 23, '霜降'),
(11, 7, '立冬'), (11, 22, '小雪'), (12, 7, '大雪'), (12, 21, '冬至')]
jieqi = '冬至'
jieqi_date = None
for m, d, name in jieqi_table:
if m < month or (m == month and d <= day):
jieqi = name
jieqi_date = datetime(year, m, d, 0, 0)
else:
break
if jieqi_date is None:
jieqi_date = current_datetime
result = {"年": year, "月": jieqi_date.month, "日": jieqi_date.day,
"时": 0, "分": 0, "节气": jieqi, "时间": jieqi_date}
_JIEQI_CACHE[cache_key] = {"result": result, "cache_time": current_datetime}
return result.copy()
def get_next_jieqi_start_date(year, month, day, hour, minute):
current_datetime = datetime(year, month, day, hour, minute)
cache_key = (year, month, day, hour // 4, 'next')
if cache_key in _JIEQI_CACHE:
cached = _JIEQI_CACHE[cache_key]
if (current_datetime - cached["cache_time"]).seconds < 86400:
return cached["result"].copy()
if 1900 <= year <= 2100 and SXTWL_AVAILABLE:
try:
day_obj = fromSolar(year, month, day)
current_day = day_obj.after(1)
while True:
if current_day.hasJieQi():
jq_index = current_day.getJieQi()
jd = current_day.getJieQiJD()
t = sxtwl.JD2DD(jd)
result = {"年": t.Y, "月": t.M, "日": t.D, "时": int(t.h), "分": round(t.m),
"节气": jqmc[jq_index - 1], "时间": datetime(t.Y, t.M, t.D, int(t.h), round(t.m))}
_JIEQI_CACHE[cache_key] = {"result": result, "cache_time": current_datetime}
return result.copy()
current_day = current_day.after(1)
except:
pass
jieqi_table = [(1, 5, '小寒'), (1, 20, '大寒'), (2, 4, '立春'), (2, 19, '雨水'),
(3, 5, '惊蛰'), (3, 20, '春分'), (4, 4, '清明'), (4, 20, '谷雨'),
(5, 5, '立夏'), (5, 21, '小满'), (6, 5, '芒种'), (6, 21, '夏至'),
(7, 7, '小暑'), (7, 23, '大暑'), (8, 7, '立秋'), (8, 23, '处暑'),
(9, 7, '白露'), (9, 23, '秋分'), (10, 8, '寒露'), (10, 23, '霜降'),
(11, 7, '立冬'), (11, 22, '小雪'), (12, 7, '大雪'), (12, 21, '冬至')]
for m, d, name in jieqi_table:
if m > month or (m == month and d > day):
next_date = datetime(year, m, d, 0, 0)
result = {"年": year, "月": m, "日": d, "时": 0, "分": 0,
"节气": name, "时间": next_date}
_JIEQI_CACHE[cache_key] = {"result": result, "cache_time": current_datetime}
return result.copy()
m, d, name = jieqi_table[0]
next_date = datetime(year + 1, m, d, 0, 0)
result = {"年": year + 1, "月": m, "日": d, "时": 0, "分": 0,
"节气": name, "时间": next_date}
_JIEQI_CACHE[cache_key] = {"result": result, "cache_time": current_datetime}
return result.copy()
def jq(year, month, day, hour, minute):
try:
current_datetime = datetime(year, month, day, hour, minute)
jq_start_dict = get_jieqi_start_date(year, month, day, hour, minute)
next_jq_start_dict = get_next_jieqi_start_date(year, month, day, hour, minute)
if not jq_start_dict or not next_jq_start_dict:
month_map = {1: '小寒', 2: '立春', 3: '惊蛰', 4: '清明',
5: '立夏', 6: '芒种', 7: '小暑', 8: '立秋',
9: '白露', 10: '寒露', 11: '立冬', 12: '大雪'}
return month_map.get(month, '冬至')
jq_start_datetime = jq_start_dict["时间"]
next_jq_start_datetime = next_jq_start_dict["时间"]
jq_name = jq_start_dict["节气"]
if jq_start_datetime <= current_datetime < next_jq_start_datetime:
return jq_name
elif current_datetime < jq_start_datetime:
return jq_name
else:
return jq_name
except Exception:
month_map = {1: '小寒', 2: '立春', 3: '惊蛰', 4: '清明',
5: '立夏', 6: '芒种', 7: '小暑', 8: '立秋',
9: '白露', 10: '寒露', 11: '立冬', 12: '大雪'}
return month_map.get(month, '冬至')
def lunar_date_d(year, month, day):
if SXTWL_AVAILABLE:
try:
day_obj = fromSolar(year, month, day)
return {"年": day_obj.getLunarYear(), "農曆月": lunar_m[int(day_obj.getLunarMonth())],
"月": day_obj.getLunarMonth(), "日": day_obj.getLunarDay()}
except:
pass
return {"年": year, "農曆月": "未知", "月": month, "日": day}
# ==================== 五柱核心计算 ====================
def find_lunar_month(year_gz):
result = multi_key_dict_get(fivetigers, year_gz[0])
if result is None:
result = multi_key_dict_get(fivetigers, year_gz[1])
return dict(zip(range(1, 13), new_list(jiazi(), result)[:12]))
def find_lunar_hour(day_gz):
result = multi_key_dict_get(fiverats, day_gz[0])
if result is None:
result = multi_key_dict_get(fiverats, day_gz[1])
return dict(zip(list(di_zhi), new_list(jiazi(), result)[:12]))
def find_lunar_ke(hour_gz):
result = multi_key_dict_get(fivehourses, hour_gz[0])
if result is None:
result = multi_key_dict_get(fivehourses, hour_gz[1])
return new_list(jiazi(), result)
def ke_jiazi_d(zi_hour_gz):
t = [f"{h}:{m}0" for h in range(24) for m in range(6)]
zi_ke = find_lunar_ke(zi_hour_gz)
minutelist = dict(zip(t, cycle(repeat_list(1, zi_ke))))
return minutelist
def get_month_ganzhi_by_jieqi(year, month, day, hour, minute, year_ganzhi):
current_jq = jq(year, month, day, hour, minute)
month_dizhi = jieqi_to_dizhi.get(current_jq, '寅')
year_gan = year_ganzhi[0]
start_gan = multi_key_dict_get(fivetigers, year_gan)
if start_gan is None:
start_gan = multi_key_dict_get(fivetigers, year_ganzhi[1])
start_gan = start_gan[0] if start_gan else '丙'
dizhi_order = ['寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥', '子', '丑']
gan_order = list(tian_gan)
start_idx = dizhi_order.index('寅')
current_idx = dizhi_order.index(month_dizhi)
offset = current_idx - start_idx
start_gan_idx = gan_order.index(start_gan)
month_gan = gan_order[(start_gan_idx + offset) % 10]
return f"{month_gan}{month_dizhi}"
def gangzhi(year, month, day, hour, minute):
if not SXTWL_AVAILABLE:
raise ImportError("sxtwl 库未安装")
cdate = fromSolar(year, month, day)
ygz = cdate.getYearGZ()
yTG = "{}{}".format(tian_gan[ygz.tg], di_zhi[ygz.dz])
dgz = cdate.getDayGZ()
dTG = "{}{}".format(tian_gan[dgz.tg], di_zhi[dgz.dz])
hTG_raw = cdate.getHourGZ(hour)
hTG = "{}{}".format(tian_gan[hTG_raw.tg], di_zhi[hTG_raw.dz])
mTG = get_month_ganzhi_by_jieqi(year, month, day, hour, minute, yTG)
# 刻柱:用子时时柱为起点
zi_hTG_raw = cdate.getHourGZ(0)
zi_hTG = "{}{}".format(tian_gan[zi_hTG_raw.tg], di_zhi[zi_hTG_raw.dz])
ke_dict = ke_jiazi_d(zi_hTG)
m = minute // 10
key = f"{hour}:{m}0"
ke_gz = ke_dict.get(key, '未知')
return [yTG, mTG, dTG, hTG, ke_gz]
# ==================== GUI - 移动端优化版 ====================
class WuzhuGUI:
def __init__(self, root):
self.root = root
self.root.title("五柱十字万年历 v3.2")
self.root.geometry("900x800") # 稍微加高,容纳更多按钮
self.setup_styles()
self.create_ui()
self.show_current()
def setup_styles(self):
style = ttk.Style()
style.theme_use('clam')
style.configure('Title.TLabelframe', font=('微软雅黑', 10, 'bold'))
style.configure('Title.TLabelframe.Label', font=('微软雅黑', 10, 'bold'))
# 增大按钮字体,方便触屏点击
style.configure('TButton', font=('微软雅黑', 12))
style.configure('Big.TButton', font=('微软雅黑', 14, 'bold'))
def create_ui(self):
main_frame = ttk.Frame(self.root, padding="10")
main_frame.pack(fill=tk.BOTH, expand=True)
# ========== 输入面板 ==========
input_frame = ttk.LabelFrame(main_frame, text="时间输入(点击框可弹出键盘)",
padding="10", style='Title.TLabelframe')
input_frame.pack(fill=tk.X, pady=(0, 10))
# === 年月日:用Entry代替Spinbox,并绑定焦点事件 ===
date_frame = ttk.Frame(input_frame)
date_frame.pack(pady=5)
# 年
ttk.Label(date_frame, text="年:", font=('微软雅黑', 12)).pack(side=tk.LEFT, padx=5)
self.year_var = tk.StringVar(value=str(datetime.now().year))
self.year_entry = tk.Entry(date_frame, textvariable=self.year_var,
width=6, font=('微软雅黑', 14), justify='center')
self.year_entry.pack(side=tk.LEFT, padx=5)
self.year_entry.bind('<FocusIn>', lambda e: self.on_entry_focus(e))
# 快速年份按钮
year_btn_frame = ttk.Frame(date_frame)
year_btn_frame.pack(side=tk.LEFT, padx=5)
ttk.Button(year_btn_frame, text="-", width=2, command=lambda: self.adjust_year(-1)).pack(side=tk.LEFT)
ttk.Button(year_btn_frame, text="+", width=2, command=lambda: self.adjust_year(1)).pack(side=tk.LEFT)
# 月
ttk.Label(date_frame, text="月:", font=('微软雅黑', 12)).pack(side=tk.LEFT, padx=5)
self.month_var = tk.StringVar(value=str(datetime.now().month))
self.month_entry = tk.Entry(date_frame, textvariable=self.month_var,
width=4, font=('微软雅黑', 14), justify='center')
self.month_entry.pack(side=tk.LEFT, padx=5)
self.month_entry.bind('<FocusIn>', lambda e: self.on_entry_focus(e))
month_btn_frame = ttk.Frame(date_frame)
month_btn_frame.pack(side=tk.LEFT, padx=5)
ttk.Button(month_btn_frame, text="-", width=2, command=lambda: self.adjust_month(-1)).pack(side=tk.LEFT)
ttk.Button(month_btn_frame, text="+", width=2, command=lambda: self.adjust_month(1)).pack(side=tk.LEFT)
# 日
ttk.Label(date_frame, text="日:", font=('微软雅黑', 12)).pack(side=tk.LEFT, padx=5)
self.day_var = tk.StringVar(value=str(datetime.now().day))
self.day_entry = tk.Entry(date_frame, textvariable=self.day_var,
width=4, font=('微软雅黑', 14), justify='center')
self.day_entry.pack(side=tk.LEFT, padx=5)
self.day_entry.bind('<FocusIn>', lambda e: self.on_entry_focus(e))
day_btn_frame = ttk.Frame(date_frame)
day_btn_frame.pack(side=tk.LEFT, padx=5)
ttk.Button(day_btn_frame, text="-", width=2, command=lambda: self.adjust_day(-1)).pack(side=tk.LEFT)
ttk.Button(day_btn_frame, text="+", width=2, command=lambda: self.adjust_day(1)).pack(side=tk.LEFT)
# === 时分:同样用Entry ===
time_frame = ttk.Frame(input_frame)
time_frame.pack(pady=5)
ttk.Label(time_frame, text="时:", font=('微软雅黑', 12)).pack(side=tk.LEFT, padx=5)
self.hour_var = tk.StringVar(value=f"{datetime.now().hour:02d}")
self.hour_entry = tk.Entry(time_frame, textvariable=self.hour_var,
width=4, font=('微软雅黑', 14), justify='center')
self.hour_entry.pack(side=tk.LEFT, padx=5)
self.hour_entry.bind('<FocusIn>', lambda e: self.on_entry_focus(e))
hour_btn_frame = ttk.Frame(time_frame)
hour_btn_frame.pack(side=tk.LEFT, padx=5)
ttk.Button(hour_btn_frame, text="-", width=2, command=lambda: self.adjust_hour(-1)).pack(side=tk.LEFT)
ttk.Button(hour_btn_frame, text="+", width=2, command=lambda: self.adjust_hour(1)).pack(side=tk.LEFT)
ttk.Label(time_frame, text="分:", font=('微软雅黑', 12)).pack(side=tk.LEFT, padx=5)
self.minute_var = tk.StringVar(value=f"{datetime.now().minute:02d}")
self.minute_entry = tk.Entry(time_frame, textvariable=self.minute_var,
width=4, font=('微软雅黑', 14), justify='center')
self.minute_entry.pack(side=tk.LEFT, padx=5)
self.minute_entry.bind('<FocusIn>', lambda e: self.on_entry_focus(e))
minute_btn_frame = ttk.Frame(time_frame)
minute_btn_frame.pack(side=tk.LEFT, padx=5)
ttk.Button(minute_btn_frame, text="-", width=2, command=lambda: self.adjust_minute(-10)).pack(side=tk.LEFT)
ttk.Button(minute_btn_frame, text="+", width=2, command=lambda: self.adjust_minute(10)).pack(side=tk.LEFT)
# === 快速时间选择按钮(触屏友好)===
quick_frame = ttk.Frame(input_frame)
quick_frame.pack(pady=10)
ttk.Button(quick_frame, text="🕐 子时(23-1)", command=lambda: self.set_hour(0), width=12).pack(side=tk.LEFT, padx=2)
ttk.Button(quick_frame, text="🕕 午时(11-13)", command=lambda: self.set_hour(12), width=12).pack(side=tk.LEFT, padx=2)
ttk.Button(quick_frame, text="🕛 当前时间", command=self.show_current, width=12).pack(side=tk.LEFT, padx=2)
# === 主操作按钮 ===
btn_frame = ttk.Frame(input_frame)
btn_frame.pack(pady=10)
self.calc_btn = ttk.Button(btn_frame, text="▶ 开始排盘",
command=self.calculate, width=15, style='Big.TButton')
self.calc_btn.pack(side=tk.LEFT, padx=10)
self.clear_btn = ttk.Button(btn_frame, text="🗑 清空",
command=self.clear_result, width=10)
self.clear_btn.pack(side=tk.LEFT, padx=5)
# ========== 结果显示面板 ==========
result_frame = ttk.LabelFrame(main_frame, text="排盘结果",
padding="10", style='Title.TLabelframe')
result_frame.pack(fill=tk.BOTH, expand=True)
self.result_text = scrolledtext.ScrolledText(
result_frame, wrap=tk.WORD, font=('微软雅黑', 12),
width=80, height=25, bg='#f5f5f5'
)
self.result_text.pack(fill=tk.BOTH, expand=True)
self.result_text.tag_config('title', font=('微软雅黑', 16, 'bold'), foreground='#2c3e50')
self.result_text.tag_config('subtitle', font=('微软雅黑', 13, 'bold'), foreground='#34495e')
self.result_text.tag_config('ganzhi', font=('微软雅黑', 15, 'bold'), foreground='#c0392b')
self.result_text.tag_config('info', font=('微软雅黑', 11), foreground='#7f8c8d')
self.result_text.tag_config('correct', font=('微软雅黑', 11), foreground='#27ae60')
self.result_text.tag_config('big', font=('微软雅黑', 18, 'bold'), foreground='#8e44ad')
# ========== 焦点处理:强制弹出软键盘 ==========
def on_entry_focus(self, event):
"""Entry获得焦点时的处理"""
widget = event.widget
widget.selection_range(0, tk.END) # 全选文本,方便替换
# 在手机上,点击Entry通常会弹出键盘,但如果不行,可以尝试:
# 某些Python IDE需要额外的处理
# ========== 数值调整按钮 ==========
def adjust_year(self, delta):
try:
v = int(self.year_var.get()) + delta
self.year_var.set(str(v))
except:
pass
def adjust_month(self, delta):
try:
v = int(self.month_var.get()) + delta
if 1 <= v <= 12:
self.month_var.set(str(v))
except:
pass
def adjust_day(self, delta):
try:
v = int(self.day_var.get()) + delta
if 1 <= v <= 31:
self.day_var.set(str(v))
except:
pass
def adjust_hour(self, delta):
try:
v = int(self.hour_var.get()) + delta
v = v % 24
self.hour_var.set(f"{v:02d}")
except:
pass
def adjust_minute(self, delta):
try:
v = int(self.minute_var.get()) + delta
v = max(0, min(59, v))
self.minute_var.set(f"{v:02d}")
except:
pass
def set_hour(self, h):
"""快速设置小时"""
self.hour_var.set(f"{h:02d}")
self.minute_var.set("00")
# ========== 核心功能 ==========
def show_current(self):
now = datetime.now(pytz.timezone('Asia/Hong_Kong'))
self.year_var.set(str(now.year))
self.month_var.set(str(now.month))
self.day_var.set(str(now.day))
self.hour_var.set(f"{now.hour:02d}")
self.minute_var.set(f"{now.minute:02d}")
self.calculate()
def calculate(self):
try:
year = int(self.year_var.get())
month = int(self.month_var.get())
day = int(self.day_var.get())
hour = int(self.hour_var.get())
minute = int(self.minute_var.get())
if year < 0 or year > 9999:
messagebox.showerror("错误", f"年份必须在0-9999之间")
return
try:
datetime(year, month, day)
except ValueError:
messagebox.showerror("错误", f"日期无效:{year}-{month}-{day}")
return
gz = gangzhi(year, month, day, hour, minute)
current_jq = jq(year, month, day, hour, minute)
jq_info = get_jieqi_start_date(year, month, day, hour, minute)
next_jq_info = get_next_jieqi_start_date(year, month, day, hour, minute)
lunar = lunar_date_d(year, month, day)
self.display_result(year, month, day, hour, minute, gz, current_jq, jq_info, next_jq_info, lunar)
except ImportError as e:
messagebox.showerror("错误", str(e) + "\n请安装sxtwl库:pip install sxtwl")
except Exception as e:
messagebox.showerror("错误", f"排盘失败:{str(e)}")
def display_result(self, year, month, day, hour, minute, gz, current_jq, jq_info, next_jq_info, lunar):
self.result_text.delete(1.0, tk.END)
self.result_text.insert(tk.END, "=" * 50 + "\n", 'title')
self.result_text.insert(tk.END, " 五柱十字干支万年历\n", 'title')
self.result_text.insert(tk.END, "=" * 50 + "\n\n", 'title')
self.result_text.insert(tk.END, "【公历时间】\n", 'subtitle')
self.result_text.insert(tk.END, "-" * 35 + "\n")
self.result_text.insert(tk.END, f"{year}年{month}月{day}日 {hour:02d}:{minute:02d}\n")
weekday = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
wd = datetime(year, month, day).weekday()
self.result_text.insert(tk.END, f"{weekday[wd]}\n\n")
self.result_text.insert(tk.END, "【农历】\n", 'subtitle')
self.result_text.insert(tk.END, "-" * 35 + "\n")
if lunar.get("農曆月") != "未知":
self.result_text.insert(tk.END, f"{lunar['年']}年 {lunar['農曆月']} {lunar['日']}日 {hour:02d}:{minute:02d}\n")
weekday = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
wd = datetime(year, month, day).weekday()
self.result_text.insert(tk.END, f"{weekday[wd]}\n\n")
else:
self.result_text.insert(tk.END, "(需安装sxtwl库)\n\n")
self.result_text.insert(tk.END, "【节气】\n", 'subtitle')
self.result_text.insert(tk.END, "-" * 35 + "\n")
self.result_text.insert(tk.END, f"当前:{current_jq}\n")
self.result_text.insert(tk.END, f"开始:{next_jq_info['年']}-{jq_info['月']}-{jq_info['日']} {jq_info['时']:02d}:{jq_info['分']:02d}\n")
self.result_text.insert(tk.END, f"下一节气:{next_jq_info['节气']} {next_jq_info['年']}-{next_jq_info['月']}-{next_jq_info['日']} {next_jq_info['时']}:{next_jq_info['分']}\n\n")
self.result_text.insert(tk.END, "【五柱十字】\n", 'subtitle')
self.result_text.insert(tk.END, "-" * 35 + "\n")
zhu_names = ["年柱", "月柱", "日柱", "时柱", "刻柱"]
for i, name in enumerate(zhu_names):
if i < len(gz) and gz[i]:
self.result_text.insert(tk.END, f"{name}:", 'info')
self.result_text.insert(tk.END, f"{gz[i]}\n", 'big')
self.result_text.insert(tk.END, "\n【完整格式】\n", 'subtitle')
self.result_text.insert(tk.END, "-" * 35 + "\n")
full_str = " ".join([g for g in gz if g])
self.result_text.insert(tk.END, f"{full_str}\n\n", 'ganzhi')
self.result_text.insert(tk.END, "【纳音五行】\n", 'subtitle')
self.result_text.insert(tk.END, "-" * 35 + "\n")
for i, name in enumerate(zhu_names):
if i < len(gz) and gz[i]:
nayin = nayin_dict.get(gz[i], '未知')
self.result_text.insert(tk.END, f"{name}【{gz[i]}】{nayin}\n", 'info')
self.result_text.insert(tk.END, "\n" + "=" * 50 + "\n", 'info')
self.result_text.insert(tk.END, "【说明】\n", 'info')
self.result_text.insert(tk.END, "刻柱以当日子时为五马遁起点\n", 'correct')
self.result_text.insert(tk.END, "仅供国学文化研究参考\n", 'info')
self.result_text.insert(tk.END, "=" * 50 + "\n")
def clear_result(self):
self.result_text.delete(1.0, tk.END)
def main():
root = tk.Tk()
app = WuzhuGUI(root)
root.mainloop()
if __name__ == "__main__":
main()
更多推荐
所有评论(0)