前段时间宝宝出生了,兴奋之余,一直忙着给宝宝选名字,想起网上各式各样的五行查询,出于好奇研究了下算法,于是自己也试着写了个小程序。先上张截图:
当然,首先就要先理解最基本的,什么是天干地支,什么是生辰八字,什么是五行。
1. 什么是天干地支
天干地支,简称为干支,源自远古时代对天象的观测。”甲、乙、丙、丁、戊、己、庚、辛、壬、癸”称为十天干,”子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥”称为十二地支。天干地支组成形成了古代纪年历法。十干和十二支依次相配,组成六十个基本单位,两者按固定的顺序相互配合,组成了干支纪法。
2. 什么是生辰八字
生辰八字,简称八字,是指一个人出生时的干支历日期;年月日时共四柱干支,每柱两字,合共八个字,故称。生辰八字在汉族民俗信仰中占有重要地位,古代汉族星相家据此推算人的命运的好坏。在历书中,年的干支与日的干支基本都有,而月与时的天干可以依据年、日的干支按口诀推算得出。
上面说的年月日时干支,意思是把日期分成四部分:年、月、日、时。而每个日期又有天干和地支两部分,因此合起来就是:年干、年支、月干、月支、天干、天支、时干、时支。
众所周知,一个时辰是两个小时,具体的对应关系如下:
子时 | 丑时 | 寅时 | 卯时 | 辰时 | 己时 |
---|---|---|---|---|---|
23: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 |
3. 什么是五行
五行是中国自古以来道学的一种系统观,广泛地用于中医学、堪舆、命理、相术和占卜等方面。五行的意义包涵借着阴阳演变过程的五种基本动态:水(代表润下)、火(代表炎上)、金(代表收敛)、木(代表伸展)、土(代表中和)。中国古代哲学家用五行理论来说明世界万物的形成及其相互关系。它强调整体概念,旨在描述事物的运动形式以及转化关系。
4. 怎么知道哪个时辰的八字都是什么
首先知道天干、地支的五行含义:
甲 | 乙 | 丙 | 丁 | 戊 | 己 | 庚 | 辛 | 壬 | 癸 | ||
---|---|---|---|---|---|---|---|---|---|---|---|
木 | 木 | 火 | 火 | 土 | 土 | 金 | 金 | 水 | 水 | ||
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
寅 | 卯 | 辰 | 巳 | 午 | 未 | 申 | 酉 | 戌 | 亥 | 子 | 丑 |
水 | 土 | 木 | 木 | 土 | 火 | 火 | 土 | 金 | 金 | 土 | 水 |
具体的八字推算,老祖宗已经帮我们总结好了,问问度娘可以发现有很多种方法,我这里采用比较简单也易实现的一种:
年干支推算:
1.年干公式:年干=年份个位数- 3 (适用于任何西元年,个位数小于3,借10)
2.年支公式:年支=(年份+7)÷12余数(整除余0,即余12=丑)
通过以上公式,可以得出年干、年支与自然数的对应关系。
天干地支纪年法首先是天干在前,地支在后,比如今年2016就为——丙申年。
月干支推算:
月的地支是固定不变的:正月是寅,二月是卯,三月是子,依次类推…..也就是用年支的推算方式,年支和月支应该正好一致。
月干公式:月干=年干x2+月支 (和超过10,直接取个位数)
例:已知2015年为乙未年,求2015年申月天干?
解:2015年乙未年,天干为乙,乙=2,申=7
日干推算:日干推算比较复杂,我这里使用高氏日柱公式来进行推算。公式如下(具体含义可参考高氏日柱公式):
r=s/46+5(s/4*3+u)+m+d+x
日支推算:我这里采用的是用六十甲子表,直接查询日干结果在甲子表中对应的值。
时干推算:
①时支公式:时支=小时÷2-1(小时为偶数),时支=(小时+1)÷2-1(小时为奇数)
②时干公式:时干=日干×2+时支 (晨子=-1,夜子=11)
在这里吐槽一下网上流传很广的那些帖子,我找的六十甲子基本都是把自己的“己”给错写成了已经的“已”,导致有些日期查询异常。
到这里,知道了八字的计算方式和与自然数的对应关系,因此,可以用数组来描述这些关系,因为月干是需要与年份有关的,因此可以定义一个函数来获取:
另外就是利用高氏日柱公式计算日干、日支方法。
现在来想一下程序的结构:我希望的是和那些网站一样,选择出生年月日时,就可以给出结果。因此,可以定义成一个工具类,输入是日期对象,输出是八字和五行的分析结果。
另外,上面的公式只适用于公历,我希望可以用农历和公历两种方法进行推算。这里用到了一个插件calendar.js,可以进行公历农历的转换。
完整Demo点击下面链接(因为关注点没在日期校验上,所以对于日期并没有增加校验,如下拉列表每月的天数):