python实现下的四柱八字

计算八字的算法研究

本文用python的代码实现了计算八字,这是自己开发的,开放出来供大家研究学习。
以下也是基于jupyter notebook导出的,所以,保持原样,可读性更高。如果不是技术开发人员阅读可能会有些障碍,不过,那就pass掉代码块就行了。
首先,要想算出准备八字,就要搞清楚临界点的问题。比如,2024年是甲辰,但当输入2024.1.1时,输出却变成了“癸卯甲子甲子甲子”。这是为什么,因为,目前农历(阴历)还未过2023年。所以,在计算时要先把年从阳历转成阴历。
所以,先从这个小算法开始。

from lunardate import LunarDate
from datetime import datetime
def convert_solar_to_lunar(year, month, day):
    solar_date = datetime(year, month, day)
    lunar_date = LunarDate.fromSolarDate(solar_date.year, solar_date.month, solar_date.day)
    return lunar_date
solar_year = 2024
solar_month = 1
solar_day = 1
lunar_date = convert_solar_to_lunar(solar_year, solar_month, solar_day)
print(f"阳历 {solar_year}-{solar_month:02d}-{solar_day:02d} 对应的农历是 {lunar_date.year}年{lunar_date.month}月{lunar_date.day}日")

阳历 2024-01-01 对应的农历是 2023年11月20日

def get_bazi(year, month, day, birth):
    # 首先要年转成阴历,并且只在计算年柱时用阴历
    lunar_date = convert_solar_to_lunar(year, month, day)
    only4y = lunar_date.year
    
    # 计算天干地支纪年法中的年柱
    year柱子 = get_year_column(only4y)
    # 计算天干地支纪年法中的月柱
    month柱子 = get_mon_column(year, month)
    # 计算天干地支纪年法中的日柱
    day柱子 = get_day_column(year, month, day,birth)
    # 计算天干地支纪年法中的时柱
    time柱子 = get_time_column(year, month, day, birth)
    return year柱子 + month柱子 + day柱子 + time柱子
def get_year_column_1(year):
    # 天干地支纪年法中的天干
    tiangan = [ "庚", "辛", "壬", "癸","甲", "乙", "丙", "丁", "戊", "己"]
    # 天干地支纪年法中的地支
    dizhi = ["申", "酉", "戌", "亥","子", "丑", "寅", "卯", "辰", "巳", "午", "未"]
    # 计算天干
    tiangan_index = year % 10
    tiangan = tiangan[tiangan_index]
    # 计算地支
    dizhi_index = year % 12
    dizhi = dizhi[dizhi_index]
    return f"{tiangan}{dizhi}"
def get_year_column(year):
    # 计算天干
    tiangan = ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"]
    # 计算地支
    dizhi = ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"]
    # 计算天干
    tiangan_index = (year - 4) % 10
    tiangan = tiangan[tiangan_index]
    # 计算地支
    dizhi_index = (year - 4) % 12
    dizhi = dizhi[dizhi_index]
    
    return f"{tiangan}{dizhi}"
def get_mon_column(year, month):
    # 计算天干
    tiangan = ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"]
    # 计算地支
    dizhi = ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"]
    # 计算天干
    tiangan_index = (year - 4) % 10
    midMonth = tiangan_index * 2 + month
    midMonth = midMonth % 10
    
    # 平闰年校验
    if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
        # print(year, '是闰年')
        if month == 1 or month == 2:
            midMonth = midMonth - 1
            month = month - 1
    tiangan = tiangan[midMonth]
    dizhi = dizhi[month]
    return f"{tiangan}{dizhi}"
def get_day_column(year, month, day, birthtime):
    # 查表
    # 创建一个空字典
    calendar = {}
    # 填充数据
    calendar[1] = "甲子"
    calendar[2] = "乙丑"
    calendar[3] = "丙寅"
    calendar[4] = "丁卯"
    calendar[5] = "戊辰"
    calendar[6] = "己巳"
    calendar[7] = "庚午"
    calendar[8] = "辛未"
    calendar[9] = "壬申"
    calendar[10] = "癸酉"
    calendar[11] = "甲戌"
    calendar[12] = "乙亥"
    calendar[13] = "丙子"
    calendar[14] = "丁丑"
    calendar[15] = "戊寅"
    calendar[16] = "己卯"
    calendar[17] = "庚辰"
    calendar[18] = "辛巳"
    calendar[19] = "壬午"
    calendar[20] = "癸未"
    calendar[21] = "甲申"
    calendar[22] = "乙酉"
    calendar[23] = "丙戌"
    calendar[24] = "丁亥"
    calendar[25] = "戊子"
    calendar[26] = "己丑"
    calendar[27] = "庚寅"
    calendar[28] = "辛卯"
    calendar[29] = "壬辰"
    calendar[30] = "癸巳"
    calendar[31] = "甲午"
    calendar[32] = "乙未"
    calendar[33] = "丙申"
    calendar[34] = "丁酉"
    calendar[35] = "戊戌"
    calendar[36] = "己亥"
    calendar[37] = "庚子"
    calendar[38] = "辛丑"
    calendar[39] = "壬寅"
    calendar[40] = "癸卯"
    calendar[41] = "甲辰"
    calendar[42] = "乙巳"
    calendar[43] = "丙午"
    calendar[44] = "丁未"
    calendar[45] = "戊申"
    calendar[46] = "己酉"
    calendar[47] = "庚戌"
    calendar[48] = "辛亥"
    calendar[49] = "壬子"
    calendar[50] = "癸丑"
    calendar[51] = "甲寅"
    calendar[52] = "乙卯"
    calendar[53] = "丙辰"
    calendar[54] = "丁巳"
    calendar[55] = "戊午"
    calendar[56] = "己未"
    calendar[57] = "庚申"
    calendar[58] = "辛酉"
    calendar[59] = "壬戌"
    calendar[60] = "癸亥"
    dicf2 = {}
    dicf2[18] = 25
    dicf2[19] = 9
    dicf2[20] = 54
    dicf2[21] = 39
    dicmon = {}
    dicmon[1]=1
    dicmon[4]=1
    dicmon[5]=1
    dicmon[3]=0
    dicmon[2]=2
    dicmon[6]=2
    dicmon[7]=2
    dicmon[8]=3
    dicmon[9]=4
    dicmon[10]=4
    dicmon[11]=5
    dicmon[12]=5
    yearfront2 = int(str(year)[:2])
    yearlast2 = int(str(year)[-2:])
    isdoublemonth = 30 if month % 2 == 0 else 0
    # (month/2==0)?0:30
    # 主公式
    ret = yearlast2 * 5 + int(yearlast2/4) + dicf2[yearfront2] + day + isdoublemonth + dicmon[month]
    # 平闰年校验
    if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
        # print(year, '是闰年')
        if month == 1 or month == 2:
            ret = ret - 1
    # else:
        # print(year, '是平年')
    retindex, retyu = divide_remainder(ret, 60)
    if retyu:
        retindex = retyu
    # 计算天干
    # tiangan = ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"]
    # 计算地支
    # dizhi = ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"]
    # 计算天干
    # tiangan_index = (year - 4) % 10
    # tiangan = tiangan[tiangan_index]
    # 计算地支
    # dizhi_index = (year - 4) % 12
    # dizhi = dizhi[dizhi_index]
    day柱子 = calendar[retindex]
    return f"{day柱子}"
def divide_remainder(num, divisor):
    # 使用 divmod 方法获取整除结果和取余结果
    result, remainder = divmod(num, divisor)
    if remainder:
        return result, remainder
    else:
        return result
