☰
周易排盘源码解析:四柱、节气与干支历的工程实现
2026/11/5 5:49:14 网站建设 项目流程

简介:这份《周易排盘源码》是一套基于ASP语言开发的在线周易预测工具,面向易学爱好者、Web开发者以及希望研究传统术数算法实现的技术人员,可用于搭建八字、六爻与奇门遁甲三类在线排盘功能。资源以rar压缩包形式提供,整体约503KB,上游未提供具体文件数量与类型明细,从描述看应包含ASP页面、脚本与相关配置等源码文件,上传服务器后即可运行。已有3208人学习下载,具备一定的参考热度。源码中八字模块涉及生辰输入验证、干支转换、五行属性分析及大运流年推算;六爻模块涵盖随机摇卦模拟、卦象生成与动爻爻辞引用;奇门遁甲则需处理九宫布局、八门九星八神对应等复杂运算。对开发者而言,可借此理解ASP处理用户输入、数据计算与页面展示的核心逻辑,是学习传统易学算法与Web交互设计的实用素材。

1. 从一份排盘源码说起:它到底能算什么

前阵子帮朋友看一个做传统文化内容的小程序,他想要一个能自己算、自己改的排盘工具,而不是调别人接口、数据还回不来的那种。翻了几份源码后,我盯上了这份「周易排盘源码」——它把四柱、节气、干支历、五行生克这些底层逻辑都摊在代码里,输入一个公历时间,能吐出年柱、月柱、日柱、时柱,再往下接大运、流年、十神这些衍生信息。适合两类人:一类是想跑起来看效果的开发者,装个运行环境、改个日期就能出结果;另一类是准备二次开发、把它嵌进自己的内容站或工具类应用的人,源码在手,排盘规则、输出格式都能按自己的需求改。下面我按「能干什么 → 怎么跑 → 怎么改」的顺序,把这份源码拆开讲。

2. 项目定位与技术选型:为什么用这套结构做排盘

2.1 排盘这件事,难点不在界面在历法

很多人第一反应是排盘不就是查表吗,真上手写才发现坑全在时间换算上。公历日期要转成干支历,年柱不是按元旦切,而是按立春切;月柱不是按月初切,而是按节气切;日柱要连续推算不能断;时柱还要处理早晚子时的归属问题。这份源码把这些规则拆成了独立的计算层,界面层只负责收集输入和展示结果,历法换算、干支推算、五行判定各自成模块。这种分层的好处是,你改排盘规则时不用动界面,换界面时也不用碰算法,二次开发时心里有底。

从技术选型看,这类项目常见做法是纯前端 JavaScript 实现,浏览器里直接跑,不依赖后端服务,好处是部署简单、数据不出本地;也有用 Python 写的版本,方便做批量计算或接数据分析。源码里如果带了节气数据表,一般是把若干年的节气时刻预先算好存成数组或 JSON,运行时按年份查表再插值,避免每次都跑天文算法。我一般会先确认节气数据覆盖的年份范围,这决定了这个工具能算哪一段时间的盘,超出范围要么报错要么结果失真。

2.2 目录结构:先认清哪块该动、哪块别碰

拿到源码先别急着改,花十分钟把目录过一遍,后面能省很多返工。这类排盘项目典型的目录大致是这样组织的:

zhouyi-paipan/ ├── index.html # 入口页面,输入表单 + 结果展示 ├── src/ │ ├── calendar.js # 公历/农历/干支历换算 │ ├── solar-terms.js # 节气数据与查询 │ ├── bazi.js # 四柱排盘核心逻辑 │ ├── wuxing.js # 五行、十神、纳音判定 │ └── render.js # 结果渲染与格式化 ├── data/ │ └── solar-terms.json # 预计算节气时刻表 └── assets/ # 样式与静态资源

