干支纪年算法

Posted 郎中令

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了干支纪年算法相关的知识,希望对你有一定的参考价值。

    作为21世纪的新青年,不会干支的程序员肯定不是一个好司机,中华文化源远流长,古代文明令人钦佩不已,十二地支对应十二个时辰(一个时辰等于两小时),又暗合十二生肖,每个生肖又对应着五行和阴阳属性,五行之中又相生相克,而天干同样有对应的五行阴阳,五行阴阳又暗合日月星辰和方位,利用占卜可以得吉凶,扯远了,再说下去估计就变成神棍了,言归正传, 天干地支组成形成了古代纪年历法。十天干和十二地支依次相配,组成六十个基本单位,两者按固定的顺序相互配合,组成了干支纪元法,为60甲子表,也就是几时几刻。

    十大天干: 甲 乙 丙 丁 戊 己 庚 辛 壬 癸

    对应编号: 1  2  3  4  5  6  7  8  9  10

    十二地支: 子 丑 寅 卯 辰 巳 午 未 申  酉 戌  亥

    对应编号: 1  2  3  4  5  6  7  8  9  10 11 12

    关于年支纪年法,百度是这样介绍的 

   ①年干公式:年干=公元年个位数-3 (个位小于3,加10)
     例:求1899年,1911年和2015年天干?
     解:1899年干=9-3=6=己,1911年干=1-3+10=8=辛,2015年干=5-3=2=乙
   ②年支公式:
   (公元年末二位数-11)-12*N=年支(适用于20世纪,即1900—1999年)
   (公元年末二位数+5)-12*N=年支(适用于21世纪,即2000—2099年)
对于年支计算,具有局限性,20世纪、21世纪算法都不一样,总所周知,庚子年(1900)八国联军入侵北京,1900末两位数减去 11 得到的负值,然后补位+12得到1,即为:
(0-11+12)%12=1 对应的子,故1900为庚子年。而别的网站介绍,方法更是五花八门,各种情况下都有不同的算法,实在是太繁琐,不便于计算
      我稍稍精简了下算法,直接  (年份)%12 +9 = 年支  ,大于一轮地支数12的就减去12,此方法适用于20世纪、21世纪,还适用于18世纪,六十一甲子,就会循环一次,把1900往前推60年,即1840年(第一次鸦片战争)肯定也是庚子年,带入公式 1840%12+9=13 结果大于12,然后减去12得1 ,所以1840年的年支为子。对于21世纪,带入2017,同样得到年支酉,经过大量测试,是没有问题的,作为一个有追求的程序员,怎么会止步于此,于是,后台程序就出来了
 
        protected void btnJudge_Click(object sender, EventArgs e)
        {
            //甲乙丙丁戊己庚辛壬癸   //子丑寅卯辰巳午未申酉戌亥
            string[] G = { "","","","","戊","","","","","" };
            string[] Z = { "","","","","","","","","","","","" };
           //獲取文本框值
            string year =txtYear.Text.Trim().ToString();
            string i = year.Substring(3,1);
            int Lasti = Convert.ToInt32(i);
            //計算年干
            Lasti =  Lasti > 3 ? Lasti - 3 : Lasti + 10 - 3;
            string YearG = G[Lasti-1];
            //計算年支
            int Lastz = Convert.ToInt32(year) % 12 + 9;
            Lastz = Lastz > 12 ? Lastz - 12 : Lastz;
            string YearZ = Z[Lastz-1];
            string All = YearG + YearZ;
            Response.Write("<script>alert(\'"+All+"\')</script>");
            
        }

对于文本框输入值合不合法,则是在前台进行判断

    <script type="text/javascript">
        $(function () {
            $("#btnJudge").click(function () {
                var num = /\\d/;
                var Year = parseInt($("#txtYear").val());
                if (!num.test(Year)) {
                    alert("請輸入一個合法年份");
                    return false;
                }
                else if (Year < 999 || Year > 9999) {
                    alert("請輸入一個介於999~9999的年份");
                    return false;
                }
             
            })
        });
    </script>

对于月份的算法,这就比较复杂了,需要查询月干表,如现在还是丙申猴年的腊月,那么查下表可得,月支为 辛丑 

然而在程序员的眼中,这只是一个二维数组而已,创建了此表,然后根据年干和月份来查询月支即可,仅此而已。

关于这些皮毛,个人只是兴趣爱好,中华文明,博大精深,而现代社会的高速发展,让身边的人都忙忙碌碌,或许是无暇顾及其它,让人不由得想起了那句:子在川上曰,逝者如斯夫

 

以上是关于干支纪年算法的主要内容,如果未能解决你的问题,请参考以下文章

LQ0249 干支纪年程序填空

天干地支的来历

27 October in ss

以下代码片段的算法复杂度

有人可以解释啥是 SVN 平分算法吗?理论上和通过代码片段[重复]

片段(Java) | 机试题+算法思路+考点+代码解析 2023