dingsir的个人博客分享 http://blog.sciencenet.cn/u/dingsir

博文

心算任意年份的天干地支的方法

已有 9274 次阅读 2017-1-10 13:34 |个人分类:软件杂谈|系统分类:教学心得| 公式, 口诀, 天干地支, EXCEL公式, 心算方法

update: 修正笔误,增加口诀.2017-11-8

update: 增加从干支推算年份的方法. 2017-10-29

Update: 增加C#代码的实例 。2017-7-3

初看以为复杂,其实非常简单,天干地支记年法是60年一循环,一张图片足以解释清楚。

天干地支心算法.png


喜欢玩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








https://wap.sciencenet.cn/blog-1213210-1026674.html

上一篇:回复网友, 我对HOMO/LUMO的理解
下一篇:漫谈化学结构的文本表示法 SMILES, CAL脚本以及用CAL生成SMILES
收藏 IP: 112.2.61.*| 热度|

2 黄荣彬 chenhuansheng

该博文允许注册用户评论 请点击登录 评论 (2 个评论)

数据加载中...
扫一扫,分享此博文

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-21 12:15

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部