celestial-computations

star 1

Astrum Harmonis Celestialis — A specialized computational agent mastering Chinese celestial cosmology (Bazi/Four Pillars, Zhouyi/I Ching) and planetary/celestial mechanics.

0x-wzw By 0x-wzw schedule Updated 4/29/2026

name: celestial-computations category: research description: > Astrum Harmonis Celestialis — A specialized computational agent mastering Chinese celestial cosmology (Bazi/Four Pillars, Zhouyi/I Ching) and planetary/celestial mechanics. version: 3.0.0 author: Dodecimus for {_USER_NAME} license: MIT platforms: [linux, macos, windows] tags: [chinese-astrology, bazi, iching, celestial-mechanics, astronomy]

Astrum Harmonis Celestialis

"As above, so below. The heavens inscribe patterns that time reveals."

A complete computational framework for Chinese celestial cosmology:

  • Bazi (八字) — Four Pillars of Destiny calculation engine
  • Zhouyi (周易) — I Ching hexagram mathematics and relationships
  • Celestial Mechanics — Planetary ephemeris integration
  • Heaven-Earth Synthesis — Unifying the ancient and precise

Architecture

aether/        — Cosmological constants and mappings
  └─ Heavenly Stems (天干), Earthly Branches (地支), Five Phases (五行)

logos/         — Mathematical and astronomical algorithms
  └─ BaziCalculator, SolarTermCalculator, PlanetaryEphemeris

harmon/        — Relationship calculations and synthesis
  └─ Ten Gods, Branch Interactions, Hexagram Relations

praxis/        — Operational interface
  └─ CelestialAgent API, CLI, Query Processor

Installation

cd ~/.hermes/skills/celestial-computations
pip install -r requirements.txt

Usage

Python API

from celestial_computations import CelestialAgent

agent = CelestialAgent()

# Calculate Bazi chart
chart = agent.bazi_chart(2024, 4, 13, 12)
print(chart["pillars"]["day"])  # Day pillar

# Get hexagram reading
reading = agent.hexagram_reading(1, moving_lines=[2, 5])
print(reading["opposite"]["name"])

# Planetary positions
planets = agent.planetary_report()

CLI

# Bazi chart
celestial-computations bazi 2024 4 13 12

# Hexagram reading
celestial-computations hexagram 1

# Current planetary positions
celestial-computations planetary

# Complete Celestial Report
celestial-computations report

# JSON output
celestial-computations bazi 2024 4 13 12 --json

Core Capabilities

Bazi (Four Pillars)

  • Year, Month, Day, Hour pillar calculation
  • Solar term boundaries (二十四节气)
  • Ten Gods (十神) determination
  • Five Phase balance analysis
  • Branch interactions (Clash 冲, Combine 合)
  • Luck Pillar (大运) computation

Zhouyi (I Ching) — Hexagram Calculator

Full hexagram engine in hexagram_calculator.py:

  • 8 Trigrams with binary, element, family role, symbol mappings
  • 64 Hexagrams in King Wen order with verified binary strings
  • Opposite (错卦), Nuclear (互卦), Changed (变卦) calculations
  • Day Pillar → Hexagram mapping (日柱→卦象) via trigram-element attribution
  • Leibniz binary representation
from celestial_computations import CelestialAgent

agent = CelestialAgent()

# Get hexagram with opposite + nuclear
reading = agent.hexagram_reading(1, moving_lines=[2, 5])
# Contains: original, opposite, nuclear, changed

# Map Bazi day pillar → hexagram
report = agent.hexagram_from_day_pillar("丁", "丑")
# Returns: hexagram, opposite, nuclear, element_relation, gua_ci

# Direct calculator access
from celestial_computations.hexagram_calculator import HexagramCalculator
hc = HexagramCalculator()

# Compose from any two trigrams
h = hc.hexagram_from_trigrams("坎", "震")  # 屯 (#3)

# All derivative hexagrams (opposite, nuclear, all single-line changes)
d = hc.all_derivatives(1)

# Search by name
results = hc.search_by_name("复")  # Returns #24 地雷复

Binary mapping (verified): King Wen order binary strings were derived from 卦名 trigram decomposition, not naive trigram-pair multiplication. Each 卦名 encodes upper/lower trigram via element characters (天=乾, 地=坤, 水=坎, 火=离, 雷=震, 风=巽, 山=艮, 泽=兑). This produces correct binaries: 乾=111111, 坤=000000, 坎=010010, 离=101101, 既济=010101, 未济=101010.

Nuclear (互卦) calculation: Middle 4 lines indexed bottom-to-top. Lower nuclear trigram = lines 2,3,4 from bottom; upper = lines 3,4,5 from bottom. The binary stores [index 0]=top yao, [index 5]=bottom yao.

Trigram element mapping for 日柱→卦象:

  • 甲乙 Stem → 震巽 (Wood 木), 丙丁 → 离 (Fire 火), 戊己 → 坤 (Earth 土), 庚辛 → 乾 (Metal 金), 壬癸 → 坎 (Water 水)
  • 子亥 Branch → 坎, 丑辰未戌 → 坤, 寅卯 → 震巽, 巳午 → 离, 申酉 → 乾

Celestial Mechanics

  • Planetary position ephemeris
  • Solar term calculation
  • Lunar phase computation
  • Calendar conversions

Astronomical Solar Term Calculation (NEW)

For precise solar term boundaries, use astronomical calculation via ephem:

def get_sun_longitude(observer, date):
    """Calculate Sun's ecliptic longitude in degrees."""
    sun = ephem.Sun()
    observer.date = ephem.Date(date)
    sun.compute(observer)
    eq = ephem.Equatorial(sun.ra, sun.dec, epoch=ephem.J2000)
    ecl = ephem.Ecliptic(eq)
    return math.degrees(ecl.lon) % 360

def get_solar_term_name(lon_deg):
    """Map solar longitude to 24 terms."""
    idx = int(((lon_deg - 315 + 360) % 360) / 15)  # Li Chun = 315°
    return SOLAR_TERMS_CN[idx % 24]

