Skip to main content

x-iztro

crates.io PyPI Go Reference License: MIT

中文文档:README.zh-CN.md

Give it a birth date and hour; get back a complete Zi Wei Dou Shu (紫微斗数, Purple Star Astrology) chart — twelve palaces, every star with its brightness and transformation, decadal and annual horoscopes — as typed objects in Rust, Python, or Go, plus a single call that renders the whole chart as text you can hand straight to an LLM.

What the LLM-ready output looks like

from x_iztro import Astro

astro = Astro()
chart = astro.by_solar("2000-8-16", 2, "female")
print(astro.astrolabe_to_prompt(chart))
=== 基本信息 ===
性别: 女
阳历: 2000-8-16
农历: 二〇〇〇年七月十七
干支: 庚辰 甲申 丙午 庚寅
时辰: 寅时 (03:00~05:00)
星座: 狮子座
生肖: 龙
命宫地支: 午
身宫地支: 戌
命主: 破军
身主: 文昌
五行局: 木三局
生年四化: 太阳禄, 武曲权, 太阴科, 天同忌

=== 十二宫 ===

--- 财帛 ---
天干地支: 戊寅
大限: 43-52
小限虚岁: 9, 21, 33, 45, 57, 69, 81, 93, 105, 117
十二神: 绝, 飞廉, 吊客, 岁驿
主星: 武曲(得)[权], 天相(庙)
辅星: 天马
杂耀: 解神, 三台, 天寿, 天巫, 天厨, 阴煞, 天哭

--- 夫妻 [来因] ---
天干地支: 庚辰
大限: 23-32
小限虚岁: 7, 19, 31, 43, 55, 67, 79, 91, 103, 115
十二神: 死, 将军, 岁建, 华盖
主星: 七杀(庙)
辅星: 右弼, 火星(陷)
杂耀: 封诰, 华盖

... (all twelve palaces)

The same text is available in six languages — pass language="en-US" and the stars, palaces and brightness levels come out as general([+1])[B], wealth, Tiger hour, Twelve Gods: dissipated, gossip, … and so on. horoscope_to_prompt does the same for a horoscope at a given date.

Why not just ask the LLM to cast the chart?

Casting a chart is arithmetic, not interpretation: lunar/solar conversion, leap month handling, sexagenary cycle, the placement rules for ~100 stars, and the 四化 transformation table. A language model gets some of it right and quietly gets the rest wrong, and you cannot tell which from the output. This library does the arithmetic deterministically and verifiably, then hands the LLM the part it is actually good at — reading the chart.

Install

Rust

[dependencies]
x-iztro = "0.2"

Python — requires 3.10+, ships as an abi3 wheel with zero runtime dependencies.

pip install x-iztro

Go — the core library is embedded as WebAssembly and driven by the pure-Go wazero runtime: no cgo, no Rust toolchain, cross-compilation works as usual.

go get github.com/x-haose/x-iztro/go/iztro

Quick start

Rust

use x_iztro::{by_solar, IztroError};
use x_iztro::data::types::*;

fn main() -> Result<(), IztroError> {
    let chart = by_solar(
        "2000-8-16",        // solar birth date
        2,                  // hour index: 0 = early Rat hour … 12 = late Rat hour
        Gender::Female,
        true,               // fix_leap: split leap months at the midpoint
        Language::ZhCN,
        Config::default(),  // boundaries and school; defaults match JS iztro
    )?;

    // Translated strings; `soul` and `five_elements_class` are language-independent
    // keys (`StarKey::PojunMaj`, `FiveElementsClass::Wood3rd`).
    println!("{} / {}", chart.lunar_date, chart.chinese_date);
    println!("{:?} {:?}", chart.soul, chart.five_elements_class);

    // `horoscope` derefs to the data, so the six levels are plain fields.
    let horoscope = chart.horoscope("2024-1-1", 0)?;
    println!("{:?}", horoscope.yearly.base.mutagen);

    // Bad input is an error, never a panic.
    assert!(by_solar("2000-13-1", 2, Gender::Male, true, Language::ZhCN, Config::default()).is_err());
    Ok(())
}

Python

from x_iztro import Astro, IztroError
from x_iztro.enums import MajorStar, Mutagen, PalaceName

chart = Astro().by_solar("2000-8-16", 2, "female")
print(chart.chinese_date, chart.soul, chart.five_elements_class)

