翻日历这事,往深了扒就是一套时间定位系统。阳历盯着太阳转,阴历跟着月亮走,农历两头都得顾。日常说的“万年历”早不是墙上挂的那本厚纸,进化成了能掐会算的程序逻辑。

万年历本质是公历与农历的映射数据库加上节气、干支、星期推算规则的集合。公历部分用格里高利历法。一年三百六十五天,闰年多一天。闰年判定:年份能被四整除但不能被一百整除,或者能被四百整除。这套算法四百三十年前就定死了,没变过。农历麻烦。月球绕地球周期约二十九点五三天,十二个月下来三百五十四天左右,跟阳历差十一天上下。硬跟阳历对齐就得插闰月。十九年七闰,这是规律。具体哪年闰哪个月,不靠公式算,得查《紫金历》数据。官方授权的那份精准到秒的星历表。每版数据管几十年,到期得更新。手机上装的日历应用,后台都挂着这份表。

农历月相计算依赖定朔法,新月出现的精确时刻即为初一。干支纪日更死板,从某甲子日算起不间断循环,每六十天一轮。哪怕改朝换代,六十花甲子照转。甲子、乙丑、丙寅,顺序绝不乱。节气体现在太阳黄经度数。黄经零度春分,十五度清明,依此类推,每十五度一个节气。地球公转轨道是椭圆的,太阳视运动速度不均匀,节气间隔不固定。有的节气十五天,有的十六天。今年冬至到下一年冬至叫一回归年,三百六十五天五小时四十八分四十六秒。小数点后那堆零碎,每四年凑出个二月二十九。

星期制度纯人造。七天一循环跟天体无关,源自宗教习惯,后来成全球标准。万年历算星期有个现成公式:蔡勒公式或者基姆拉尔森公式。输入年月日,吐出星期几。编程课上拿来练手的那套东西。

万年历

公历农历换算麻烦在起始点。农历正月初一对应的公历日期每年跳。有时候一月二十几,有时候二月十几。公历二零二六年春节落在二月十七。二零二七年在二月六号。差值超过十天。农历月份大小不定,大月三十天小月二十九天,排列无周期。往年腊月是大月,今年可能变腊月小。全凭天文台观测结果定。观测月亮实际位置,跟太阳黄经差够数值就定朔。地球自转不均匀、月球轨道摄动全得考虑进去。民间老黄历跟官方授时中心发布的有时差,老黄历沿用清代《御定万年书》算法,精度跟现代天文数据对不齐。差一两天正常。日食月食那类天象更明显。

节气与农历月份绑定规则决定闰月位置,无中气之月置闰。每个农历月里必须包含一个中气。雨水、春分、谷雨这类偶数节气叫中气。如果一个农历月从初一到月底跨过去,没沾上任何中气,这个月自动成闰月。规则严丝合缝。偶尔也会出例外。公历一九八四年闰十月,下个闰十一月得等二零三三年。

万年历“万年”是夸张说法,实际有效范围受制于地球自转长期变慢与历法修订可能。一九二八年国民政府在南京颁过《民国十七年戊辰时宪书》。一九四九年改用公元纪年,农历并行。一九六九年紫金山天文台整编《中国天文年历》,之后每年出一本。电子万年历普遍覆盖一九零一年到二一零零年。再往前查或往后推,误差累积。公元一五八二年十月五号到十四号这段公历空白,改历时直接抹掉十天。阳历上那十天没存在过。中国农历里那十天是万历十年九月十八到二十七。历法切换瞬间,中西日期错位。写程序处理历史日期绕不过这个坑。

干支月跟农历月份两码事。干支月以节气分界。立春建寅,惊蛰建卯。今年立春在二月三号下午,那个时刻之前算上一年丑月。之后算寅月。属相按干支年走还是按立春走,民间跟官方各执一词。户口登记以正月初一为准。命理学按立春。万年历标注属相切换点得选边站,多数软件两套都标。

星期、干支、农历月相、公历、节气,五套系统叠一起。查一个日期,后台调五组数据。公历部分简单,农历部分靠查表,干支循环靠计数器,节气靠天文算法,星期靠公式。各干各的,输出在一屏显示。

手机待机状态显示锁屏农历日期,本质是短定时唤醒读取历表并刷新界面。成本极低。日历应用每隔段时间同步一次网络时间服务器。协议叫NTP,精确到毫秒。年月日时不会错。区时设定错会差出一整天。中国跨东五到东九区,统一用东八区。新疆本地作息跟北京时间差俩小时,日历显示还是同一个时间点。屏幕右上角数字一致,太阳实际位置不同。

万年历

老式机械万年历用齿轮组模拟这些周期。一百二十齿的齿轮跟五十九齿的啮合。调一次管几十年。电子化之后用单片机存数据表。TP日历芯片内置一百年农历。过保就得换。公历日期、星期、农历月日、干支、节气、纪念日,屏幕循环切。

找某年春节对应的公历,反向查公历对应农历,翻到公元前后汉初的日期,那时用的是《颛顼历》,十月为岁首。跟现在用的《授时历》体系完全不同。万年历这概念,说的是随时能查,过去未来任意一天都能对上号。前提是历法规则不变、数据表够准、芯片不停电。