|||
update: 修正笔误,增加口诀.2017-11-8
update: 增加从干支推算年份的方法. 2017-10-29
Update: 增加C#代码的实例 。2017-7-3
初看以为复杂,其实非常简单,天干地支记年法是60年一循环,一张图片足以解释清楚。
喜欢玩Excel函数的可以用这个公式来算 (A2为年份保存的单元格,注意根据具体位置调整)
=MID("甲乙丙丁戊已庚辛壬癸",MOD(A2-IF(A2>0,4,3),10)+1,1) & MID("子丑寅卯辰已午未申酉戌亥",MOD(A2-IF(A2>0,4,3),12)+1,1)
写成VBA的函数也是可以的,要放在模块中才便于使用.
Function TGDZ(theYear As Integer) As String
Dim N As Integer, M1 As Integer, M2 As Integer
Application.Volatile
If theYear = 0 Then
MsgBox "年份不能为0,没有公元0年这一说法,开始即为公元1年"
TGDZ = "年份错误不能为0"
Exit Function
End If
N = theYear - IIf(theYear > 0, 4, 3)
M1 = (N Mod 10) + 10 * IIf((N Mod 10) < 0, 1, 0) + 1
M2 = (N Mod 12) + 12 * IIf((N Mod 12) < 0, 1, 0) + 1
TGDZ = Mid("甲乙丙丁戊已庚辛壬癸", M1, 1) & Mid("子丑寅卯辰已午未申酉戌亥", M2, 1)
End Function
上述函数使用方法就是 =TGDZ(A1), 这里A1就是A1格,保存年份,公元前记为负数.
当然,也可以贴个计算实例,一目了解。
原始的EXCEL文件 利用EXCEL计算天干地支年份的公式.xlsx
用Powershell计算的脚本 计算天干地支.rar
用C#计算 TGDZcalc.rar
显然,这么上面这么多年份对应关系是不必要的,可以快速心算,只要知道10个天干,12个地支的汉字就行。
自编两句助记的口诀如下
对公元以后的年份:
年份减84(即1984,也可用1924),记住这个数。
天干除干数,地支除支数(即分别除10,12),余数加1找汉字。
第1步,用年份减去1984或1924,不出现负数即可。记下这个差。
第2步,用第1步求得的差,对10,12分别求余数,余数加1后按这个顺序分别在天干地支中找汉字,合起来就成。
如2013年,这个数为2013-1984=29.记住这个数。
29除10余9, 9+1=10, 天干顺序中第10位即为癸。(实际上就是计算机中的取余)
29除12余5,5+1=6, 地支中第6位为巳。
此年即为癸巳年。
又如1937年,这个数为1937-1924=13,记住这个数13.
13除10余3, 3+1=4, 天干中第4位为丁。
13除12余1, 1+1=2, 地支中第2位为丑。
此年即为丁丑年。
当然,以上所指年份均为农历年。 公历的某些日子在农历中可能是另一年所属。
或许有人钻牛角尖,问,如果更早的或更晚的年份呢? 比如说公元前呢?
上面的口诀再改改就行,变成通杀版本,可计算上下五千年,如下
元前减3元后4(公元前年份数减3; 公元后年份减4,这里的3,4就是自然数3 或4, 不是1904.由于没有公元公元0年,这里出现了不连续需要调整),
负数花甲变正数。(负数通过与60的整数倍相加变为正数)
天干除干数,地支除支数(即分别除10,12取余数,注意负数可加上60的整数倍变成正数来求余),
余数加1找汉字。
比如,嬴渠梁发布招贤令的年份是公元前361年,记为-361年。
-361-3=--364, 负数的求余不太好理解,可以加上整数倍个花甲(即60年天干地支1个循环)调整为正数再来看(不能直接去掉负号变成正数来求余)。
-364加上360得-4,还不够正数。再加一个60, 得56.
以56除以10的余数加上1,得7,天干即庚;56除以12的余数加1,得9,地支即申。此年即为庚申年。
负数的心算稍麻烦一些,但如果用EXCEL来计算,与正数一样简单。 Enjoy it!
---------------------2017-10-29 更新--------------------------------
有人会问,如果反过来呢,我们是不是可以根据花甲来推算他的年份? 这个显然也是可以的,只是有一点,从年份到干支的计算中,多少个花甲(60年)的倍数是丢掉不用的,因此,必须补上这个信息,我们才能反推出准确的年份,否则,计算的结果是不唯一的.
比如说, 出生在丙辰年的人,如果不推定他所处的大致年份,前60年,后60年出生的人都可能是丙辰生肖的.
这个推算相对复杂一点,倒也解说得清楚.
首先还是根据干支倒算出余数,比如说 丙辰年的,丙在天干排第3,对应前面的计算,天干余数为2. 辰在地支排第5,地支余数为4. 哪个数值除以10余2, 除以12余4呢?
这里有个小技巧,一个数除以10的余数,减去它除以12的余数,其差值应该是2的倍数.每增加一个10年,这个差值就增加2.或者说,每增加2,对应的年分就增加10年.(如果差值小于0,天干的余数先要加上12再去相减).
因此,这个倍数除以2就得到十位数.或者说直接除以2乘以10就得到不含个位数的中间值.
个位上的数字很简单,就是天干余数.
以丙辰为例,天干余数2,地支余数4,差值小于0,加上12再相减,12+2-4=10. 10除以2得5,十位数即为5.个位数为天干余数2,因此,结果为52,即52是丙辰在该花甲中的序数.加上1924即为1976年. 假设这个属相是1984年之后出生的,应该是1984+52=2036年,目前还没有出生呢.
为了方便,可以列出下面的公式:
=1984
+MOD((12+FIND(LEFT(B2,1),"甲乙丙丁戊已庚辛壬癸")-FIND(RIGHT(B2,1),"子丑寅卯辰已午未申酉戌亥")),12)*10/2+
FIND(LEFT(B2,1),"甲乙丙丁戊已庚辛壬癸")-1
我特意把公式写成三行以方便观察.
第一行指定基数,即干支数的首年,比如说,这个人在1984年之后生的,用1984;如果在1984之前的,可能是1924, 或者是1864年,依次类推.本例中用了1984.
第二行,就是该干支在花甲中的序数的十位数的计算.原理上面讲过了.
第三行,就是该干支在花甲中的序数的个位数.
对于公元前,由于没有公元前0年,所以干支的首年变化了.计算表示-57年(公元前57年)为公元前的首个甲子年,因此,这个公式的 调整为
=-57+
MOD((12+FIND(LEFT(B2,1),"甲乙丙丁戊已庚辛壬癸")-FIND(RIGHT(B2,1),"子丑寅卯辰已午未申酉戌亥")),12)*5
+FIND(LEFT(B2,1),"甲乙丙丁戊已庚辛壬癸")-1
如果不在范围之内,通过减去更多个60倍数就可以得到了.
以上面讲的嬴渠梁发布招贤令的年份是庚申年,
上面公式计算出来的是-1, 通过减去360年(6个花甲)就得到-361年.至于要减去多少个花甲年份才能正确,要靠其它信息来确定了.
因为公元前的年份计算结果不能为正数,如果一旦出现正数,就需要再减去60.
老规矩,还是放上示例文件. 从干支推算年份的方法.xlsx
也相应的编个口诀吧(括号内为对应的示例):
序数减1, (丙→2, 辰→4)
正差乘5, (12+2-4=10, 10*5→50,差为负值要加上12)
个位干余,(50 + 2=52)
加上基数( 1924+52=1976,一般只要记住两个基数就可以了,近代常用1924, 公元前用-57,其它的加减若干个60就行了.)
2018-1-31 最近学习matlab,补充个用m语言写的函数.TGDZ(matlab).rar
C#的小程序,CMD下面运行TGDZcalc.rar
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-11-23 09:09
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社