# Enums are language-independent keys, so these checks give the same answer
# no matter which language the chart was rendered in.
soul = chart.palace(PalaceName.SOUL)
print(soul.has([MajorStar.ZIWEI]), soul.has_mutagen(Mutagen.LU))

horoscope = chart.horoscope("2024-1-1", 0)
print(horoscope.yearly.heavenly_stem, horoscope.yearly.earthly_branch)

# IztroError subclasses ValueError; .code is a machine-readable category.
try:
    Astro().by_solar("2000-13-1", 2, "male")
except IztroError as e:
    print(e.code)  # invalid_date

Go

package main

import (
    "errors"
    "fmt"
    "log"

    "github.com/x-haose/x-iztro/go/iztro"
)

func main() {
    chart, err := iztro.BySolar("2000-8-16", 2, iztro.GenderFemale, true, iztro.LanguageZhCN, nil)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(chart.ChineseDate, chart.Soul, chart.FiveElementsClass)

    soul := chart.Palace(iztro.PalaceSoul)
    fmt.Println(soul.Has(iztro.StarZiweiMaj), soul.HasMutagen(iztro.MutagenLu))

    horoscope, err := chart.Horoscope("2024-1-1", 0)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(horoscope.Yearly.HeavenlyStem, horoscope.Yearly.EarthlyBranch)

    // Errors carry a category you can match with errors.Is.
    _, err = iztro.BySolar("2000-13-1", 2, iztro.GenderMale, true, iztro.LanguageZhCN, nil)
    fmt.Println(errors.Is(err, iztro.ErrInvalidDate)) // true
}

Features

  • Full chart — twelve palaces, body palace, soul/body stars, five elements class, major/minor/adjective stars with brightness and 四化 transformations.
  • Six horoscope levels — decadal, yearly, monthly, daily, hourly and the childhood limit, each with its own palaces and transformations.
  • Chart queries — locate a palace by name, branch or index; test stars, transformations and empty palaces; the 三方四正 surrounded-palace group; and the flying-star (飞星) family.
  • Two schools — the default school and 中州派 (Zhongzhou), selected per chart.
  • Six languages — zh-CN, zh-TW, en-US, ja-JP, ko-KR, vi-VN, with language-independent key constants so your logic never depends on the display language.
  • LLM outputastrolabe_to_prompt / horoscope_to_prompt render a whole chart as structured text.
  • Validated input — date format and existence, solar years 1583–9999, hour index 0–12. Invalid input returns Err(IztroError) in Rust, raises x_iztro.IztroError (a ValueError) in Python, returns an error matchable with errors.Is in Go, and yields {"error":"..."} JSON over the C FFI. Every failure carries a machine-readable category. Nothing panics.

Accuracy

Every number is checked field-by-field against the JavaScript iztro v2.5.8 (version-pinned), with zero tolerance for differences. Roughly 710,000 golden cases in eight layers:

Layer Cases Coverage
Tier 1 1,560 60 years × 13 hours × both genders, every field compared individually
Tier 2 37,440 60 years × the 1st and 15th of each month × 13 hours × both genders
Tier 3 586,430 every day of 60 years × 13 hours × both genders × fix_leap, hashed
Edge years 46,228 the far ends of the supported range, where leap months and tables strain
Horoscope 5,760 360 charts × 16 target dates, all six horoscope levels, every field
Variants 14,268 lunar-date charts across leap months, Zhongzhou school, all six languages
Config 9,696 each boundary switch at its non-default value
Astro type 12,488 the heaven / earth / human chart perspectives

On top of that: the serialization contract is compared key-by-key against JS JSON.stringify, and the three bindings are cross-checked so that the same birth data yields the same answers in Rust, Python and Go.

cargo test                                               # regular layers, ~15s
cargo test --release --test golden_tier3 -- --ignored    # Tier 3 in full, ~20s

Configuration

Six switches, passed explicitly per chart — there is no global state.

Switch Values Default Effect
year_divide normal / exact normal Year boundary: lunar new year, or 立春
horoscope_divide normal / exact normal Horoscope boundary: 1st of the month, or solar term
age_divide normal / birthday normal Nominal age: increments at new year, or on the birthday
day_divide forward / current forward Late Rat hour belongs to the next day, or the current one
algorithm default / zhongzhou default School of placement rules
astro_type heaven / earth / human heaven Chart perspective (Zhongzhou)

