Skip to content

wbx1-Ltd/BaziCore-Swift

Repository files navigation

BaziCore

A rigorous BaZi (Four Pillars) computation core in pure Swift.
Explicit rules, traceable boundaries, golden-fixture validation, and layered providers.

简体中文 · Report Issue · Releases


Table of Contents

TOC


✨ Features

Capability Description
🎯 Four Pillars Year / month / day / hour pillars with configurable boundary rules
🧭 Traceable Boundaries Li Chun, Jie boundaries, Zi hour, and true solar time travel with the chart
📚 Metaphysics Tables Hidden stems, ten gods, five elements, NaYin, void branches, ShenSha — table-driven
🔁 Luck Cycles DaYun, LiuNian, LiuYue, XiaoYun, and child-limit (起运) calculation
🌙 Calendar Provider GanZhi and solar-term data via LunarCore-Swift
☀️ Astronomy Provider True solar time and exact solar terms via AstroCore-Swift v3
🧱 Layered Providers Calendar and astronomy engines are swappable; the core binds to neither
🧪 Golden Fixtures Self-generated baselines, cross-validated across 17,000+ charts including every boundary
🧵 Thread-Safe Targeting full Sendable conformance
🚫 Isolated Tables Derived metaphysics tables never leak into calendar engines

🧩 Architecture

BaziCore sits above calendar and astronomy libraries, keeping BaZi rules separate from Chinese lunar calendar conversion and astronomical computation. Each concern is a standalone product you can adopt independently.

BaziCore                         rules · inputs · pillar models · chart engine
   │
   ├─ BaziCoreTables             hidden stems · ten gods · five elements · NaYin · void · ShenSha
   │
   ├─ BaziCoreLuck               DaYun · LiuNian · LiuYue · XiaoYun · child-limit   (needs Tables)
   │
   ├─ BaziCoreLunarCoreAdapter   GanZhi & solar-term data            (via LunarCore-Swift)
   │
   ├─ BaziCoreAstronomy          true solar time & exact solar terms (via AstroCore-Swift v3)
   │
   └─ BaziCoreTesting            golden fixture schemas · provider parity helpers

🗂️ Modules

Module Depends on Responsibility
BaziCore Birth inputs, rule sets, pillar models, chart calculation
BaziCoreTables BaziCore Hidden stems, ten gods, five elements, NaYin, void branches, ShenSha catalogs
BaziCoreLuck BaziCore, BaziCoreTables DaYun, LiuNian, LiuYue, XiaoYun, and child-limit calculations
BaziCoreLunarCoreAdapter BaziCore, LunarCore GanZhi and solar-term data backed by LunarCore-Swift
BaziCoreAstronomy BaziCore, AstroCore True solar time and exact boundary support backed by AstroCore-Swift v3
BaziCoreTesting BaziCore Golden fixture schemas and provider parity helpers

🧠 Design Principles

  • Rules are explicit. Li Chun, Jie boundaries, Zi hour, and true solar time are represented in configuration — never hidden behind defaults.
  • Results are traceable. Boundary decisions and provider confidence travel with the chart, so any value can be explained.
  • Tables are isolated. Derived metaphysics tables do not leak into calendar or astronomy engines.
  • Validation is thorough. Golden fixtures are generated by our own engines and cross-validated across 17,000+ charts spanning more than a century, including leap days, 时辰 boundaries, and every solar-term edge.

📦 Installation

Swift Package Manager

Add the dependency:

dependencies: [
    .package(url: "https://github.com/wbx1-Ltd/BaziCore-Swift.git", from: "1.1.0"),
]

Then add only the products you need as target dependencies:

.target(
    name: "YourTarget",
    dependencies: [
        "BaziCore",                  // core rules & chart engine
        "BaziCoreTables",            // metaphysics tables
        "BaziCoreLuck",              // luck-cycle calculations
        "BaziCoreLunarCoreAdapter",  // GanZhi & solar terms via LunarCore
        "BaziCoreAstronomy",         // true solar time via AstroCore
    ]
),

Or in Xcode: File → Add Package Dependencies… → paste the URL above.

🚀 Usage

Compute a chart from a birth moment. The calculator needs a solar-term provider; BaziCoreAstronomy ships the high-precision one.

import BaziCore
import BaziCoreAstronomy

let moment = try CivilMoment(
    year: 1995, month: 6, day: 15, hour: 8, minute: 30,
    timeZoneIdentifier: "Asia/Shanghai"
)
let input = BirthInput(moment: moment, sexForLuckCycle: .female)

let solarTerms = AstronomicalSolarTermProvider.shared
let calculator = BaziCalculator(solarTermProvider: solarTerms)
let chart = try calculator.chart(for: input)