calendar.js和solar-terms.js是地基,动它们要格外小心,改错一个节气边界,整年的月柱都会偏。bazi.js是业务核心,四柱怎么排、早晚子时怎么处理都在这。wuxing.js偏规则判定,十神、纳音这类映射表改起来相对安全。render.js和index.html是展示层,想换皮肤、加导出功能,主要动这两块。认清这条边界,后面改造时就不会一改界面把算法带崩。

2.3 核心数据流:一次排盘请求走了哪几步

把一次排盘从输入到输出的链路理清楚,比读十遍代码都管用。用户填一个公历日期和时间,前端拿到后先做时区与真太阳时的校正(如果源码支持),然后进历法换算层,把公历转成干支历的年月日时,再进排盘核心算出四柱,最后进规则层补十神、五行、纳音,交给渲染层输出。这条链路里任何一环出错,结果都会错,所以调试时最好在每一环打日志,看中间值对不对。

// 排盘主流程示意:输入公历时间,输出四柱与衍生信息 function paipan(input) { // 1. 时间校正:处理时区、可选的真太阳时 const corrected = correctTime(input.date, input.time, input.longitude); // 2. 历法换算:公历 -> 干支历 const ganzhi = toGanZhiCalendar(corrected); // 3. 四柱排盘:年柱按立春、月柱按节气、日柱连续推、时柱按日干起 const sizhu = buildFourPillars(ganzhi); // 4. 衍生信息:十神、五行、纳音 const extra = buildExtraInfo(sizhu); return { sizhu, extra }; }

这段是主流程的骨架,correctTime负责把用户输入的公历时间做校正,longitude参数用于真太阳时换算,不需要的话可以传空。toGanZhiCalendar是历法换算的核心,内部会调节气表判断年柱和月柱的边界。buildFourPillars按规则拼出四柱,buildExtraInfo补十神和五行。实际源码里函数名可能不同,但这条数据流基本一致,照着这条线读代码,比从头到尾逐行看快得多。

3. 跑起来:环境准备与第一次排盘

3.1 环境准备:纯前端项目最省事

如果源码是纯前端实现,跑起来几乎没有门槛,一个静态服务器就够。我一般用 Node 自带的 http-server 或者 Python 的 http.server,避免直接双击打开 HTML 时遇到跨域读不到 JSON 的问题。

# 方式一:Node 环境,全局装一个静态服务器 npm install -g http-server cd zhouyi-paipan http-server -p 8080 # 方式二:Python 环境,零依赖 cd zhouyi-paipan python3 -m http.server 8080

两条命令任选其一,浏览器打开http://localhost:8080就能看到输入页面。这里用静态服务器而不是直接开文件,是因为节气数据放在data/solar-terms.json里,页面通过 fetch 读取,直接开文件协议会被浏览器拦掉,这是新手最容易翻车的一步。如果源码是 Python 版本,那就先建虚拟环境再装依赖:

python3 -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install -r requirements.txt python app.py

requirements.txt里通常只有少量依赖,装完直接跑入口文件即可。虚拟环境这一步别省,排盘项目有时会用到特定版本的日期库,全局环境里版本冲突排查起来很费时间。

3.2 第一次排盘:拿一个已知结果的时间验证

跑起来之后别急着试各种日期,先拿一个你手头有标准答案的时间去验证。比如输入 1990 年 1 月 1 日中午 12 点,看输出的年柱是不是按立春算的、月柱有没有跨节气、日柱和时柱对不对。这一步是给自己建立信心,也是后面排查问题的基准。

// 在浏览器控制台直接调排盘函数,绕过界面看原始输出 const result = paipan({ date: '1990-01-01', time: '12:00', longitude: 116.4 // 可选,真太阳时校正用 }); console.log(result.sizhu); // 看四柱 console.log(result.extra); // 看十神、五行

在控制台直接调函数的好处是能看到中间结构,不被界面格式化掩盖。longitude传你所在地的经度,不传就按标准时区算。如果结果和预期对不上,先别怀疑算法,优先检查三件事:节气数据覆盖的年份对不对、时区设置有没有偏、输入时间格式是不是被解析错了。这三样占了我遇到问题的一大半。

3.3 结果解读:四柱之外那些字段怎么用

排盘结果里除了四柱,通常还有十神、五行分布、纳音、大运这些字段。十神是根据日干和其他干支的关系推出来的,用来描述五行生克的相对位置;五行分布是统计八字里金木水火土各占多少,很多工具会画个简单的比例条;纳音是另一套映射,按六十甲子查表。这些字段的计算逻辑大多在wuxing.js里,属于规则映射,改起来风险低。

理解这些字段的用途,对二次开发很关键。比如你想做一个「五行缺什么」的提示功能,直接读五行分布字段就行,不用自己再算一遍。想加大运流年,就在四柱基础上按规则推,源码里如果没带这块,就得自己补,补的时候注意大运起运的规则和节气、性别都有关,不是简单加十年。第一次跑通后,建议把每个输出字段都打印出来看一遍,知道每个字段从哪来、代表什么,后面改起来才不会误伤。

4. 核心模块拆解:四柱排盘的关键代码

4.1 年柱与月柱:立春和节气是两条硬边界

年柱和月柱是排盘里最容易出错的地方,因为它们的切换点不是自然月,而是立春和各个节气。年柱以立春为界,立春之前算上一年;月柱以节气为界,每个月的开始是「节」而不是「中气」。源码里通常有一个节气查询函数,输入年份返回该年各节气的具体时刻,然后拿用户时间跟这些时刻比大小。

// 判断年柱:以立春时刻为界 function getYearPillar(date, solarTerms) { const lichun = solarTerms.get('lichun', date.getFullYear()); // 立春之前,年柱归上一年 const year = date < lichun ? date.getFullYear() - 1 : date.getFullYear(); return ganZhiOfYear(year); // 按干支纪年换算 } // 判断月柱:找到当前时间落在哪个节气区间 function getMonthPillar(date, solarTerms) { const terms = solarTerms.listOfYear(date.getFullYear()); // 从后往前找最后一个早于当前时间的「节」 for (let i = terms.length - 1; i >= 0; i--) { if (date >= terms[i].time && terms[i].isJie) { return ganZhiOfMonth(terms[i].monthIndex, getYearStem(date)); } } }

getYearPillar里solarTerms.get('lichun', year)取的是该年立春的精确时刻,date < lichun这个比较决定了年柱归属,边界当天出生的人尤其要注意。getMonthPillar遍历该年节气列表,从后往前找最后一个早于当前时间的「节」,isJie用来区分节和中气,只有节才换月柱。getYearStem取年干,因为月干是由年干推出来的,这是五虎遁的规则。这段逻辑改的时候,节气数据的时间精度直接决定边界判断准不准,数据表如果只精确到天,边界附近出生的人就可能排错。

4.2 日柱与时柱:连续推算和早晚子时

日柱的难点在于它必须连续,不能靠年份直接映射,常见做法是选定一个基准日,算出目标日期与基准日相差多少天,再对六十取模。时柱则要处理早晚子时:晚上 23 点到 24 点算当天的子时还是第二天的子时,不同流派有不同处理,源码里一般会有一个开关或者固定一种规则。

// 日柱:基准日 + 天数差,对 60 取模 function getDayPillar(date) { const baseDate = new Date('1900-01-31'); // 基准日,对应某个已知干支 const baseIndex = 40; // 基准日的六十甲子序号 const diffDays = Math.floor((date - baseDate) / 86400000); const index = ((baseIndex + diffDays) % 60 + 60) % 60; return SIXTY_JIAZI[index]; } // 时柱:按日干起时干,处理早晚子时 function getHourPillar(date, dayStem, lateZiAsNextDay) { let hour = date.getHours(); let stemBase = dayStem; // 晚子时归次日:23 点后日干顺延一位 if (lateZiAsNextDay && hour >= 23) { stemBase = (dayStem + 1) % 10; } const branch = Math.floor(((hour + 1) % 24) / 2); // 时辰地支 return ganZhiOfHour(stemBase, branch); }