Custom 四化 and brightness tables can be supplied alongside them.

Documentation

https://ziwei.x-hoase.com — the documentation site, in Chinese and English: a guide that starts from zero, the Zi Wei concepts behind the data model, and per-language API references where every function, type and method has its own entry with real output and edge-case notes. LLM-friendly endpoints: /llms.txt, /llms-full.txt, and any page with .md appended.

The site lives in docs/ (cd docs && npm ci && npm run dev to run it locally). Rust API docs are also published at docs.rs/x-iztro. Runnable projects for all three languages are under examples/.

Building from source

Only needed when changing the Rust core.

cargo build --release

# Python bindings
PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 maturin develop --features python

# Go bindings: rebuild and refresh the embedded wasm
cargo build --release --target wasm32-wasip1
cp target/wasm32-wasip1/release/x_iztro.wasm go/iztro/

Golden test data is generated from the JS iztro package:

cd tests/golden && npm install && node generate_tier1.mjs   # …and the other generators

Credits

Ported from iztro by SylarLong. New to Zi Wei Dou Shu? Its author maintains an introduction at iztro.com.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

x_iztro-0.2.0.tar.gz (158.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

x_iztro-0.2.0-cp310-abi3-win_amd64.whl (591.8 kB view details)

Uploaded CPython 3.10+Windows x86-64

x_iztro-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (794.7 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

x_iztro-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (771.5 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

x_iztro-0.2.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (1.3 MB view details)

Uploaded CPython 3.10+macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file x_iztro-0.2.0.tar.gz.

File metadata

  • Download URL: x_iztro-0.2.0.tar.gz
  • Upload date:
  • Size: 158.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for x_iztro-0.2.0.tar.gz
Algorithm Hash digest
SHA256 709506fd36c1744d8f6e3e69f6c806a55ddf0bae8c48291b66d52e605567c7cf
MD5 e5635d8b0de3f42533318845efe5f2ba
BLAKE2b-256 beeb21ae4f9934397ac873d5e6481523421066d813bc22743360bfe3d4d38dea

See more details on using hashes here.

Provenance

The following attestation bundles were made for x_iztro-0.2.0.tar.gz:

Publisher: wheels.yml on x-haose/x-iztro

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file x_iztro-0.2.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: x_iztro-0.2.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 591.8 kB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for x_iztro-0.2.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 126aa1ca4a0fc8699c56d749a73c0d118a2d4fe1586a11e8d9547fc5d0ba70a5
MD5 152937a1ba6d2bd569f32d6b596c38f9
BLAKE2b-256 1d4676f313f6764dd3a051e639eaab912be3f476234dac5ca956e06396a5ea70

See more details on using hashes here.

Provenance

The following attestation bundles were made for x_iztro-0.2.0-cp310-abi3-win_amd64.whl:

Publisher: wheels.yml on x-haose/x-iztro

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file x_iztro-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for x_iztro-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7f18515d14b6a238eec157207bcdde5ad609e0c02f645113c8f79844d24e0e9b
MD5 6824bbe098cbc6f2af39f5969520f45d
BLAKE2b-256 4f309ddc1fef83b3bc5662bdedd60257de1c122046750a7c463e9467e46895d8

See more details on using hashes here.

Provenance

The following attestation bundles were made for x_iztro-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: wheels.yml on x-haose/x-iztro

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file x_iztro-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for x_iztro-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 65d42f24116f021d5b4a3699d04d0c1cac4d56eeb1197e3dd44e205d99809fd2
MD5 16309e068e47cd2a0bd5e97bdda41ce2
BLAKE2b-256 603f9776392cc7c501b39990a2018e615ffcdc98b0479e611f39aceb496039ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for x_iztro-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: wheels.yml on x-haose/x-iztro

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file x_iztro-0.2.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for x_iztro-0.2.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 6ee8611aa7d0336fe2afb4a02247c2129c252040fdf223186f8c6e1548247d66
MD5 bfc375324ae10fc373e89daede37212b
BLAKE2b-256 75a6995f412243504c5c1d947019d5ef7e2be1c5f04f28883f62309e3527f665

See more details on using hashes here.

Provenance

The following attestation bundles were made for x_iztro-0.2.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: wheels.yml on x-haose/x-iztro

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page