print(chart.fourPillars.chinese) // 乙亥 壬午 丁丑 甲辰
print(chart.dayMaster.chinese)   // 丁

Every chart carries a trace so any value can be explained:

chart.trace.provider     // .astronomy
chart.trace.confidence   // .canonical
chart.trace.notes        // [.yearBoundaryLiChunExact, .birthBeforeLiChun, …]

For batch calculation, warm likely years once and reuse the same provider:

solarTerms.prewarm(gregorianYears: 1995...1996)

Derive metaphysics tables and ShenSha from BaziCoreTables:

import BaziCoreTables

let tenGod = TenGodEngine.tenGod(of: chart.fourPillars.year.stem, dayMaster: chart.dayMaster)
let naYin = NaYinTable.naYin(for: chart.fourPillars.day.cycle)
let shenSha = ShenShaCatalog.ziPingCommon.evaluate(chart: chart)

Compute luck cycles from BaziCoreLuck:

import BaziCoreLuck

let direction = LuckDirection.resolve(yearStem: chart.fourPillars.year.stem, sex: .female)
let childLimit = try ChildLimitEngine.compute(
    birth: moment, direction: direction, rule: .threeDaysPerYear,
    provider: solarTerms
)
let daYun = DaYunEngine.compute(
    monthPillar: chart.fourPillars.month.cycle, birthGregorianYear: 1995,
    childLimit: childLimit, direction: direction
)

For true solar time, set the rule and inject a corrector:

var rules = BaziRuleSet.professionalDefault
rules.timeCorrection = .trueSolarTime

let calculator = BaziCalculator(
    ruleSet: rules,
    solarTermProvider: solarTerms,
    timeCorrectionProvider: TrueSolarTimeEngine()
)
let chart = try calculator.chart(for: BirthInput(
    moment: moment,
    location: CalculationLocation(longitude: 87.6)
))

🔬 Validation

BaziCoreTesting defines golden-fixture schemas and provider parity helpers so that every chart can be checked against independent, source-backed references rather than a single engine's opinion.

Strategy Description
Golden fixtures Versioned expected charts stored as fixtures and replayed in CI
Provider parity Same input run through different calendar/astronomy providers must agree
Cross-validation Engine output checked across 17,000+ charts and the full solar-term range, to the second
Boundary cases Li Chun, Jie transitions, late Zi hour, and true-solar-time edges

⚡ Performance

Measured on Apple Silicon, release build.

Metric Result
🏎️ Four-pillar throughput ~25,000 charts/sec (≈40 µs/chart, warm)
🔮 With full luck cycle ~19,000 charts/sec (≈53 µs/chart)
❄️ Cold single chart ~5 ms (first chart computes solar terms)
🌞 Child-limit boundary lookup Nearby Jie fast path for natural providers, with full-scan fallback
🧠 Memory ~8 MB steady — flat from 20k to 200k charts, no leaks
Validation 17,000+ charts cross-checked across 1902–2099, zero discrepancies

Solar-term instants are computed to the second. The bounded term cache is thread-safe and never grows unbounded. For batch workloads, reuse AstronomicalSolarTermProvider.shared and call prewarm(gregorianYears:) before chart calculation to keep solar-term roots warm across charts and luck-cycle calculations.

🗺️ Roadmap

The computation layers are complete, cross-validated, and shipped in 1.0.0.

  • Package layout, six-module split, and CI (format / lint / test)
  • Birth inputs and configurable rule sets
  • Four Pillars chart engine
  • Metaphysics tables (BaziCoreTables)
  • Calendar and astronomy adapters (LunarCore / AstroCore)
  • Luck-cycle calculations (BaziCoreLuck)
  • Golden fixtures and cross-validation suite (BaziCoreTesting)
  • First tagged release (1.0.0)
  • AstroCore v3 migration and shared solar-term cache (1.1.0)

📋 Supported Range

Item Range
🖥️ Platforms iOS 15+ · macOS 12+ · tvOS 15+ · watchOS 8+ · visionOS 1+
🔧 Swift 6.0+
🌙 Calendar provider LunarCore-Swift 1.2.0+
☀️ Astronomy provider AstroCore-Swift 3.0.0+

📚 References

Source Usage
LunarCore-Swift GanZhi and solar-term data provider
AstroCore-Swift True solar time, precise solar terms, and JD-native astronomy primitives

📝 License

Copyright © 2026-present wbx1 Ltd..
This project is MIT licensed.

About

A rigorous BaZi (Four Pillars) computation core in pure Swift — explicit rules, traceable boundaries, and golden-fixture validation.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages