紫微斗数出生日期输入控件
这段时间学了下紫微斗数,断命没学会,倒是对写程序排命盘产生了兴趣。今天先完成了第一步,用pyqt做了个支持日期输入的控件,可以输入公历或农历日期及时间,并根据输入的公历或农历日期查到对应的农历或公历日期以及用干支计时法表示的当日年月日时信息。试用该控件的一个程序显示的界面如下:
如果输入了不存在的农历日期:
下面是日期输入控件代码:
from datetime import datetime
import pandas as pd
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QLabel, QComboBox, QDateEdit, \
QGroupBox, QMessageBox
from PyQt5.QtCore import QDate
from lunarcalendar import Lunar, DateNotExist, Solar, Converter
# 天干列表
heavenly_stems = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']
# 地支列表
earthly_branches = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥']
# 时辰时间范围及时辰名称列表
time_name = ['00:00~00:59早子', '01:00~02:59丑', '03:00~04:59寅', '05:00~06:59卯', '07:00~08:59辰',
'09:00~10:59巳', '11:00~12:59午', '13:00~14:59未', '15:00~16:59申', '17:00~18:59酉',
'19:00~20:59戌', '21:00~22:59亥', '23:00~23:59晚子']
# 五虎遁诀由年干定月干表
month_stem_from_year = pd.DataFrame([
['年干', '子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'],
['甲', '丙', '丁', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸', '甲', '乙'],
['乙', '戊', '己', '戊', '己', '庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁'],
['丙', '庚', '辛', '庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己'],
['丁', '壬', '癸', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛'],
['戊', '甲', '乙', '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'],
['己', '丙', '丁', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸', '甲', '乙'],
['庚', '戊', '己', '戊', '己', '庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁'],
['辛', '庚', '辛', '庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己'],
['壬', '壬', '癸', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛'],
['癸', '甲', '乙', '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']])
# 五鼠遁诀由日干定时干表
time_stem_from_day = pd.DataFrame([
['日干', '子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'],
['甲', '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸', '甲', '乙'],
['乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁'],
['丙', '戊', '己', '庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己'],
['丁', '庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛'],
['戊', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'],
['己', '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸', '甲', '乙'],
['庚', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁'],
['辛', '戊', '己', '庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己'],
['壬', '庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛'],
['癸', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']])
def safe_lunar(year, month, day, isleap=False):
"""
QDateEdit控件不能保证输入的农历日期存在,故进行异常捕捉。
发生异常则返回None
"""
try:
lunar = Lunar(year, month, day, isleap=isleap)
return lunar
except DateNotExist as e:
print(e)
return None
def calculate_days_to_basic_day(date):
"""
计算给定日期离支持的最早日期之前最近的一个甲子日1899年12月22日之间的天数差,
用这个天数差确定给定日期的日干支
:param date: 以短横杠隔开的日期字符串
:return: 给定日期与1899年12月22日之间的天数差
"""
# 将字符串日期转换为datetime对象
day = datetime.strptime(date, '%Y-%m-%d')
base_day = datetime.strptime('1899-12-22', '%Y-%m-%d')
# 计算两个日期之间的差值并返回间隔天数
difference = day - base_day
return difference.days
class DateInputWidget(QWidget):
def __init__(self):
super().__init__()
self.solar_year = 0 # 公历年
self.solar_month = 0 # 公历月
self.solar_day = 0 # 公历日
self.lunar_year = 0 # 农历年
self.lunar_month = 0 # 农历月
self.lunar_day = 0 # 农历日
self.ye