def get_time_column(year, month, day, birth):
    # 计算天干
    tiangan = ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"]
    # 计算地支
    dizhi = ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"]
    hour = None
    # if birth >= 100:
    hour = birth / 100
    # else:
    #     return
    
    if hour > 24:
        return
    # 时地支
    时辰 = None
    if hour < 1:
        时辰 = "子"
        hour_old = 1
    elif hour < 3:
        时辰 = "丑"
        hour_old = 2
    elif hour < 5:
        时辰 = "寅"
        hour_old = 3
    elif hour < 7:
        时辰 = "卯"
        hour_old = 4
    elif hour < 9:
        时辰 = "辰"
        hour_old = 5
    elif hour < 11:
        时辰 = "巳"
        hour_old = 6
    elif hour < 13:
        时辰 = "午"
        hour_old = 7
    elif hour < 15:
        时辰 = "未"
        hour_old = 8
    elif hour < 17:
        时辰 = "申"
        hour_old = 9
    elif hour < 19:
        时辰 = "酉"
        hour_old = 10
    elif hour < 21:
        时辰 = "戌"
        hour_old = 11
    else:
        时辰 = "亥"
        hour_old = 12
    # print(时辰)
    # 时天干
    day_tg = get_day_column(year, month, day, birth)[0]
    hour_tg = None
    if day_tg == '甲' or day_tg == '己':
        hour_index, yu = divide_remainder(hour_old, 10)
        if yu:
            hour_index = yu
        # print(hour_index)
        hour_tg = tiangan[hour_index - 1]
    if day_tg == '乙' or day_tg == '庚':
        hour_index, yu = divide_remainder(hour_old, 10)
        if yu:
            hour_index = yu
        hour_tg = ["丙", "丁", "戊", "己", "庚", "辛", "壬", "癸", "甲", "乙"][hour_index - 1]
    if day_tg == '丙' or day_tg == '辛':
        hour_index, yu = divide_remainder(hour_old, 10)
        if yu:
            hour_index = yu
        hour_tg = ["戊", "己", "庚", "辛", "壬", "癸", "甲", "乙", "丙", "丁"][hour_index - 1]
    if day_tg == '丁' or day_tg == '壬':
        hour_index, yu = divide_remainder(hour_old, 10)
        if yu:
            hour_index = yu
        hour_tg = ["庚", "辛", "壬", "癸", "甲", "乙", "丙", "丁", "戊", "己"][hour_index - 1]
    if day_tg == '戊' or day_tg == '癸':
        hour_index, yu = divide_remainder(hour_old, 10)
        if yu:
            hour_index = yu
        hour_tg = ["壬", "癸", "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛"][hour_index - 1]
    # 计算天干
    tiangan_index = (year - 4) % 10
    tiangan = tiangan[tiangan_index]
    # 计算地支
    dizhi_index = (year - 4) % 12
    dizhi = dizhi[dizhi_index]
    return f"{hour_tg}{时辰}"
print(get_bazi(1980,10,23,2230))

庚申丙戌己巳乙亥

print(get_bazi(2011,4,12,1508))

辛卯壬辰丁酉戊申

print(get_bazi(2024,1,1,0))

癸卯甲子甲子甲子
* * *
### 加入五行映射的算法

def handlwuxingbybazhi(bz):
    print("八字:"+bz+"\n")
    
    ret1 = None
    tgls = {}
    tgls['甲']="阳木"
    tgls['乙']="阴木"
    tgls['丙']="阳火"
    tgls['丁']="阴火"
    tgls['戊']="阳土"
    tgls['己']="阴土"
    tgls['庚']="阳金"
    tgls['辛']="阴金"
    tgls['壬']="阳水"
    tgls['癸']="阴水"
    
    
    dzls = {}
    dzls['子']="阳水"
    dzls['丑']="阴土"
    dzls['寅']="阳木"
    dzls['卯']="阴水"
    dzls['辰']="阳土"
    dzls['巳']="阴火"
    dzls['午']="阳火"
    dzls['未']="阴土"
    dzls['申']="阳金"
    dzls['酉']="阴金"
    dzls['戌']="阳土"
    dzls['亥']="阴水"
        
    
    ret1 = tgls[bz[0]]+","+dzls[bz[1]]+","+tgls[bz[2]]+","+dzls[bz[3]]+","+tgls[bz[4]]+","+dzls[bz[5]]+","+tgls[bz[6]]+","+dzls[bz[7]]
    os = set()
    os.add(tgls[bz[0]][1])
    os.add(dzls[bz[1]][1])
    os.add(tgls[bz[2]][1])
    os.add(dzls[bz[3]][1])
    os.add(tgls[bz[4]][1])
    os.add(dzls[bz[5]][1])
    os.add(tgls[bz[6]][1])
    os.add(dzls[bz[7]][1])
    
    aa=["金","木","水","火","土"]
    for i in os:
        aa.remove(i)
    
    print("五行:"+tgls[bz[4]][1]+"命")
    print("五行缺:")
        
    print(aa)
    return f"{ret1}"

应用示例

print(handlwuxingbybazhi(get_bazi(2017,2,6,1130)))

八字:丁酉壬寅甲子庚午
    
    五行:木命
    五行缺:
    [‘土’]
    阴火,阴金,阳水,阳木,阳木,阳水,阳金,阳火

print(get_bazi(2024,1,1,0))

癸卯甲子甲子甲子