def get_month_branch_from_lon(lon_deg):
    """Map longitude to zodiac month (寅月 to 丑月)."""
    lon_shifted = (lon_deg + 45) % 360
    idx = int(lon_shifted // 30)
    return BRANCH_ORDER[idx]  # ['寅','卯','辰',...]

# Example: Get precise term for current moment
observer = ephem.Observer()
observer.lat = '3.1390'; observer.lon = '101.6869'  # KL coordinates
sun_lon = get_sun_longitude(observer, datetime.utcnow())
print(f"Solar term: {get_solar_term_name(sun_lon)}")  # 谷雨 ~35°, 立春 ~315°

Advantage over hardcoded dates: Accounts for actual Sun position, leap seconds, and local longitude. Terms shift slightly year-to-year but ephem tracks this precisely.

Solar longitude → Term mapping:

  • 315°: 立春 (Li Chun) — Start of 寅月 (Tiger)
  • 330°: 雨水 (Yu Shui)
  • 345°: 惊蛰 (Jing Zhe)
  • 0°/360°: 春分 (Chun Fen)
  • ... (every 15° increment)

Planetary Ephemeris (七政星历)

Generate positions for Sun, Moon, and 5 classical planets:

def get_planetary_positions(observer, date):
    bodies = {
        '太阳': ephem.Sun(), '月亮': ephem.Moon(),
        '水星': ephem.Mercury(), '金星': ephem.Venus(),
        '火星': ephem.Mars(), '木星': ephem.Jupiter(),
        '土星': ephem.Saturn()
    }
    results = []
    for name, body in bodies.items():
        body.compute(observer)
        eq = ephem.Equatorial(body.ra, body.dec, epoch=ephem.J2000)
        ecl = ephem.Ecliptic(eq)
        lon = math.degrees(ecl.lon) % 360
        zodiac = ZODIAC[int(lon // 30)]
        results.append((name, lon, zodiac))
    return results

Bazi interpretation note: Classical texts associate planets with stems (岁星=木/Jupiter→甲, 荧惑=火/Mars→丙, etc.). Modern ephemeris enables precise calculations.

Extended Branch Relations

Beyond basic 冲/合, add these calculations:

六害 (Six Harms)

六害 = {'子':'未','丑':'午','寅':'巳','卯':'辰','申':'亥','酉':'戌',
      '未':'子','午':'丑','巳':'寅','辰':'卯','亥':'申','戌':'酉'}

六破 (Six Breaks)

六破 = {'子':'酉','丑':'辰','寅':'亥','卯':'午','巳':'申','未':'戌',
      '酉':'子','辰':'丑','亥':'寅','午':'卯','申':'巳','戌':'未'}

三刑 (Three Punishments)

三刑 = {
    '寅':'巳申无恩刑', '巳':'申寅无恩刑', '申':'寅巳无恩刑',  # Fire punishment
    '丑':'戌未恃势刑', '戌':'未丑恃势刑', '未':'丑戌恃势刑',  # Earth punishment
    '子':'卯无礼刑', '卯':'子无礼刑'                           # Wood punishment
}

三合 (Three Combinations/局)

三合 = {
    '申':'子辰合水局','子':'申辰合水局','辰':'申子合水局',
    '寅':'午戌合火局','午':'寅戌合火局','戌':'寅午合火局',
    '巳':'酉丑合金局','酉':'巳丑合金局','丑':'巳酉合金局',
    '亥':'卯未合木局','卯':'亥未合木局','未':'亥卯合木局'
}

三会 (Three Meetings)

Add 三会 alongside 三合—they're distinct!

三会 = {
    '寅':'寅卯辰会东方木', '卯':'寅卯辰会东方木',
    '巳':'巳午未会南方火', '午':'巳午未会南方火',
    '申':'申酉戌会西方金', '酉':'申酉戌会西方金',
    '亥':'亥子丑会北方水', '子':'亥子丑会北方水',
    '辰':'辰戌丑未会四季土'  # etc.
}

Auxiliary Pillars (Bazi Extensions)

旬空 (旬空/空亡)

Calculate "Empty Death" branches for a day:

def 旬空(day_idx):
    """Return "旬空" branches for 60-cycle index."""
    xun = (day_idx // 10) % 6
    k1 = (10 - 2 * xun) % 12
    k2 = (11 - 2 * xun) % 12
    return 地支[k1], 地支[k2]

胎元 (Fetal Origin)

Birth month → 胎元 calculation:

def 胎元(month_stem, month_branch):
    msi = 天干.index(month_stem)
    mbi_1 = 地支.index(month_branch) + 1
    tai_stem = 天干[(msi + 1) % 10]
    tai_branch = 地支[(mbi_1 + 3 - 1) % 12]  # +3 months
    return tai_stem, tai_branch

旺相休囚死 (Five Phase Strengths)

Lookup table by month branch:

旺相休囚 = {
    '寅':{'木':'旺','火':'相','水':'休','金':'囚','土':'死'},
    '卯':{'木':'旺','火':'相','水':'休','金':'囚','土':'死'},
    '巳':{'火':'旺','土':'相','木':'休','水':'囚','金':'死'},
    '午':{'火':'旺','土':'相','木':'休','水':'囚','金':'死'},
    '申':{'金':'旺','水':'相','土':'休','火':'囚','木':'死'},
    '酉':{'金':'旺','水':'相','土':'休','火':'囚','木':'死'},
    '亥':{'水':'旺','木':'相','金':'休','土':'囚','火':'死'},
    '子':{'水':'旺','木':'相','金':'休','土':'囚','火':'死'},
    '辰':{'土':'旺','金':'相','火':'休','木':'囚','水':'死'},
    '戌':{'土':'旺','金':'相','火':'休','木':'囚','水':'死'},
    '丑':{'土':'旺','金':'相','火':'休','木':'囚','水':'死'},
    '未':{'土':'旺','金':'相','火':'休','木':'囚','水':'死'},
}

Da Yun (大运) Calculation

Full implementation steps:

Direction (顺排/逆排)

is_yang_year = (year_stem_idx % 2) == 0  # 甲丙戊庚壬 = Yang
direction = "forward" if (is_yang_year == is_male) else "backward"

Steps (起运岁数)

# Days from birth to next/prev solar term
# 3 days = 1 year, remainder * 4 = months
# Each additional day = 4 months offset

Sequence

Generate 10-year periods from birth month, alternating stems/branches based on direction.

Example (己未年男命 → Yin year + Male → backward from 丙子):

大运 = [
    ('乙亥', 4, 14), ('甲戌', 14, 24), ('癸酉', 24, 34),
    ('壬申', 34, 44), ('辛未', 44, 54), ('庚午', 54, 64),
    ('己巳', 64, 74), ('戊辰', 74, 84)
]

Mathematical Foundations

The Sexagenary Cycle

60-year cycle = lcm(10 stems, 12 branches)
Year n: stem = (n - 4) % 10, branch = (n - 4) % 12

Binary Hexagrams (Leibniz, 1703)

Hexagram #1 (Qian/Heaven): 111111 = 63
Hexagram #2 (Kun/Earth):  000000 = 0
...

This is the same binary system that powers modern computing — discovered independently in ancient China.

API Reference

CelestialAgent Methods

Method Parameters Returns
bazi_chart(year, month, day, hour) Integers Dict with pillars and analysis
hexagram_reading(number, moving_lines) Int, List[int] Dict with original, opposite, nuclear
planetary_report(datetime) Optional[datetime] Dict positions and phases
celestial_report(...) Same as bazi Complete unified report

HiddenStems (藏干)

Access hidden heavenly stems within earthly branches:

from celestial_computations.aether import HiddenStems

# Get all hidden stems for a branch (by index 0-11)
stems = HiddenStems.get_hidden_stems(0)  # 子 (Zi) branch
# Returns: [(HeavenlyStem, intensity), ...]
# Example: [(癸, 'primary')]

# Get only the primary (dominant) hidden stem
primary = HiddenStems.get_primary_stem(2)  # 寅 (Yin) branch
# Returns: HeavenlyStem(甲)

# Access by branch name
stems = HiddenStems.get_all_for_branch("寅")

NaYin (纳音)

Access the 30 sound elements of the sexagenary cycle:

from celestial_computations.aether import NaYin

# Get Na Yin for a cycle position (0-59)
nayin = NaYin.get_nayin(0)  # 海中金 (Sea Metal)
element = NaYin.get_element(0)  # Element.METAL

# Get full description
desc = NaYin.describe(0)  # "海中金 (Sea Metal, Metal)"

PlanetaryEphemeris (DE440)

Modern planetary position calculations using NASA JPL DE440 ephemeris:

from celestial_computations.logos import PlanetaryEphemeris

eph = PlanetaryEphemeris()
positions = eph.get_planet_positions(datetime.now())
lunar = eph.get_lunar_phase(datetime.now())

Note: Requires skyfield library and DE440 ephemeris download (~40MB).

Daily Bazi Report Workflow (Cron Job)

For generating daily Bazi briefings (e.g., for Telegram delivery):

Data Sources (in order of reliability)

  1. ChineseFortuneCalendar.com — Zodiac month boundaries, lunar month dates, year pillar info (verified for 2026)
  2. HKO (Hong Kong Observatory) — Lunar calendar converter (date range: 1901-2100)
  3. Python lunardate package — Lunar date conversion (install: uv pip install lunardate)
  4. Self-computed — Day pillar via JDN formula, solar term calculations

Key Calculation Steps

  1. Day Pillar: Use (JDN - 11) % 60 formula (see Section 3 above)
  2. Lunar Date: Use lunardate.LunarDate.fromSolarDate(year, month, day) → returns (year, month, day, isLeap)
  3. Solar Term: Determine current zodiac month from chinesefortunecalendar.com data or solar longitude calculation
  4. Month Pillar: Use 五虎遁 formula based on year stem group
  5. 12 Day Officers (建除十二神): Depends on month branch + day branch relationship
  6. Clash/Avoidance (冲煞): Day branch determines clash (opposite in 6-pair system) and sha direction
  7. Na Yin (纳音): Use 30-pair lookup table from 60-cycle index

Zodiac Month Boundaries (from chinesefortunecalendar.com for 2026)

These are SOLAR months (节气 boundaries), NOT lunar months:

  • 寅月 Tiger: Feb 4 – Mar 4 | 卯月 Rabbit: Mar 5 – Apr 4
  • 辰月 Dragon: Apr 5 – May 4 | 巳月 Snake: May 5 – Jun 4
  • 午月 Horse: Jun 5 – Jul 6 | 未月 Goat: Jul 7 – Aug 6
  • 申月 Monkey: Aug 7 – Sep 6 | 酉月 Rooster: Sep 7 – Oct 7
  • 戌月 Dog: Oct 8 – Nov 6 | 亥月 Pig: Nov 7 – Dec 6
  • 子月 Rat: Dec 7 – Jan 4 | 丑月 Ox: Jan 5 – Feb 3

Web Scraping Pitfalls

  • Many Chinese almanac sites use 451 (geo-blocked) or expired SSL — browser tool is essential
  • ChineseFortuneCalendar.com blocks with 451 from Python but works in browser
  • HKO calendar converter requires JavaScript interaction (no simple URL pattern for year data)
  • The chinesefortunecalendar.com/Calendar/YYYY/YYYY-ChineseCalendar.htm URL format has year-specific data
  • Tavily search may hit rate limits — have fallback computation methods ready

Na Yin (纳音) Quick Reference Table

Each pair in the 60-cycle shares a Na Yin:

Pairs (0-based) Na Yin Element
0-1 (甲子乙丑) 海中金 Sea Metal
2-3 (丙寅丁卯) 炉中火 Furnace Fire
4-5 (戊辰己巳) 大林木 Great Forest Wood
6-7 (庚午辛未) 路旁土 Roadside Earth
8-9 (壬申癸酉) 剑锋金 Sword Metal
10-11 (甲戌乙亥) 山头火 Mountain Fire
12-13 (丙子丁丑) 涧下水 Stream Water
14-15 (戊寅己卯) 城头土 Wall Earth
16-17 (庚辰辛巳) 白蜡金 White Wax Metal
18-19 (壬午癸未) 杨柳木 Willow Wood
20-21 (甲申乙酉) 泉中水 Spring Water
22-23 (丙戌丁亥) 屋上土 Roof Earth
24-25 (戊子己丑) 霹雳火 Thunder Fire
26-27 (庚寅辛卯) 松柏木 Pine Wood
28-29 (壬辰癸巳) 长流水 Long Stream Water
30-31 (甲午乙未) 砂石金 Sand Metal
32-33 (丙申丁酉) 山下火 Mountain Fire
34-35 (戊戌己亥) 平地木 Flatland Wood
36-37 (庚子辛丑) 壁上土 Wall Earth
38-39 (壬寅癸卯) 金箔金 Gold Foil Metal
40-41 (甲辰乙巳) 覆灯火 Lamp Fire
42-43 (丙午丁未) 天河水 Heavenly Water
44-45 (戊申己酉) 大驿土 Post Earth
46-47 (庚戌辛亥) 钗钏金 Hairpin Metal
48-49 (壬子癸丑) 桑柘木 Mulberry Wood
50-51 (甲寅乙卯) 大溪水 Brook Water
52-53 (丙辰丁巳) 沙中土 Sand Earth
54-55 (戊午己未) 天上火 Heavenly Fire
56-57 (庚申辛酉) 石榴木 Pomegranate Wood
58-59 (壬戌癸亥) 大海水 Ocean Water

Formula: Na Yin pair index = dayIndex // 2 (0-based from the 60-cycle)

12 Day Officers (建除十二神)

The cycle position depends on the month branch determining the "建" position:

In month 辰 (Dragon): 辰=建, 巳=除, 午=满, 未=平, 申=定, 酉=执, 戌=破, 亥=危, 子=成, 丑=收, 寅=开, 卯=闭

General rule: The month branch IS 建 (Establishment). Count forward from there.

  • 建: Good for beginning, establishing
  • 定: Good for settling, contracts, commitments
  • 执: Good for holding, maintaining
  • 破: Unfavorable - avoid major activities
  • 危: Caution needed
  • 成: Good for completing, achieving
  • 收: Good for harvesting, collecting
  • 开: Good for opening, starting
  • 闭: Good for closing, ending

Sha Direction (煞方) by Day Branch

Day Branch 煞 Direction
申/子/辰 煞南 (South)
寅/午/戌 煞北 (North)
亥/卯/未 煞西 (West)
巳/酉/丑 煞东 (East)

Testing

python -m pytest tests/

# Verify with known historical charts
python -c "from celestial_computations import CelestialAgent; \
           a = CelestialAgent(); \
           print(a.bazi_chart(1984, 2, 4, 0))"  # Jiazi year

Detailed Calculation Algorithms

1. Year Pillar (年柱) Calculation

Year changes at 立春 (Li Chun), NOT January 1st!

// Year stem = ((year - 4) % 10) for 甲子 year alignment
// Year branch = ((year - 4) % 12)

function calculateYearPillar(gregorianDate: Date): Pillar {
    const year = gregorianDate.getFullYear();
    const month = gregorianDate.getMonth() + 1;
    const day = gregorianDate.getDate();
    
    // CRITICAL: Check if before Li Chun (usually around Feb 4)
    const isBeforeLiChun = (month === 1) || (month === 2 && day < 4);
    const effectiveYear = isBeforeLiChun ? year - 1 : year;
    
    const stemIndex = (effectiveYear - 4) % 10;
    const branchIndex = (effectiveYear - 4) % 12;
    
    return { stem: STEMS[stemIndex], branch: BRANCHES[branchIndex] };
}

2. Month Pillar (月柱) Calculation - 五虎遁 (Five Tigers)

Month is determined by solar terms (节气), NOT by lunar calendar!

Year Stem Month Stem Sequence
甲, 己 (Jia, Ji) 丙, 丁, 戊, 己, 庚, 辛, 壬, 癸, 甲, 乙, 丙, 丁
乙, 庚 (Yi, Geng) 戊, 己, 庚, 辛, 壬, 癸, 甲, 乙, 丙, 丁, 戊, 己
丙, 辛 (Bing, Xin) 庚, 辛, 壬, 癸, 甲, 乙, 丙, 丁, 戊, 己, 庚, 辛
丁, 壬 (Ding, Ren) 壬, 癸, 甲, 乙, 丙, 丁, 戊, 己, 庚, 辛, 壬, 癸
戊, 癸 (Wu, Gui) 甲, 乙, 丙, 丁, 戊, 己, 庚, 辛, 壬, 癸, 甲, 乙

Month branch always starts at 寅 (Yin) for first month:

正月 = 寅, 二月 = 卯, 三月 = 辰, 四月 = 巳, 五月 = 午, 六月 = 未,
七月 = 申, 八月 = 酉, 九月 = 戌, 十月 = 亥, 十一月 = 子, 十二月 = 丑

3. Day Pillar (日柱) Calculation - Sexagenary Cycle

Use the Julian Day Number (JDN) formula — it is the most reliable method.

// FORMULA: dayIndex = (JDN - 11) % 60
// where index 0 = 甲子 (Jia Zi)
// This works because JDN 0 corresponds to 壬子 (Ren Zi, index 49)
// so offset = (0 - 49) % 60 = 11, hence (JDN - 11) % 60

function gregorianToJDN(year: number, month: number, day: number): number {
    const a = Math.floor((14 - month) / 12);
    const y = year + 4800 - a;
    const m = month + 12 * a - 3;
    return day + Math.floor((153 * m + 2) / 5) + 365 * y + Math.floor(y / 4)
           - Math.floor(y / 100) + Math.floor(y / 400) - 32045;
}

function calculateDayPillar(targetDate: Date): Pillar {
    const jdn = gregorianToJDN(targetDate.getFullYear(), 
                                targetDate.getMonth() + 1, 
                                targetDate.getDate());
    const dayIndex = (jdn - 11) % 60;
    
    const stemIndex = dayIndex % 10;
    const branchIndex = dayIndex % 12;
    
    return { stem: STEMS[stemIndex], branch: BRANCHES[branchIndex] };
}

⚠️ PITFALL: Do NOT use "Jan 1, 1900 = 甲辰 index 40" as a reference point! Multiple Chinese calendar sources cite conflicting anchor dates for 1900. The JDN formula (JDN - 11) % 60 is mathematically self-consistent and derived from the known mapping of JDN 0 → 壬子 (index 49) in the 60-cycle. The same formula can also be written as (JDN + 49) % 60 since -11 ≡ 49 (mod 60).

Verification: Consecutive days must follow the 60-cycle sequentially:

  • 2026-04-14 → 戊午 (Wu Wu), 2026-04-15 → 己未 (Ji Wei), 2026-04-16 → 庚申 (Geng Shen), 2026-04-17 → 辛酉 (Xin You)

4. Hour Pillar (时柱) Calculation - 五鼠遁 (Five Rats)

Hour branch is based on 2-hour periods starting at 23:00 (子时):

子时 = 23:00-01:00, 丑时 = 01:00-03:00, 寅时 = 03:00-05:00,
卯时 = 05:00-07:00, 辰时 = 07:00-09:00, 巳时 = 09:00-11:00,
午时 = 11:00-13:00, 未时 = 13:00-15:00, 申时 = 15:00-17:00,
酉时 = 17:00-19:00, 戌时 = 19:00-21:00, 亥时 = 21:00-23:00

Hour stem formula (五鼠遁口诀):

甲己还加甲 (Days of Jia/Ji: stems start at Jia)
乙庚丙作初 (Days of Yi/Geng: stems start at Bing)
丙辛从戊起 (Days of Bing/Xin: stems start at Wu)
丁壬庚子居 (Days of Ding/Ren: stems start at Geng)
戊癸何方发 (Days of Wu/Gui: stems start at Ren)

5. Hidden Stems (藏干) - Hidden Elements

Each branch contains hidden stems with intensity levels:

Branch Hidden Stems Intensity
子 Zi Primary
丑 Chou 己, 癸, 辛 Primary, Secondary, Tertiary
寅 Yin 甲, 丙, 戊 Primary, Secondary, Tertiary
卯 Mao Primary
辰 Chen 戊, 乙, 癸 Primary, Secondary, Tertiary
巳 Si 丙, 戊, 庚 Primary, Secondary, Tertiary
午 Wu 丁, 己 Primary, Secondary
未 Wei 己, 丁, 乙 Primary, Secondary, Tertiary
申 Shen 庚, 壬, 戊 Primary, Secondary, Tertiary
酉 You Primary
戌 Xu 戊, 辛, 丁 Primary, Secondary, Tertiary
亥 Hai 壬, 甲 Primary, Secondary

6. Da Yun (大运) Calculation

Direction rules:

  • Yang males and Yin females: Forward (顺排)
  • Yin males and Yang females: Backward (逆排)
// Determine direction
const isYangYear = yearStemIndex % 2 === 0; // 0, 2, 4, 6, 8 are Yang
const isMale = gender === "male";
const isForward = (isYangYear && isMale) || (!isYangYear && !isMale);

Starting age: Days to next/previous solar term divided by 3

// 3 days = 1 year of starting age
// Each additional day = 4 months
const daysToTerm = calculateDaysToSolarTerm(birthDate, isForward);
const years = Math.floor(daysToTerm / 3);
const months = (daysToTerm % 3) * 4;
const startingAge = years + months / 12;

7. Branch Interactions

Clashes (冲): Opposite branches

子 ↔ 午, 丑 ↔ 未, 寅 ↔ 申, 卯 ↔ 酉, 辰 ↔ 戌, 巳 ↔ 亥

Combinations (合): Six combinations

子丑合, 寅亥合, 卯戌合, 辰酉合, 巳申合, 午未合

Critical Calculation Notes

Lunar Year Boundary (IMPORTANT)

Pitfall: January/February births require Lunar New Year adjustment!

# Example: January 5, 1980
# Gregorian: 1980
# Chinese New Year 1980: February 16
# BEFORE CNY → still 1979 lunar year

# CORRECT:
if (month == 1) or (month == 2 and day < cny_day):
    lunar_year = year - 1
else:
    lunar_year = year

# For >YYYY-MM-DD: lunar_year = 1979 (己未 Ji Wei)
# NOT 1980 (which would be 庚申 Geng Shen)

Verification Protocol

When calculating from fortune-telling documents:

  1. Extract pillars from document first if available
  2. Verify year stem accounts for Lunar New Year offset
  3. Cross-check day pillar against sexagenary tables
  4. Confirm hour stem using: (DayStemIndex % 5) * 2 + HourBranchIndex

Manual Computation Mode (When Module Fails)

# Standalone verification for Ding Fire Day Master
pillars = {
    "year":  ("己", "未"),   # Earth Goat
    "month": ("丙", "子"),   # Fire Rat
    "day":   ("丁", "丑"),   # Fire Ox ← Day Master
    "hour":  ("乙", "巳"),   # Wood Snake
}

ten_gods_for_ding = {
    "甲": "正印", "乙": "偏印",  # Wood produces Fire
    "丙": "劫財", "丁": "比肩",  # Same element
    "戊": "傷官", "己": "食神",  # Fire produces Earth
    "庚": "正財", "辛": "偏財",  # Fire overcomes Metal
    "壬": "正官", "癸": "七殺",  # Water attacks Fire
}

# Weak Day Master in Winter → needs Wood (印) support

Integration

This skill provides structured inputs for agent decision-making:

  • Temporal quality assessment
  • Cyclical pattern recognition
  • Celestial state encoding

Use with other agents for:

  • Timing optimization
  • Pattern matching across domains
  • Non-Western randomness sources

Mental Models Framework (NEW)

Derived from Five Element philosophy, 15 practical cognitive tools for decision-making:

Wood Models (生发)

  • Growth Mindset: Expansion is natural; obstacles redirect, not block
  • Root Before Branch: Foundation precedes reach (本立道生)
  • Flexible Persistence: Bend and return—resilience through adaptability

Fire Models (炎上)

  • Controlled Burn: Passion needs containment; burnout is boundary failure
  • Illumination Strategy: Light dispels shadow; clarity creates accountability
  • Transformational Catalyst: Intense periods beat gradual drift

Earth Models (坤)

  • Container Principle: Capacity to hold space determines value
  • Seasonal Timing: Actions must align with natural cycles
  • Nourishing Support: Invisible infrastructure sustains all growth

Metal Models (从革)

  • Precise Division: Clarity from deciding what is excluded
  • Structural Integrity: Systems must hold form under pressure
  • Refinement Process: Excellence through reduction, not addition

Water Models (润下)

  • Adaptive Flow: Take container's shape; maintain essence
  • Penetrating Insight: Persistence beats force; depth reveals truth
  • Depth Accumulation: Store before deploying; wisdom in stillness

Decision Frameworks

  1. Five Element Matrix — Multi-factor decisions across all elements
  2. Seasonal Timing — When to act: Spring→Start, Summer→Expand, Autumn→Harvest, Winter→Store
  3. Ten God Interactions — Relationship dynamics (印 Support, 食伤 Expression, 财 Wealth, etc.)
  4. Branch Interactions — Clash (冲), Combine (合), Harm (害), Punishment (刑)
  5. Root and Branch Analysis — Find leverage points, not just symptoms

Cognitive Bias Detection

Imbalance Bias Correction
Excessive Wood Endless growth without maintenance Force "maintenance seasons"
Excessive Fire Enthusiasm without follow-through Implement cooling-off periods
Excessive Earth Analysis paralysis Ship at 80%, set deadlines
Excessive Metal Over-elimination 10% "inefficient" buffer
Excessive Water Non-commitment disguised as flexibility Irrevocable commitments
Missing Element Blindness to weakest quality Partner with strength in your weakness

Named in the tradition of great Latin cosmic treatises: Astrum (star) + Harmonis (harmony) + Celestialis (heavenly)

Install via CLI
npx skills add https://github.com/0x-wzw/Shunshi --skill celestial-computations
Repository Details
star Stars 1
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator