周易知识库
首页 > 八字命理 > 八字纳音

生辰八字,五行归属,年月日时四柱如何计算?

时间:作者:周易知识库

生辰八字,五行归属,年月日时四柱如何计算?

摘要:取名讲究五行平衡,生辰八字,五行归属,年月日时四柱如何计算?本文主要实现基于的纳音五行测算,解释程序设计思路以及五行测算算法。

一、引言

人们常说生辰八字,是如何测算的?有了生辰八字,如何测试五行归属,网上测试方法五花八门,结果并不统一,通过调研现实师父,调研收集比较一致的生辰和五行测算算法,基于开发。

二、天干地支

生辰八字,即对于一个人的出生年月日和时辰,称为四柱,分别为年柱、月柱、日柱和时柱,各自分别对应一个天干和地支,共计八个字,故称八字。

天干地支,简称干支,古代常用于纪年、纪月、纪日和纪时。如甲午中日战争,是指19世纪末日本侵略中国和朝鲜的战争,按中国干支纪年,战争爆发的1894年为甲午年,故称甲午战争。

干支源自中国远古时代对天象的观测。十天干是指“甲、乙、丙、丁、戊、己、庚、辛、壬、癸”,十二地支是指“子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥”。按照组合,十天干和十二地支依次相配,组成六十个基本单位,两者间按固定顺序相互配合,组成了干支纪元法。干支纪元法六十年一循环,故人们常称六十年为一甲子。本文主要讨论生辰的干支计算以及五行归属。

三、五行

五行,也叫五行学说,是认识世界的基本方式, 即常说的金木水火土,是中国古代哲学家用五行理论来说明世界万物的形成及其相互关系。它强调整体,旨在描述事物的运动形式以及转化关系。阴阳是古代的对立统一学说,五行是原始的系统论。五行有相生相克之说:

相生,是指两类属性不同的事物之间存在相互帮助,相互促进的关系;具体是:木生火,火生土,土生金,金生水,水生木。

相克,则与相生相反,是指两类不同五行属性事物之间关系是相互克制的;具体是:木克土,土克水,水克火、火克金、金克木。

1.正五行

何为正五行,是和纳音五行相对,正五行是指天干和地支对应的五行。

十天干五行:甲乙为木,丙丁为火,戊己为土纳音五行有什么用,庚辛为金,壬癸为水。

十二地支五行:子为水,丑为土,寅卯为木,辰为土,巳午为火,未为土,申酉为金,戌为火,亥为水。

例如生辰八字:‘癸卯’, ‘己未’, ‘丁丑’, '丙午‘,对应的五行为:水木,土土,火土,火火。

2.纳音五行

天干有天干的五行,地支有地支的五行,天干与地支配合后会变成新的五行,称为“纳音五行”,原干支五行称为正五行,纳音五行叫做假借五行,因为它是假借古代五音(宫商角徵羽)和十二音律而组合成的纳音五行。

在实际中使用正五行常与实际有出入生辰八字,五行归属,年月日时四柱如何计算?,于是便用纳音做了补充,两者之间的关系可以看做是正五行为经,纳音五行为纬。这解释了农历2023年为什么既有人说是水兔年,又有人说为金兔年。网上查询偏水兔的较多,农历2023年的年柱为‘癸卯’,天干对于为水,故称“水兔”(实在不懂为啥这里不管地支);实际在民间,农历2023年的年柱为‘癸卯’,使用纳音五行,对应纳音为“金箔金”,故称“金兔”(参考中华万年历,对每日日柱五行,使用的便是纳音五行)。

纳音五行主要用于推算吉凶祸福、预测运势以及起名等方面(咱不迷信,只为搞清日历计算方法)。

六十甲子纳音表五行歌:

甲子、乙丑——海中金,丙寅、丁卯——炉中火。

戊辰、己巳——大林木,庚午、辛未——路旁土。

壬申、癸酉——剑锋金,甲戌、乙亥——山头火。

丙子、丁丑——涧下水,戊寅、己卯——城头土。

庚辰、辛巳——白蜡金,壬午、癸未——杨柳木。

甲申、乙酉——泉中水纳音五行有什么用,丙戌、丁亥——屋上土。

戊子、己丑——霹雳火,庚寅、辛卯——松柏木。

壬辰、癸巳——长流水,甲午、乙未——沙中金。

丙申、丁酉——山下火,戊戌、己亥——平地木。

庚子、辛丑——壁上土,壬寅、癸卯——金箔金。

甲辰、乙巳——覆灯火,丙午、丁未——天河水。

戊申、己酉——大驿土,庚戌、辛亥——钗钏金。

壬子、癸丑——桑柘木,甲寅、乙卯——大溪水。

丙辰、丁巳——沙中土,戊午、己未——天上火。

庚申、辛酉——石榴木,壬戌、癸亥——大海水。

农历2023年的年柱为‘癸卯’,对照纳音五行,五行为“金箔金”,故称农历2023年为“金兔“”年。

四、程序设计思路

生辰八字的计算算的是农历,故首先需实现公历和农历的转换,计算出了农历之后,再依次实现年柱、月柱、日柱和时柱的计算。

1.公历和农历转换

公历和农历的转换使用第三方库,使用pip安装:

pip install zhdate

实现了不用网络接口直接本地计算中国农历,支持农历公历互转,支持计算的农历时间范围为1900年至2100年,实现的基本思路是内置了从1900年至2100年每年的农历春节的公历日期和从1900年到2100年的农历月份数据代码(包括是否闰年、12个月份数的大小情况),作为农历和公历互转的基本知识库,通过计算当前农历日期和当年农历新年之间的天数差值,进一步实现农历和公历的互转,更详细的实现请直接阅读源码。

from datetime import datetime
from zhdate import ZhDate
# 农历转公历
lunar_date = ZhDate(2023, 6, 1)  # 新建农历
print(lunar_date)  # 查看农历
dt_date = lunar_date .to_datetime() # 农历转换成阳历日期datetime 类型
print(dt_date)
# 公历转农历
dt_date = datetime(2023, 7, 18)
lunar_date = ZhDate.from_datetime(dt_date)
print(lunar_date)

执行结果:

2.年柱算法与实现

年柱计算算法使用农历年,例如2023年1月18日,农历为2022年,应代入2022年进行计算,网上不少算法是直接使用2023年计算的纳音五行有什么用,这回答了为什么要首先实现。

的具体计算公式如下:

g = (year -3% 10 - 1
d = (year -3) % 12 - 1

年份减3(干支纪年法是从公元4年开始的)除以10取余,余数为天干的字,年份减3除以12取余,余数为地支的字,这样合起来变成了该年的年柱。需注意的是,天干的计算结果为1-10(相应的地支计算结果为1-12),取余后分别为1-9及0,0表示的应该是第10个天干或者第12个地支生辰八字,五行归属,年月日时四柱如何计算?,在中字符串或者列表是从0开始计算的,这样恰造成计算的天干或者地支恰好错一位,故计算出来的1应该表示的是第1个天干或者地支,其索引为0,故减1实现,对于第10个天干或者地支,表示取最后一个天干或者地支,取余结果为0,减1为-1,在中有倒序索引,此时取最后一个元素。

年份天干计算实现代码如下:

def __cal_year_ganzhi(self):
        # 计算年份的天干地支
        gan = TIANGAN[(self.lunar_datetime.year - 3) % 10 - 1]
        zhi = DIZHI[(self.lunar_datetime.year - 3) % 12 - 1]
        return gan + zhi

3.月柱算法与实现

一年12个月,有12个地支,故每月和地支的关系是固定的,但并不是每月的农历初一为新的地支开始,其和24节气中的节律相关,因此月柱计算算法相比年柱计算较为复杂,网上不少算法计算有误差,并没有按照节律来计算月柱。

(1).地支算法

纳音五行取名_纳音五行有什么用_纳音五行

具体来说按照12节律的顺序:‘立春’, ‘惊蛰’, ‘清明’, ‘立夏’, ‘芒种’, ‘小暑’, ‘立秋’, ‘白露’, ‘寒露’, ‘立冬’, ‘大雪’,‘小寒’,分别对应寅、卯、辰、巳、午、未、申、酉、戌、亥、子、丑;每个节律开始的第一天到下一个节律的前一天,均为对应的地支关系。

故月柱地支的计算问题转换为十二节律的计算问题,十二节律的计算公式为:

int(year % 100 * 0.2422 + values[c] - (year % 100 - 1) // 4)

年数的后2位乘0.2422加该节律对应的C值,并减去闰年数,不同节律的C值及具体映射关系通过字典的形式给出。其中,节律为key,对应月份和C值构成列表为value,列表第一个元素为节律对应的公历月份,其余为该节律对应的C值,C值有两个分别表示对应的20世纪和21世纪的节律C值,一个的表示20世纪和21世纪节律C值相同。

节律日期月份及C值字段如下:

MONTH_C = {
    "立春": [2, 3.87],
    "惊蛰": [3, 5.63],
    "清明": [4, 5.59, 4.81],
    "立夏": [5, 6.318, 5.52],
    "芒种": [6, 6.5, 5.678],
    "小暑": [7, 7.928, 7.108],
    "立秋": [8, 8.35, 7.5],
    "白露": [9, 8.44, 7.646],
    "寒露": [10, 9.098, 8.318],
    "立冬": [11, 8.218, 7.438],
    "大雪": [12, 7.9, 7.18],
    "小寒": [1, 6.11, 5.4055]
}

(2).天干算法

月份天干计算比较简单,使用公历年进行计算:

g = ((year % 5 - 2) * 2 - 1 + 10) % 10 - 1

公历年份除以5的余数减2后乘以2再减1,当该数是负数时加10,最后减1和前面类似,因为中的索引从0开始。

(3).代码实现

def __cal_month_ganzhi(self):
    # 计算月份的天干地支
    year, month, day = self.datetime.year, self.datetime.month, self.datetime.day
    cur_date = datetime(year, month, day)
    gan_index = ((year % 5 - 2) * 2 - 1 + 10) % 10 - 1
    for i in range(len(MONTHS)):
        if cur_date < self.month_dates[MONTHS[i]]:
            return TIANGAN[(gan_index + i - 2 + 10) % 10] + DIZHI[i]
    else:
        i += 1
        return TIANGAN[(gan_index + i - 2 + 10) % 10] + DIZHI[i%12]

4.日柱算法与实现

日柱的算法暂未找到有效的计算公式,从公历农历转换处得来的灵感,通过内置的1900年到2100年每年第一天(即元旦日的干支),通过计算具体计算日与元旦的天数差推导出实际的干支,每年元旦日干支字典如下:

YUNDAN_GANZHI = {
    '1900': '甲戌', '1901': '己卯', '1902': '甲申', '1903': '己丑', '1904': '甲午', '1905': '庚子', '1906': '乙巳', '1907': '庚戌', 		'1908': '乙卯', '1909': '辛酉', '1910': '丙寅', '1911': '辛未', '1912': '丙子', '1913': '壬午', '1914': '丁亥', '1915': '壬辰', '1916': '丁酉', '1917': '癸卯', '1918': '戊申', '1919': '癸丑', '1920': '戊午', '1921': '甲子', '1922': '己巳', '1923': '甲戌', '1924': '己卯', '1925': '乙酉', '1926': '庚寅', '1927': '乙未', '1928': '庚子', '1929': '丙午', '1930': '辛亥', '1931': '丙辰', '1932': '辛酉', '1933': '丁卯', '1934': '壬申', '1935': '丁丑', '1936': '壬午', '1937': '戊子', '1938': '癸巳', '1939': '戊戌', '1940': '癸卯', '1941': '己酉', '1942': '甲寅', '1943': '己未', '1944': '甲子', '1945': '庚午', '1946': '乙亥', '1947': '庚辰', '1948': '乙酉', '1949': '辛卯', '1950': '丙申', '1951': '辛丑', '1952': '丙午', '1953': '壬子', '1954': '丁巳', '1955': '壬戌', '1956': '丁卯', '1957': '癸酉', '1958': '戊寅', '1959': '癸未', '1960': '戊子', '1961': '甲午', '1962': '己亥', '1963': '甲辰', '1964': '己酉', '1965': '乙卯', '1966': '庚申', '1967': '乙丑', '1968': '庚午', '1969': '丙子', '1970': '辛巳', '1971': '丙戌', '1972': '辛卯', '1973': '丁酉', '1974': '壬寅', '1975': '丁未', '1976': '壬子', '1977': '戊午', '1978': '癸亥', '1979': '戊辰', '1980': '癸酉', '1981': '己卯', '1982': '甲申', '1983': '己丑', '1984': '甲午', '1985': '庚子', '1986': '乙巳', '1987': '庚戌', '1988': '乙卯', '1989': '辛酉', '1990': '丙寅', '1991': '辛未', '1992': '丙子', '1993': '壬午', '1994': '丁亥', '1995': '壬辰', '1996': '丁酉', '1997': '癸卯', '1998': '戊申', '1999': '癸丑', '2000': '戊午', '2001': '甲子', '2002': '己巳', '2003': '甲戌', '2004': '己卯', '2005': '乙酉', '2006': '庚寅', '2007': '乙未', '2008': '庚子', '2009': '丙午', '2010': '辛亥', '2011': '丙辰', '2012': '辛酉', '2013': '丁卯', '2014': '壬申', '2015': '丁丑', '2016': '壬午', '2017': '戊子', '2018': '癸巳', '2019': '戊戌', '2020': '癸卯', '2021': '己酉', '2022': '甲寅', '2023': '己未', '2024': '甲子', '2025': '庚午', '2026': '乙亥', '2027': '庚辰', '2028': '乙酉', '2029': '辛卯', '2030': '丙申', '2031': '辛丑', '2032': '丙午', '2033': '壬子', '2034': '丁巳', '2035': '壬戌', '2036': '丁卯', '2037': '癸酉', '2038': '戊寅', '2039': '癸未', '2040': '戊子', '2041': '甲午', '2042': '己亥', '2043': '甲辰', '2044': '己酉', '2045': '乙卯', '2046': '庚申', '2047': '乙丑', '2048': '庚午', '2049': '丙子', '2050': '辛巳', '2051': '丙戌', '2052': '辛卯', '2053': '丁酉', '2054': '壬寅', '2055': '丁未', '2056': '壬子', '2057': '戊午', '2058': '癸亥', '2059': '戊辰', '2060': '癸酉', '2061': '己卯', '2062': '甲申', '2063': '己丑', '2064': '甲午', '2065': '庚子', '2066': '乙巳', '2067': '庚戌', '2068': '乙卯', '2069': '辛酉', '2070': '丙寅', '2071': '辛未', '2072': '丙子', '2073': '壬午', '2074': '丁亥', '2075': '壬辰', '2076': '丁酉', '2077': '癸卯', '2078': '戊申', '2079': '癸丑', '2080': '戊午', '2081': '甲子', '2082': '己巳', '2083': '甲戌', '2084': '己卯', '2085': '乙酉', '2086': '庚寅', '2087': '乙未', '2088': '庚子', '2089': '丙午', '2090': '辛亥', '2091': '丙辰', '2092': '辛酉', '2093': '丁卯', '2094': '壬申', '2095': '丁丑', '2096': '壬午', '2097': '戊子', '2098': '癸巳', '2099': '戊戌', '2100': '癸卯'
    }

天数差的计算需要注意大小月,以及特殊的2月天数,闰年为29天,平年28天,故还需判断是否闰年,闰年判断实现如下:

def is_leap_year(year):
    if year % 4 == 0:
        if year % 100 == 0:
            if year % 400 == 0:
                return True  # 能被400整除的是闰年
            else:
                return False  # 能被100整除但不能被400整除的不是闰年
        else:
            return True  # 能被4整除但不能被100整除的是闰年
    else:
        return False  # 不能被4整除的不是闰

大小月的判断通过一个长度为12的列表实现,表示对应月份前面有多少个大月即可:

BIG_MONTHS = [0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6]

纳音五行有什么用_纳音五行_纳音五行取名

第1个元素表示1月份前有0个大月,第2、3月前面有1个大月,依次类推。

日柱实现代码如下:

def __cal_day_ganzhi(self):
    # 计算日期的天干地支
    year, month, day = self.datetime.year, self.datetime.month, self.datetime.day
    yuan_dan = YUNDAN_GANZHI[str(year)]
    days = BIG_MONTHS[month - 1] * 31 + (month - 1 - BIG_MONTHS[month - 1]) * 30 + day
    if month > 2:
        days -= 1 if self.is_leap_year(year) else 2
    gz = list(GANZHI_ELEMENTS.keys())
    return gz[(gz.index(yuan_dan) + days - 1) % 60]  # 计算的是与元旦的间隔天数,故减1

5.时柱算法与实现

时柱计算比较简单,古人将现在的24小时分为12个时辰,和地支数一致,各时辰和地支的关系是固定的,时辰的换算关系是,小时数加1整除以2的商对12取余,索引从0开始,再减1即可。

时柱天干计算公式依赖于日柱天干,为天干数乘以2再加上时支(子丑寅卯辰巳午未申酉戌亥对应时支依次为-1,0,1,。。。,10)得到天干支数。

时柱实现如下:

def __cal_hour_ganzhi(self):
        # 计算时间的天干地支
        hour = self.datetime.hour
        hour = (hour + 1) // 2 % 12
        dizhi = DIZHI[hour]
        ans = (TIANGAN.index(self.__cal_day_ganzhi()[0]) + 1) * 2 + DIZHI.index(dizhi) - 1
        return TIANGAN[ans % 10 - 1] + dizhi

五、程序实现

设计nts类,为其基类,需要实现农历和公历两种类型时间的五行计算,类参数为农历的年月日,以及小时,基于基类实现到公历的转换:

class calculate_five_elements(ZhDate):
    # 在这里编写根据生辰计算五行的逻辑
    def __init__(self, lunar_year, lunar_month, lunar_day, lunar_hour, leap_month=False):
        super().__init__(lunar_year, lunar_month, lunar_day, leap_month)
        self.lunar_datetime = DATE_TIME(year=lunar_year, month=lunar_month, day=lunar_day, hour=lunar_hour)  # 农历时间
        self.datetime = super().to_datetime()
        self.datetime = DATE_TIME(year=self.datetime.year, month=self.datetime.month, day=self.datetime.day, hour=lunar_hour)  # 公历时间
        self.month_dates = self.__jieqi_date(datetime(self.datetime.year, self.datetime.month, self.datetime.day))

设计静态函数,实现公历的五行转换,具体为调用基类转换方法转换公历得到农历,返回nts类,具体实现如下:

@staticmethod
    def from_datetime(year, month, day, hour):
        cur_date = ZhDate.from_datetime(datetime(year, month, day))
        return calculate_five_elements(cur_date.lunar_year, cur_date.lunar_month, cur_date.lunar_day, hour)

最后调用类方法,返回生辰八字和五行(时柱五行返回了两种结果,一是纳音五行,二是时柱五行只看地支的五行,不同流派计算有差异),方法实现如下:

def five_elements(self):
    year_gz = self.__cal_year_ganzhi()
    month_gz = self.__cal_month_ganzhi()
    day_gz = self.__cal_day_ganzhi()
    hour_gz = self.__cal_hour_ganzhi()
    gz = [year_gz, month_gz, day_gz, hour_gz]
    nayin_five = GANZHI_ELEMENTS[year_gz], GANZHI_ELEMENTS[month_gz], GANZHI_ELEMENTS[day_gz], [GANZHI_ELEMENTS[hour_gz], DIZHI_ELEMENTS[DIZHI.index(hour_gz[-1])]]
    return gz, nayin_five

程序使用说明如下:

查询程序参数与使用说明:

python calculate_five_elements.py -h

纳音五行_纳音五行有什么用_纳音五行取名

(1)查询国历日期

查询国历2023年10月20日14点的生辰五行,输入与输出结果如下:

输入:

python calculate_five_elements.py 2023 10 20 14

输出:

(2)查询农历日期

查询农历2023年9月初六 14点的生辰五行,输入与输出结果如下:

输入,其中参数-islun表示当前查询农历日期

python calculate_five_elements.py 2023 9 6 14 -islun
# 或
python calculate_five_elements.py -islun 2023 9 6 14

输出:

(3)测试系统及环境

程序运行系统配置及开发环境如下:

专业版下的WSL2,.9发行版,.10.12

六、程序源代码 (1)字节码

完整代码编译的字节码文件(.pyc)下载请点击此处。

(2)源码

完整源码(.py)下载请点击此处。



周易知识库专业的命理易学平台。