getDayPillar里baseDate和baseIndex必须成对正确,基准日选错或者序号对不上,后面所有日柱全错,这是血泪经验,改之前一定先验证基准。diffDays用毫秒差除以一天的毫秒数,注意时区会影响结果,最好先把时间归一到当天零点再算。getHourPillar的lateZiAsNextDay参数控制早晚子时规则,stemBase在晚子时顺延一位,branch由小时数换算成十二时辰。这个开关建议做成配置项暴露出来,不同用户对流派的偏好不一样。

4.3 五行与十神:规则映射层怎么组织

五行和十神本质上是查表和简单运算,但表要组织得清楚,不然改起来容易乱。常见做法是把天干地支的五行属性、阴阳属性做成常量对象,十神则根据日干和其他干的生克关系加阴阳异同来判定。

// 天干地支的五行、阴阳属性表 const GAN_WUXING = { 甲:'木', 乙:'木', 丙:'火', 丁:'火', 戊:'土', 己:'土', 庚:'金', 辛:'金', 壬:'水', 癸:'水' }; const ZHI_WUXING = { 子:'水', 丑:'土', 寅:'木', 卯:'木', 辰:'土', 巳:'火', 午:'火', 未:'土', 申:'金', 酉:'金', 戌:'土', 亥:'水' }; // 十神判定:以日干为参照,看生克关系与阴阳异同 function getShiShen(dayStem, targetStem) { const me = GAN_WUXING[dayStem]; const other = GAN_WUXING[targetStem]; const sameYinYang = isSameYinYang(dayStem, targetStem); if (me === other) return sameYinYang ? '比肩' : '劫财'; if (generates(me, other)) return sameYinYang ? '食神' : '伤官'; if (controls(me, other)) return sameYinYang ? '偏财' : '正财'; if (controls(other, me)) return sameYinYang ? '七杀' : '正官'; if (generates(other, me)) return sameYinYang ? '偏印' : '正印'; }

GAN_WUXING和ZHI_WUXING是两张基础映射表,改属性直接改这里。getShiShen先取日干和目标干的五行,再判断阴阳是否相同,然后按生克关系分五组,每组再按阴阳分正偏。generates和controls是五行生克判断的小函数,木生火、火生土这类规则写死在里面。这一层的好处是规则集中,想加纳音或者神煞,照着同样的模式加映射表就行,不会污染排盘主逻辑。

5. 避坑与排查:排盘结果不对时先看这几处

5.1 现象:年柱在年初出生的人身上总是差一位

原因多半是年柱边界用了元旦而不是立春。公历 1 月到 2 月初出生的人,按立春算还属于上一年,如果代码里用getFullYear()直接当年份,就会多算一年。解决方法是把立春时刻查出来做比较,date < lichun时年份减一,并且确认节气数据里立春的年份键和查询年份对得上,别出现查 2024 年立春却拿到 2023 年数据的情况。

5.2 现象:月柱在节气当天前后对不上

原因是节气时刻的精度不够,或者比较时用了日期没用到时分。节气是精确到分钟的,如果数据表只存了日期,边界当天出生的人就会排错。解决方法是确认solar-terms.json里每个节气都带完整时间戳,比较时用完整时间而不是只比日期。另外注意「节」和「中气」要分开,只有节换月柱,中气不换,源码里如果没区分,月柱会多换一次。

5.3 现象:日柱整体偏移一天

原因是基准日和基准序号不匹配,或者天数差计算受时区影响。new Date('1900-01-31')在不同时区解析出来的时刻可能差几小时,除以一天的毫秒数后取整就可能少一天或多一天。解决方法是在算天数差之前先把两个时间都归一到当天零点,用setHours(0,0,0,0)处理,再算差值。改完拿几个已知日柱的日期回归验证,别只测一个。

5.4 现象:晚子时出生的人时柱和日柱对不上

原因是早晚子时规则没统一。有的实现里 23 点后日柱进第二天、时柱也按第二天算,有的只进时柱不进日柱,两种规则混用就会自相矛盾。解决方法是把lateZiAsNextDay这类开关做成显式配置,日柱和时柱共用同一个开关,别一个地方写死一个地方读配置。改完专门测 23:00 到 23:59 这个区间,这是最容易漏测的时段。

5.5 现象:页面打开空白,控制台报跨域或 404

原因是直接双击打开了 HTML,fetch 读不到本地 JSON,或者静态服务器的根目录指错了。解决方法是起一个静态服务器,确认访问路径下data/solar-terms.json能直接打开。如果 404,检查服务器启动目录是不是项目根目录,路径大小写是否一致,Linux 下大小写敏感,Windows 下不敏感,换环境部署时这个问题很常见。

6. 二次开发:把排盘能力接进自己的项目

6.1 先定改造边界:算法层只读,展示层随便改

二次开发最忌讳一上来就大改。我的习惯是先把calendar.js、solar-terms.js、bazi.js标成只读区,除非确认有 bug,否则不动;wuxing.js和render.js是改造区,加字段、换展示都在这。想加一个「五行分布图」,就在render.js里读extra的五行统计,画个比例条,完全不碰算法。想支持导出图片,也是展示层的事。这条边界守住了,后面迭代再快也不会把排盘结果改错。

6.2 扩展输出:加神煞、加大运的落地方式

源码如果没带神煞和大运,扩展时照着现有模式加就行。神煞是查表加条件判断,建一张神煞规则表,按日干或年支去匹配;大运要按起运规则推,和节气、性别、年干阴阳都有关,推的时候把中间值打出来核对。加完之后别只测一个盘,拿十几个不同年份、不同性别的样例跑一遍,看输出结构是否稳定。验证方法很简单:同一份输入跑两次结果必须一致,不同输入之间的差异要能解释得通。

改造点动哪个文件风险验证方式
换展示样式render.js / assets低页面目测 + 导出检查
加五行图表render.js低对比统计数值
加神煞wuxing.js + 新表中多组样例回归
加大运bazi.js 新增模块中高起运时刻人工核对
改节气数据范围solar-terms.json高边界年份重点测

6.3 一个具体技巧:把排盘函数抽成纯函数方便测试

改造时我一般会把paipan抽成不依赖 DOM 的纯函数,输入一个对象、输出一个对象,界面只负责调它和渲染。这样写单元测试特别方便,拿一批已知结果的时间做断言,改算法前后跑一遍,回归问题立刻暴露。纯函数还有个好处是能直接搬到 Node 里跑批量计算,做数据统计或者生成内容时不用开浏览器。抽的时候注意把时区、真太阳时这些外部依赖做成参数传进来,别在函数内部读全局配置,不然测试还是不好写。

// 纯函数版排盘,便于测试和批量调用 function paipanPure({ date, time, longitude = null, lateZiAsNextDay = true }) { const corrected = correctTime(date, time, longitude); const ganzhi = toGanZhiCalendar(corrected); const sizhu = buildFourPillars(ganzhi, { lateZiAsNextDay }); return { sizhu, extra: buildExtraInfo(sizhu) }; } // 测试用例:断言已知时间的排盘结果 const out = paipanPure({ date: '1990-01-01', time: '12:00' }); console.assert(out.sizhu.year === '己巳', '年柱不符');

paipanPure把所有外部依赖收进参数,lateZiAsNextDay显式传入,测试时想切规则直接改参数。console.assert只是示意,正式项目里换成测试框架的断言。这套写法我从一个排盘项目踩坑之后就一直沿用:那次改月柱逻辑,界面测着没问题,结果批量跑历史数据时发现边界年份全偏了,因为没有纯函数、没法批量回归。从那以后我每次动算法层之前,都强制先把纯函数和测试用例补齐再改,宁可多花半小时,也不想到上线后才发现整年的盘都是错的。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询