简介这份《周易排盘源码》是一套基于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.pyrequirements.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原因是直接双击打开了 HTMLfetch 读不到本地 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只是示意正式项目里换成测试框架的断言。这套写法我从一个排盘项目踩坑之后就一直沿用那次改月柱逻辑界面测着没问题结果批量跑历史数据时发现边界年份全偏了因为没有纯函数、没法批量回归。从那以后我每次动算法层之前都强制先把纯函数和测试用例补齐再改宁可多花半小时也不想到上线后才发现整年的盘都是错的。希望帮到你。本文还有配套的精品资源点击获取