排盘引擎里,争议最大、实现分歧最多的地方,不是什么高深算法,是每天晚上的 23 点到凌晨 1 点。
按十二时辰,23 点到 1 点都是子时。但这两天之间隔着午夜零点——于是子时被劈成了两半:23 点到 0 点叫晚子时(夜子时),0 点到 1 点叫早子时。
麻烦在这:日柱什么时候换?晚子时出生的人,日柱算今天还是算明天?
传统上一直有两派:一派主张“子时一到即换日”——23 点起就算次日;另一派主张“午夜才换日”——晚子时仍算当天,只是时柱用子时。
两派都有传承依据,都有拥护者。这不是一个技术问题,是一个学派立场问题——但引擎必须给出一个确定的行为。
▲ 一行配置,背后是两派传承
面对两派分歧,我们的做法是:引擎不替用户选立场,把规则做成可配置。
日柱切换模式提供两个选项:“23 点换日”与“0 点换日”。默认值取多数派共识,但每一次排盘,页面都会标明当前用的是哪种口径。
为什么标明?因为用户拿着两个软件对盘,第一句往往是“怎么你们的日柱不一样”。同样的生日、不同的换日规则,日柱当然可能不同——这不是谁错了,是口径不同。把口径亮出来,误会就消失了大半。
工程上还有一个必须处理的细节:晚子时的时柱。无论换不换日,时柱的天干都得按“次日子时”起——这是两派都认的“夜子时起五鼠遁次日”。日柱和时柱在这个问题上是分开处理的,实现时千万别绑死。
▲ 边界处多测一秒,线上少修一夜
子时是典型的边界逻辑,测试必须卡在边界两侧。
基础用例两组:23:59:59 与 00:00:01。在两种换日模式下,日柱是否按预期切换,一个都不能含糊。
然后叠一层:换日 + 交节同日。立冬当天 23:30 出生,月柱要按交节时刻判,日柱要按子时规则判,两套规则同时生效——这是最容易翻车的组合。
再叠一层:真太阳时叠加。北京时间 22:50,出生地在东经 80 度,太阳时已经是 21:20——还没到子时;反过来,北京时间 22:30 而太阳时已过 23 点的西部城市也存在。换不换日,得用校正后的时间判,不是用钟表时间判。
三层叠完,这条边界才算测干净。历法系统里最贵的 if 往往只有一行——贵在你想不到它会在哪被触发。
早子时晚子时,是排盘引擎的必修课。
规则可以有立场,实现必须透明——这是我们对这类分歧问题的一贯做法。
午夜前后两小时,藏着一个行业一半的争议。
💡 你习惯哪种换日口径?你在别的软件上遇到过日柱对不上的情况吗?评论区聊聊。

