はじめに
「私しか得しないニッチな技術」シリーズとして、今回は四柱推命の命式作成ツールについて書きます。
以前の記事では、四柱推命に興味を持ったことをきっかけに、自分用の命式作成ツールを作った経緯や、搭載した機能を紹介しました。
今回は、ツールの機能紹介ではありません。
四柱推命という、資料や流派によって計算方法や表現に違いがあるものを、どのようにプログラムへ落とし込んだか。
その過程で考えた、計算方針、データの扱い、前提条件の明示についてまとめます。
作ったもの
作ったのは、四柱推命の命式や運気の流れを確認するためのWebツールです。
現在は、以下の情報を表示できます。
| ページ | 主な内容 |
|---|---|
| 基本命式 | 年柱、月柱、日柱、時柱、通変星、十二運など |
| 大運・年運 | 大運、年運、通変星、十二運、地支関係など |
| 月運 | 指定年の月ごとの干支や運気の流れ |
| 日運 | 指定日の干支や確認項目 |
ツールはこちらです。
前回の記事では、なぜこのツールを作ったのか、どのような機能があるのかを中心に紹介しました。
今回は、その裏側にある「何を基準として計算するか」という部分に焦点を当てます。
四柱推命は、計算式を書くだけでは作れなかった
四柱推命をプログラムにしようとすると、最初に計算式を考えたくなります。
しかし、実際にはコードを書く前に決めなければならないことが多くありました。
たとえば、次のような点です。
- 年柱や月柱を、どの時点で切り替えるか
- 月の区切りを暦月で扱うか、節入りで扱うか
- 出生時刻が節入りの前後にある場合、どちらの月柱とするか
- 出生時刻が不明な場合、時柱をどのように扱うか
- 大運の開始時期を、何歳からと表示するか
- 順行・逆行をどの条件で判定するか
- 通変星や十二運を、どの対応表に基づいて求めるか
- 流派による違いをどこまで扱うか
四柱推命には、広く使われている基本的な考え方がある一方で、資料や流派によって細かな違いもあります。
そのため、単に「正しい計算式」を一つ実装すれば完成する、というものではありませんでした。
まず必要だったのは、
このツールでは、何を基準として計算するのか
を決めることでした。
最初に計算方針を整理した
実装を進めるにあたり、処理ごとに計算方針を分けて整理しました。
主な分類は次のとおりです。
| 分類 | 整理した内容 |
|---|---|
| 年柱 | 年の切り替えをどの基準で判定するか |
| 月柱 | 節入り日・節入り時刻をどこまで考慮するか |
| 日柱 | 日別データからどの値を取得するか |
| 時柱 | 出生時刻と日干からどのように判定するか |
| 大運 | 順行・逆行と起運時期をどのように求めるか |
| 年運 | 対象年の干支と命式との関係をどう表示するか |
| 月運 | 月の切り替え点をどのデータで判定するか |
| 日運 | 対象日の干支をどのデータから取得するか |
こうして分類してみると、四柱推命のツールは、単一の計算処理ではなく、複数の小さな判定処理を組み合わせたものだと分かりました。
データを機械が扱える形にした
四柱推命の計算では、干支、節入り、通変星、十二運など、複数の対応関係を扱います。
これらをプログラム内へ直接書き続けると、修正や確認が難しくなります。
そのため、可能な範囲でデータと処理を分けました。
たとえば、日別の情報はJSON形式のデータとして保持し、対象日をキーとして値を取得します。
簡略化すると、次のようなイメージです。
{
"2026-07-13": {
"HDay": "戊子",
"EDay": "..."
}
}
実際のデータには、日干支だけでなく、月や年の切り替え判定に使用する情報も含まれます。
JavaScript側では、対象の日付に対応するデータを取得し、画面表示用の処理へ渡します。
const targetDate = "2026-07-13";
const dayData = datesMapping[targetDate];
if (!dayData) {
throw new Error(`対象日のデータが見つかりません: ${targetDate}`);
}
const dayStemBranch = dayData.HDay;
掲載しているコードは、実際に使用している処理の考え方を示すために簡略化した例です。
月柱は単純な月番号では決められない
実装時に特に注意が必要だったのが、月柱です。
一般的なカレンダーでは、1月1日から1月31日までを1月として扱います。
しかし、四柱推命では、月の切り替えに節入りを使用します。
そのため、同じ2月生まれでも、節入り前か後かによって月柱が異なる場合があります。
単純にJavaScriptの月番号を取得して処理すると、四柱推命上の月と一致しない可能性があります。
const month = birthDate.getMonth() + 1;
この値だけでは、四柱推命上の月柱を正確に判定できません。
必要なのは、対象日時と節入り日時を比較する処理です。
概念的には、次のようになります。
function isAfterSolarTerm(birthDateTime, solarTermDateTime) {
return birthDateTime >= solarTermDateTime;
}
対象者の出生日時が節入りより前か後かを判定し、その結果に基づいて月柱を切り替えます。
この部分は、日付だけでなく時刻まで扱うかによって結果が変わるため、ツールの計算方針として明示する必要があります。
節入り時刻の扱いを段階的に改善した
開発初期は、節入り日を中心に月の切り替えを判定していました。
しかし、同じ節入り日であっても、節入り時刻より前に生まれた場合と、後に生まれた場合では、月柱が異なる可能性があります。
そこで、節入り時刻を含むデータを用意し、出生日時と比較できる形へ変更しました。
概念的なデータ構造は、次のような形です。
{
"1984": {
"立春": "1984-02-05T00:25:00+09:00"
}
}
JavaScriptでは、ISO形式の日時をDateオブジェクトへ変換して比較します。
const birthDateTime = new Date("1984-02-05T00:10:00+09:00");
const solarTermDateTime = new Date("1984-02-05T00:25:00+09:00");
const isBeforeSolarTerm = birthDateTime < solarTermDateTime;
この例では、出生時刻が節入り時刻より前なので、節入り前の月として扱います。
実際には、出生地による時刻補正や、データの対象期間なども考慮する必要があります。
出生地による時刻差も無視できなかった
日本国内でも、出生地によって標準時との間に時間差があります。
日常生活ではほとんど意識しない差ですが、出生時刻が時刻区分の境界付近にある場合、時柱の判定に影響する可能性があります。
そこで、主要な地域について、簡易的な地方時差補正を選択できるようにしました。
ただし、ここで重要なのは、補正を行えば必ず正確になるということではありません。
- 出生時刻そのものが正確か
- 出生地をどの地点として扱うか
- 真太陽時まで考慮するか
- サマータイムや歴史的な標準時変更を扱うか
といった別の論点があります。
そのため、このツールでは、対応している範囲と未対応の範囲を分けて考えています。
計算結果だけでなく、前提条件も表示する
ツールを作る中で、計算結果だけを表示するのは不十分だと感じました。
利用者から見ると、結果が表示されても、次の点が分からないためです。
- どのデータを使っているか
- どの計算方法を採用しているか
- どこまで細かく判定しているか
- どのような条件では誤差が生じるか
- 流派による違いを扱っているか
そこで、各ページに以下のような説明を追加しました。
- ご利用について
- 計算方針
- 表示内容の範囲
- 未対応事項
- 参考利用であること
- 鑑定結果や将来の出来事を保証しないこと
計算処理を実装することと、その計算の前提を説明することは、別の作業です。
しかし、外部へ公開するツールでは、どちらも必要だと考えました。
法規・規格調査と似ている部分
四柱推命のツールを作っていると、普段の法規・規格調査と似ている部分があることに気づきました。
法規や規格を扱う場合も、結論だけを記載すればよいとは限りません。
- どの文書を参照したか
- どの条項を根拠としたか
- どの条件に適用されるか
- 例外はあるか
- 判断できない範囲はどこか
- 文書の版や時点はいつか
といった情報を整理する必要があります。
四柱推命の場合も同様に、
- どの暦データを使用するか
- どの計算方法を採用するか
- どの流派の考え方を含むか
- どの範囲まで実装するか
- どこに未対応事項があるか
を整理する必要がありました。
扱っている題材は異なりますが、
複雑な情報を、前提条件とともに機械が扱える形へ変換する
という点では、共通する部分があります。
実装して分かったこと
このツールを作る前は、四柱推命の命式作成は、決められた計算を順番に行うものだと思っていました。
実際に実装してみると、必要だったのは計算だけではありませんでした。
- 用語を定義する
- 資料間の違いを確認する
- 採用する計算方針を決める
- データ形式を統一する
- 条件分岐を整理する
- 例外を確認する
- 未対応範囲を明示する
- 利用者が理解できる表示へ変換する
こうして見ると、作っていたのは単なる占い画面ではなく、小さなルールエンジンに近いものだったのかもしれません。
今後改善したいこと
現時点では、基本的な命式、大運、年運、月運、日運を確認できる状態になっています。
今後は、必要に応じて次の点を改善したいと考えています。
- 節入り時刻の判定精度をさらに確認する
- 出生地による時刻補正の説明を充実させる
- 合・冲・刑・害の表示を拡張する
- 空亡の表示内容を整理する
- 年運、月運、日運の重なりを見やすくする
- 計算方針をページごとに整理する
- 使用しているデータの対象期間を明示する
- テストケースを増やす
機能を増やすだけでなく、計算根拠や制約を確認しやすくすることも、今後の改善項目です。
おわりに
今回は、「私しか得しないニッチな技術」シリーズとして、四柱推命の命式作成ツールを別の角度から整理しました。
前回の記事では、四柱推命に興味を持ち、自分用のWebツールを作った経緯を紹介しました。
今回あらためて振り返ると、実装で重要だったのは、コードを書くことだけではありませんでした。
資料を確認し、考え方の違いを整理し、採用する計算方針を決め、データと処理へ変換する。
そして、結果だけでなく、その前提や未対応範囲も説明できる状態にする。
これは、普段行っている情報調査や文書構造化にもつながる考え方でした。
私しか使わないかもしれないと思って作り始めたツールですが、自分の疑問を調べ、構造化し、動く形へ変える過程そのものが、私にとっての「ニッチな技術」なのだと思います。
四柱推命の命式作成ツールはこちらです。
前回の記事はこちらです。