2027年是丁未年。要理解这句话,不能只看公历年份的数字,也不能把年份末尾的数字直接当成天干地支。天干地支是一套按固定次序循环的纪年方法,天干有十个,地支有十二个,两组各自轮转,再按照规定的配对次序组成六十个干支。公历年份则依照格里高利历计数,两套历法的起点、边界以及表达目的都不相同。把两者放在一起计算,需要先说明采用哪一种年份界线,再把公历年份映射到六十甲子循环之中。
天干地支简称干支。十天干依次是甲、乙、丙、丁、戊、己、庚、辛、壬、癸。十二地支依次是子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥。把天干排成一列,把地支排成另一列,从甲子开始,每一步两边各向后移动一位。甲之后是乙,子之后是丑,所以甲子之后为乙丑。继续向前,序列会经过丙寅、丁卯、戊辰,最后抵达癸亥。下一步,天干回到甲,地支回到子,循环重新开始。
两个序列的长度不同,是六十甲子形成六十种配对的关键。十和十二的最小公倍数是六十,因此两边各自前进六十步后,才会同时回到起点。这个性质说明干支纪年每六十年复现一次。某个年份若对应甲子,六十年之后又会对应甲子。只知道年份所在的某个较大周期,还不足以决定该年干支;实际计算时需要把公历年份放在一个已知的参照年份旁边,计算两者的差距,再按六十取余。
常见的公历年份算法把1984年定作甲子年。用这个参照点,先设公历年份为Y,再计算Y减1984的结果。把这个差值除以六十,所得余数记作R。余数可能是零,也可能从一到五十九。R为零时,年份与1984年处于同一干支位置,也就是甲子。R为一时,向后数一个位置,得到乙丑。R为二时,得到丙寅。如此继续,余数为五十九时,得到癸亥。
这项计算也可以拆成两个较短的部分。天干每十年回到同一位置,地支每十二年回到同一位置。把Y减1984的结果除以十,所得余数用于确定天干;把同一个差值除以十二,所得余数用于确定地支。余数都从零开始编号,零对应各自序列的第一个字。天干余数零是甲,余数一是乙,余数二是丙。地支余数零是子,余数一是丑,余数二是寅。求出两个余数之后,把相应天干和地支并排读出,便得到该年份的干支。
分开计算时有一个必须留意的地方。两个余数只能形成干支序列中允许出现的组合,并不是任意天干都能和任意地支相配。比如甲子是一个有效组合,甲丑却不是六十甲子中的一项。以公历年份的差值分别对十和十二取余,能够保证结果来自同一轮逐位前进的过程,所以产生的是有效干支。若另外随意挑选天干和地支,再把它们拼在一起,就可能得到不在六十甲子中的组合。
用2027年作例子,先计算2027减1984,结果为43。43除以十,余数为3。按天干顺序从零编号,零是甲,一是乙,二是丙,三是丁,所以天干为丁。43除以十二,余数为7。地支从零开始,零是子,依次往后数,七对应未,所以地支为未。把两字合在一起,2027年对应丁未。若用整组序列核对,从甲子向后数四十三位,同样会落在丁未。
余数的编号方式很容易造成一位偏差。有人先把甲当作数字一,再直接用普通除法的余数查表,结果可能把甲子算成乙丑,或让余数零无处安放。比较稳妥的做法,是先明确从零开始编号,然后按照余数查表。也可以用完整的六十甲子列表,把余数当成从起点前进的步数。余数为零就停在甲子,余数为一就前进一步。两种办法都能算出结果,关键在于表格编号和计算规则必须一致。
如果使用程序计算,取余运算还要考虑负数。公历年份早于1984年时,Y减1984会是负数。有些程序语言把负数取余的结果保留为负值,有些则给出非负余数。直接把负余数当作数组下标,可能会查到错误位置,甚至发生越界。若希望余数始终落在零至五十九之间,可以先计算Y减1984,再加上足够的六十倍数,最后对六十取余。更一般地,可以把结果写成先取余,再加六十,之后再次取余。这样得到的数总在零至五十九范围内。
用完整周期求干支,写成公式就是先把Y减1984对六十取余,取得结果后再加六十取余,以确保负年份也能得到非负位置。这个位置对应六十甲子列表的数组下标。若按从零开始的数组存放甲子、乙丑、丙寅等项目,那么取出的项目就是年份干支。若程序里的列表从一开始编号,就必须调整下标,不能把数学上的零直接当作第一项的编号。程序错误常常不出在历法本身,而是出在编号习惯没有说清楚。
分开计算天干和地支时,规则可以写成两条索引关系。天干索引是Y减1984对十取余之后再加十取余。地支索引是Y减1984对十二取余之后再加十二取余。随后分别从天干表和地支表中取出对应位置。把这两项合成一个年份名称即可。这里的十和十二不能互换,天干表的长度是十,地支表的长度是十二。若把两个表长度写反,某些年份会出现看似合理、实际周期不对的答案。
1984年这个参照点并非凭空挑选。它对应甲子这一已知干支年份,因而可以作为计算公历年份干支的锚点。只要参照年份和对应干支都正确,任意相差六十的公历年份都会得到相同结果。也可以换成其他已经核实的年份作为起点,但公式里必须同时换掉起点年份与起点干支。若把参照年份换了,却仍按甲子作为起点,后面的计算会整体错位。
参照点法的好处是简单,手算和编程都方便。它不必把古代历法的所有规则重新推演一遍,只需要明确采用的干支年份边界,并依照周期换算。对于一般的公历年份查询,这种方法足够直接。使用者仍须区分它回答的问题:它通常给出某个公历年份在常见干支纪年规则下的年名,并不自动判断某一天是否已经跨入新干支年,也不负责换算生日、节气或其他历法信息。
年份边界是实际应用中最容易发生争议的部分。公历的一年从一月一日开始,到十二月三十一日结束。干支年在不同语境中,可能依农历正月初一划分,也可能依立春时刻划分。很多民俗场合谈生肖年份时,使用农历新年作为切换点。部分命理排盘规则则把立春作为年柱转换点。二者并不是同一日期,农历新年通常在公历一月下旬至二月中旬之间,立春则大多落在公历二月初。某些年份里,两个节点相隔多日。
对整年进行概括时说2027年是丁未年,通常是在给出公历年份对应的年名。若问题涉及2027年年初某一天属于哪个干支年,就不能只把年份数字代入公式后直接下。还要先确定询问者采用农历新年还是立春作为年界,再查明该年边界发生的具体日期和时刻。边界之前的日期可能仍属于上一干支年,边界之后才进入丁未年。只要问题精确到日期,这一步就不能省略。
农历新年本身也不是固定在公历同一天。农历月份依朔望月安排,闰月又会影响后续月份的排布,所以春节日期每年都有变化。单凭公历年份无法推断某个日期是否已经进入新年。要处理具体日期,需要可信的农历日期资料,或依照经过验证的历法算法换算。只拿公历年份计算出丁未,再把这个结果套到当年一月的每一天,可能会把仍处于上一干支年的日期也标成丁未。
立春是二十四节气之一,精确时刻会因年份而异。若规则把立春设为干支年分界,就必须比较目标日期的时刻和该年立春的时刻。目标时刻在立春之前,按这类规则仍处于上一干支年;落在立春之后,才属于新一干支年。只知道公历日期而不知道具体时区,在临近节气边界时也可能不足以作出准确判断。面向一般读者时,说明年名即可。面向排盘、天文历算或历史记录时,边界与时刻都要交代清楚。

