dsh-metaphysics 0.62.2 → 0.62.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,13 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="470" height="28" role="img" aria-label="公开对拍:0 处不符|128 例 · 5 剔除 · 312 紫微 · 20 奇门 · 12 交运">
2
- <title>公开对拍:0 处不符|128 例 · 5 剔除 · 312 紫微 · 20 奇门 · 12 交运</title>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="455" height="28" role="img" aria-label="公开对拍:0 处不符|128 例 · 5 剔除 · 127 未核 · 312 紫微 · 20 奇门 · 12 交运">
2
+ <title>公开对拍:0 处不符|128 例 · 5 剔除 · 127 未核 · 312 紫微 · 20 奇门 · 12 交运</title>
3
3
  <linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient>
4
- <rect width="470" height="28" rx="4" fill="#555"/>
5
- <rect x="62" width="408" height="28" rx="4" fill="#1f6f3f"/>
6
- <rect x="62" width="408" height="28" fill="url(#s)"/>
4
+ <rect width="455" height="28" rx="4" fill="#555"/>
5
+ <rect x="62" width="393" height="28" rx="4" fill="#1f6f3f"/>
6
+ <rect x="62" width="393" height="28" fill="url(#s)"/>
7
7
  <rect width="66" height="28" rx="4" fill="#555"/>
8
8
  <rect x="62" width="4" height="28" fill="#555"/>
9
9
  <g fill="#fff" text-anchor="middle" font-family="Verdana,DejaVu Sans,sans-serif" font-size="11">
10
10
  <text x="33" y="18">对拍</text>
11
- <text x="266" y="18">0 处不符|128 例 · 5 剔除 · 312 紫微 · 20 奇门 · 12 交运</text>
11
+ <text x="258.5" y="18">0 处不符|128 例 · 5 剔除 · 127 未核 · 312 紫微 · 20 奇门 · 12 交运</text>
12
12
  </g>
13
13
  </svg>
package/engine/almanac.js CHANGED
@@ -10,7 +10,7 @@
10
10
  import { solarToLunar } from './lunar.js';
11
11
  import { nayinOf } from './nayin.js';
12
12
  import {
13
- toJDN, fromJDN, dayGanzhiIndex, ganzhiName, termWindow, termInstantJd, partsToJd, STEMS, BRANCHES, TERM_NAMES,
13
+ toJDN, fromJDN, dayGanzhiIndex, ganzhiName, termWindow, termInstantJd, STEMS, BRANCHES, TERM_NAMES,
14
14
  } from './calendar.js';
15
15
  import { HEX64 } from './interpret-data.js';
16
16
  import { sanheGroupOf } from './sanhe.js';
@@ -196,13 +196,18 @@ export function buildAlmanac(input) {
196
196
  if (day > daysInMonth(year, month)) {
197
197
  throw new Error(`非法日期:${year} 年 ${month} 月没有 ${day} 日`);
198
198
  }
199
- const jdNoon = partsToJd({ year, month, day, hour: 12, minute: 0 });
200
199
  const lunar = solarToLunar(year, month, day);
201
200
  const jdn = toJDN(year, month, day);
202
201
 
202
+ // 黄历是「按日」出版的:交节当天即算新节(通书本子口径),所以节气一律比「日序」,
203
+ // 不比当天正午的时刻。用正午比时刻时,交节落在午后的那半年,整天还挂在上个月——
204
+ // 每年 12 个「节」约一半在午后,等于每年约 6 天的月柱、建除、值日神全错。
205
+ // 八字侧仍按精确到分的交节时刻判月柱(见 bazi.js),两者不共用这一层。
206
+ const termDayIndex = (jd) => Math.floor(jd + 0.5);
207
+
203
208
  // 年柱:立春界;同时给出春节界口径
204
209
  const lichunJd = termInstantJd(year, 2);
205
- const ganzhiYear = jdNoon < lichunJd ? year - 1 : year;
210
+ const ganzhiYear = termDayIndex(lichunJd) <= jdn ? year : year - 1;
206
211
  const yearIdx = (((ganzhiYear - 4) % 60) + 60) % 60;
207
212
  const yearGz = ganzhiName(yearIdx);
208
213
  const springYear = lunar.lunarYear;
@@ -211,9 +216,8 @@ export function buildAlmanac(input) {
211
216
  // 月柱:以「节」为界
212
217
  const jieTerms = termWindow(year, { jieOnly: true });
213
218
  let prevJie = null;
214
- let nextJie = null;
215
219
  for (const t of jieTerms) {
216
- if (t.jd <= jdNoon) prevJie = t; else { if (!nextJie) nextJie = t; }
220
+ if (termDayIndex(t.jd) <= jdn) prevJie = t;
217
221
  }
218
222
  const monthBranchIdx = ((2 + (prevJie.index - 2) / 2) % 12 + 12) % 12;
219
223
  const yinMonthStem = ((STEMS.indexOf(yearGz.stem) % 5) * 2 + 2) % 10;
@@ -231,7 +235,7 @@ export function buildAlmanac(input) {
231
235
  let prevTerm = null;
232
236
  let nextTerm = null;
233
237
  for (const t of allTerms) {
234
- if (t.jd <= jdNoon) prevTerm = t; else { if (!nextTerm) nextTerm = t; }
238
+ if (termDayIndex(t.jd) <= jdn) prevTerm = t; else { if (!nextTerm) nextTerm = t; }
235
239
  }
236
240
  const fmtJdDate = (jd) => {
237
241
  const p = fromJDN(Math.floor(jd + 0.5));
package/engine/bazi.js CHANGED
@@ -14,13 +14,16 @@ import { SANHE } from './sanhe.js';
14
14
  import { analyzeBaziFrame, scoreLuck } from './geju.js';
15
15
 
16
16
  // 地支藏干(本气 / 中气 / 余气)
17
+ // 巳的顺序是「丙庚戊」而不是「丙戊庚」:庚长生于巳,是中气;戊是辰月余气,排末位。
18
+ // 本表与下面 RENYUAN_TABLE(巳月:戊 5 日 → 庚 9 日 → 丙 16 日)互为倒序,
19
+ // 也与寅(甲丙戊)、申(庚壬戊)、亥(壬甲)的「长生=中气」写法一致。
17
20
  export const HIDDEN_STEMS = {
18
21
  子: ['癸'],
19
22
  丑: ['己', '癸', '辛'],
20
23
  寅: ['甲', '丙', '戊'],
21
24
  卯: ['乙'],
22
25
  辰: ['戊', '乙', '癸'],
23
- 巳: ['丙', '戊', '庚'],
26
+ 巳: ['丙', '庚', '戊'],
24
27
  午: ['丁', '己'],
25
28
  未: ['己', '丁', '乙'],
26
29
  申: ['庚', '壬', '戊'],
@@ -147,7 +147,14 @@ export function deltaTSeconds(year) {
147
147
  return v0 + ((v1 - v0) * (year - y0)) / (y1 - y0);
148
148
  }
149
149
  }
150
- return knots[knots.length - 1][1];
150
+ // 2100 年后用 Morrison & Stephenson (2004) 抛物线外推:ΔT ≈ 32 × ((y − 1820)/100)² 秒。
151
+ // 注意单位:括号里是「世纪」,不是年——写成 32×(y−1820)² 会在 2400 年给出 1076 万秒(约 124 天),
152
+ // 把节气、朔望整体推后好几个月。这里以 2100 端点(110s)接续抛物线增长率,保证 2100→2101 连续:
153
+ // 2101 约 111.8s、2200 约 321s、2400 约 936s。
154
+ const [yLast, vLast] = knots[knots.length - 1];
155
+ const uLast = (yLast - 1820) / 100;
156
+ const u = (year - 1820) / 100;
157
+ return vLast + 32 * (u * u - uLast * uLast);
151
158
  }
152
159
 
153
160
  // 1929 年元旦之前,中国历书按「北京地方平时」(116.4°E,UTC+7.7611)推算朔与中气;