公历年份算法与农历年份名称之间存在关联,但不能把它们混为一谈。计算出丁未,只能说明在指定的纪年规则下,年份干支是丁未。它不会直接告诉人们某个农历月份有几天,也不会给出该年是否置闰,更不能代替公历和农历之间的完整换算。若需要知道某个公历日期对应的农历月日,应使用相应的历法换算资料。若只想知道生肖,也仍要确认该日期是否越过采用的生肖年界。
天干和地支还各有阴阳属性。传统排列中,甲、丙、戊、庚、壬属阳干,乙、丁、己、辛、癸属阴干。地支也按阳、阴交替排列,子属阳,丑属阴,寅属阳,卯属阴,依次类推。六十甲子逐位配对时,阳干会与阳支相遇,阴干会与阴支相遇。这是因为两列每次都前进一位,配对的阴阳属性同步变化。这个规律也能用来检查干支组合:若算出阴阳不相配的天干和地支,通常说明查表、编号或取余过程出了差错。
在具体查表时,完整六十甲子表可以作为直观的核对工具。表从甲子起,按每一步一干一支的方式排列,序号采用零到五十九。给定公历年份后,先算出相对1984年的差值,再将差值规整到零至五十九的范围,最后按位置取表。列表的开头应是甲子、乙丑、丙寅、丁卯、戊辰、己巳。列表末尾应是己未、庚申、辛酉、壬戌、癸亥。甲子之后重新进入甲子。若表尾不是癸亥,或甲子之后没有乙丑,列表次序就需要检查。
手工推算时,也可以利用十年和十二年的周期分别校验。对2027年而言,差值43对十取余得到3,指向丁。差值43对十二取余得到7,指向未。再检查丁是阴干,未是阴支,阴阳相配。还可以把2027与相近的已知年份比较。2025年相对于1984年的差值是41,得到乙巳。2026年再向后一步,是丙午。2027年接着是丁未。相邻公历年份在正常的干支序列中应各向前移动一位,这为计算提供了第二种核对方式。
相邻年份核对并不能取代参照点计算。如果每一步都在前一年结果上加一,某处一旦写错,错误就会继续传播。把结果和固定参照点对照,可以减少这种累积风险。查历史长序列时尤其如此。先用1984年确定基准,再对选定年份做公式计算,最后检查相邻年份是否连贯,三种检查各有作用。固定基准负责整体定位,相邻年份负责发现断点,完整六十甲子表负责核对序号。
常见错误之一,是把公历年份的末两位直接映射到天干。天干确实每十年重复一次,但年份的天干并不是简单地取公历年份末位即可查得,必须把采用的编号起点说清楚。仅凭数字7推断2027年的天干为丁,容易在换用其他对照规则时产生偏差。可靠的计算需要参照年,或明确写出的公式。数字末位可以辅助记忆,不能取代规则说明。
另一个常见错误,是认为地支只由年份末位决定。十二年一轮与十年一轮并不相同,地支周期无法用公历年份个位数完整表达。2027年的未支,是把2027与甲子参照年相减后,对十二取余得到的结果。若直接看末位7,再随意配一个地支,往往只是在偶然情况下得到正确答案。要解释计算过程,就应展示参照年份、差值、取余结果以及查表位置,而不是只写结果。
还需要避免把生肖与地支当成完全相同的概念。十二生肖通常对应十二地支,未对应羊,因而丁未年常被称作羊年。但生肖年份也有年界问题,具体日期落在哪一个生肖年,仍需遵循特定边界。生肖只是常见文化表达,地支则是干支体系中的一个组成部分。把某一年称为羊年,并不会自动解决该年年初的日期归属,也不会说明其天干是丁。
把公式写进电子表格时,最好把参照年份与结果序列分开设置。年份放在一个单元格,1984放在另一个单元格,差值由公式计算。天干表与地支表分别按固定顺序排列,之后依余数取出文字。这样调整参照年份或检查顺序时,不必在一条很长的公式里反复找数字。若工作表需要处理公元前的历史年份,还要特别检查电子表格对负数取余的行为,以及它采用的年份编号体系。
历史年份还有另一层限制。现代常用的公元纪年没有公元零年,公元前一年之后直接是公元一年。很多程序和天文学计算会为了连续算术方便而使用包含零年的编号体系。若把历史资料里的公元前年份直接当作带负号的整数,计算结果可能与历史纪年对应错一年。针对古代年份编写程序时,应先说明公元前后年份如何编码,再确定参照年份。只处理现代公历年份时,这类问题通常不会出现,但不应把现代简式无条件套到所有历史年代。
不同历法的年数递增方式也不能混在一个公式里。1984年的参照规则针对公历年份编号。若输入的是某一朝代的年号年份、传统历法年份或经过改写的历史年份,必须先把它转换成相同的公历年份表示,或者另外建立可靠的锚点。公式中的Y不是任意一种年份数字,而是与1984年处于同一计数体系的公历年份。这个前提若没有满足,取余过程算得再准确也没有意义。
如果应用程序只显示年份标签,可以把输入限定为整数年份,并明确显示这是公历年份的干支对应。若应用程序接受日期,就应另外实现年界判断,并在界面或数据说明里标明采用的规则。不要让一个只处理年份数字的函数悄悄承担完整日期换算的工作。把年名计算和日期边界判断拆开,能够让每个函数只负责一件清楚的事,也方便分别测试。函数名称若写作干支年名,便不该暗示它已经处理节气时刻或农历新年。
测试用例可以从参照点开始。输入1984,应得到甲子。输入1985,应得到乙丑。输入2024,应得到甲辰。输入2025,应得到乙巳。输入2026,应得到丙午。输入2027,应得到丁未。再测试2044,距离1984整整六十年,应重新得到甲子。测试这些年份可以检查起点、相邻递增以及六十年回绕。还可以加入比1984更早的年份,确认负数余数处理正确。
更系统的测试方式,是对六十种余数逐一检查。可以把1984加上从零到五十九的每一个整数,依次计算干支,确认恰好遍历一次完整六十甲子。随后再把每个年份加六十,检查对应结果保持不变。分开计算天干和地支的实现,也可以把同一批结果与完整列表比对。若只测试2027一个点,可能发现不了数组下标偏移、循环末尾回绕或负数处理等问题。周期算法的测试应覆盖周期起点、周期末端、周期回绕和较早年份。
网页上的干支查询表通常只展示结果。若表格没有解释采用何种年界,用户容易把年名查询误认为日期换算。一个清楚的工具至少应写明年份输入代表公历年份,展示所用公式或参照点,并说明结果按哪种常用口径给出。用户查的是某个日期时,工具应要求输入年月日,不能只接收年份便声称判定了当天的干支年。信息不充分时,把限制直接标出来,比给出看似精确的更可靠。
对于只需快速查询的人,算法可以压缩成几句话。记住1984年为甲子。把目标公历年份减去1984。差值对十取余查天干,对十二取余查地支,余数从零开始。2027年与1984年相差43年,43对十余3,得到丁;43对十二余7,得到未;组合起来就是丁未。若问题落在年初边界附近,先确认采用春节还是立春作为分界。
把这套方法讲清楚,重点不在于背下某个年份的名称,而在于知道每一步为什么成立。六十甲子来自十天干和十二地支同步轮转。1984年提供了一个已知起点。目标年份与起点之间的差值决定前进步数。十年周期定位天干,十二年周期定位地支,六十年周期负责完整回返。取余后的编号要从零开始,负数要规整到有效范围。遇到具体日期,还要把年份算法和年界规则分开处理。
干支算法本身不复杂,出错通常是因为少写了一个前提。有人没有说明参照年份,有人从一开始编号,有人把年份名称直接套到一月的日期上,也有人把公历年份、农历年份和节气年视作同一种口径。把这些细节逐一说明之后,计算过程可以直接复核。对2027这个公历年份,按照1984年甲子的参照法,差值是43,天干余数为3,地支余数为7,对应丁未年。