Charting entries
by_solar, by_lunar, rearranged and the JSON convenience variants.
Charting is where everything starts: give a birth date, hour and gender, get an Astrolabe.
This page is the full reference for the four charting entry points.
The entry points that take external input (by_solar, by_lunar, the two JSON variants and
get_horoscope) all return a Result: date format and existence, the solar year range and the hour
index are validated up front in the core, and invalid input returns an IztroError rather than
panicking. rearranged also returns a Result (guarding against invalid raw_dates from
deserialized charts); functions whose parameters are all enums with no invalid values
(astrolabe_to_text and friends) return their result directly. Error types are on
Error handling.
by_solar
Purpose Chart a natal chart from a solar date.
Zi Wei meaning Zi Wei Dou Shu computes on the lunar calendar, but most people only remember their
solar birthday. This function converts solar to lunar first (including the year, month, day and hour
pillars) and places the stars from there.
When the year turns over is governed by year_divide — for someone born between lunar New Year and
the Beginning of Spring, the two settings give different year pillars, which in turn affects the
mutagens, the soul and body stars, and every year-based star.
Signature
pub fn by_solar(
solar_date: &str,
time_index: u8,
gender: Gender,
fix_leap: bool,
language: Language,
config: Config,
) -> Result<Astrolabe, IztroError>Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
solar_date | &str | Yes | — | Solar date in YYYY-M-D; month and day need no zero padding. Years 1583–9999 |
time_index | u8 | Yes | — | Hour index 0–12. 0 is the early Zi hour (00:00–01:00), 12 the late Zi hour (23:00–24:00) |
gender | Gender | Yes | — | Gender::Male or Gender::Female. Sets the direction of the decadal scope and of the Changsheng and Boshi gods |
fix_leap | bool | Yes | — | Whether to correct for lunar leap months. When true, days after the fifteenth of a leap month count as the next month (except in the late Zi hour, see below) |
language | Language | Yes | — | Output language; affects every translated field in the DTO. The *_key fields are unaffected |
config | Config | Yes | — | Charting configuration: six switches plus custom tables. Use Config::default() for the defaults |
Return value Astrolabe — a complete chart with the twelve palaces, the four pillars, the soul
and body stars and the five elements class. The field list is on
the data model.
Example
use x_iztro::*;
let chart = by_solar("2000-8-16", 2, Gender::Female, true, Language::EnUS, Config::default())?;
println!("{} | {} | {}", chart.solar_date, chart.lunar_date, chart.chinese_date);
println!("{} {} {}", chart.sign, chart.zodiac,
translate_five_elements_class(chart.five_elements_class, Language::EnUS));
println!("soul {} body {}",
translate_star(chart.soul, Language::EnUS),
translate_star(chart.body, Language::EnUS));five_elements_class, soul and body are strongly typed enums, not strings — compare them directly
in predicates, and run them through i18n::translate_* when you need display text in the current
language.
Output
2000-8-16 | 二〇〇〇年七月十七 | geng chen - jia shen - bing woo - geng yin
leo dragon wood 3rd
soul rebel body scholarlunar_date stays in Chinese numerals in every language: 二〇〇〇年七月十七 is "the 17th day of the
7th lunar month of 2000". The star names are iztro's en-US vocabulary — rebel is Pojun, scholar
is Wenchang.
Edge cases and pitfalls
by_lunar
Purpose Chart a natal chart from a lunar date.
Zi Wei meaning The lunar date is Zi Wei Dou Shu's native input, and this skips the solar
conversion. Anyone who knows their lunar birthday can use it directly; the result is identical to
calling by_solar with the corresponding solar date.
Signature
pub fn by_lunar(
lunar_date: &str,
time_index: u8,
gender: Gender,
leap: LeapMonth,
language: Language,
config: Config,
) -> Result<Astrolabe, IztroError>Parameters
Identical to by_solar apart from the following two; by_solar's fix_leap is folded into leap here.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
lunar_date | &str | Yes | — | Lunar date in YYYY-M-D; write the month as a positive number (leap months are flagged by the next parameter) |
leap | LeapMonth | Yes | — | NotLeap — not a leap month; Leap — leap month, charted as itself; LeapFixed — leap month, and days after the 15th are treated as the next month (iztro fixLeap). Flagging a leap month that does not exist in that year falls back to the ordinary month |
Return value Same as by_solar.
Example
use x_iztro::*;
let a = by_lunar("2000-7-17", 2, Gender::Female, LeapMonth::NotLeap, Language::EnUS, Config::default())?;
let b = by_solar("2000-8-16", 2, Gender::Female, true, Language::EnUS, Config::default())?;
assert_eq!(a.solar_date, b.solar_date);
println!("{}", a.solar_date);Output
2000-8-16Edge cases and pitfalls
The silent fallback for a wrongly flagged leap month is deliberate
Flag leap as a leap month when that month is not one and the chart is cast for the ordinary month
without an error (as in iztro). If you need strict validation, confirm the leap month exists for that
year and month before calling. LeapMonth::from_flags(is_leap_month, fix_leap) converts from the
iztro-style pair of booleans.
rearranged
Purpose Re-anchor the chart on a given stem and branch as the Soul palace and return a new chart; the original is untouched.
Zi Wei meaning The Zhongzhou school reads one set of birth data as three charts: the heaven chart anchors the five elements class on the Soul palace's pillar, the earth chart on the body palace's, the human chart on the Spirit palace's. Change the anchoring pillar and the class changes, and with it the placement of Ziwei and Tianfu, the twelve palace names, the Changsheng gods and the decadal and age scopes are all recomputed. This method opens that capability up to any stem and branch, not just those three.
Signature
pub fn rearranged(
&self,
from_stem: HeavenlyStem,
from_branch: EarthlyBranch,
) -> Result<Astrolabe, IztroError>Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
from_stem | HeavenlyStem | Yes | — | Stem of the new Soul palace |
from_branch | EarthlyBranch | Yes | — | Branch of the new Soul palace |
Return value Result<Astrolabe, IztroError>. A chart produced by a charting entry point always
rearranges successfully; IztroError::Internal is returned only when raw_dates was deserialized
or hand-built with a lunar month that does not exist in the month table.
Recomputed: the Soul and body palaces, the five elements class,
the fourteen major stars, the twelve palace names, the Changsheng gods, the decadal and age scopes,
plus Tianshang, Tianshi and Tiancai, which follow the Soul palace. Carried over from the original
chart: minor stars, the remaining adjective stars, the Boshi gods and the Sui-qian and Jiang-qian
gods.
On the rearranged chart, patterns() / patterns_with(), horoscope queries and the to_text
projection
all compute from the rearranged layout — the five elements class, soul palace and decadal
ranges follow the new starting stem-branch; the birth data (dates and four pillars) stays unchanged.
Example
use x_iztro::*;
let chart = by_solar("2000-8-16", 2, Gender::Female, true, Language::EnUS, Config::default())?;
// anchor on the original chart's body palace pillar — equivalent to the earth chart
let body = chart.palaces.iter().find(|p| p.is_body_palace).unwrap();
let earth = chart.rearranged(body.heavenly_stem, body.earthly_branch)?;
println!("heaven {} → earth {}",
translate_five_elements_class(chart.five_elements_class, Language::EnUS),
translate_five_elements_class(earth.five_elements_class, Language::EnUS));Output
heaven wood 3rd → earth earth 5thEdge cases and pitfalls
The three standard charts do not need this method
For the heaven, earth and human charts just chart with
Config::default().with_astro_type(AstroType::Earth); both charting entry points support it.
rearranged exists for anchoring on an arbitrary stem and branch.
by_solar_json / by_lunar_json
Purpose Chart and return the DTO as a JSON string directly, sparing the caller the serialization.
Signature
pub fn by_solar_json(
solar_date: &str,
time_index: u8,
gender: Gender,
fix_leap: bool,
language: Language,
config: Config,
) -> Result<String, IztroError>
pub fn by_lunar_json(
lunar_date: &str,
time_index: u8,
gender: Gender,
leap: LeapMonth,
language: Language,
config: Config,
) -> Result<String, IztroError>Parameters Exactly the same as the corresponding charting functions.
Return value String — the JSON serialization of the DTO, with
camelCase keys, values translated per language, plus the language-independent *Key fields.
Example
use x_iztro::*;
let json = by_solar_json("2000-8-16", 2, Gender::Female, true, Language::EnUS, Config::default())?;
let v: serde_json::Value = serde_json::from_str(&json)?;
println!("{} {}", v["solarDate"], v["palaces"][0]["nameKey"]);Output
"2000-8-16" "wealthPalace"Edge cases and pitfalls
These two are just shortcuts for by_solar(...)?.to_dto() plus serialization.
For further analysis on the Rust side use by_solar to get an Astrolabe, which gives you all the
query methods; reach for the JSON variants only when handing the result to another process or a
frontend.
get_horoscope
Purpose Compute the horoscope for a target date, starting from a natal chart.
Zi Wei meaning A horoscope layers six scopes — decadal, age, yearly, monthly, daily and hourly — onto the natal chart, each with its own starting palace, pillar and scope stars.
Signature
pub fn get_horoscope(
astrolabe: &Astrolabe,
solar_date: &str,
time_index: u8,
language: Language,
) -> Result<HoroscopeData, IztroError>Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
astrolabe | &Astrolabe | Yes | — | The natal chart |
solar_date | &str | Yes | — | Target solar date in YYYY-M-D, years 1583–9999 |
time_index | u8 | Yes | — | Target hour index 0–12 |
language | Language | Yes | — | Output language |
Return value Result<HoroscopeData, IztroError>. Details on
the horoscope object.
Example
use x_iztro::*;
let chart = by_solar("2000-8-16", 2, Gender::Female, true, Language::EnUS, Config::default())?;
let h = get_horoscope(&chart, "2025-1-1", 0, Language::EnUS)?;
println!("decadal palace index {}, yearly pillar {:?}{:?}",
h.decadal.index, h.yearly.heavenly_stem, h.yearly.earthly_branch);Output
decadal palace index 2, yearly pillar JiaChenEdge cases and pitfalls
When you want to keep querying off the horoscope (fetching a scope's palaces, testing scope stars),
use the astrolabe method chart.horoscope(...) to get a HoroscopeRef — it holds the natal chart
too, so queries need not be handed the chart again. The free function here returns only the data.
astrolabe_to_text / horoscope_to_text
Purpose Project a chart or a horoscope into semantic text — the chart's facts in
natural-language form, for a language model or a person. Alongside serde_json (machine structure)
and the translated fields (display), it is the third projection of the same object.
Signature (the x_iztro::text module, which also holds palace_to_text /
surrounded_palaces_to_text / patterns_to_text)
pub fn astrolabe_to_text(astrolabe: &Astrolabe, lang: Language) -> String
pub fn horoscope_to_text(
astrolabe: &Astrolabe,
horoscope: &HoroscopeData,
lang: Language,
) -> StringConvenience methods that emit in the chart language: Astrolabe::to_text(),
HoroscopeRef::to_text(), PalaceRef::to_text(); SurroundedPalaces::to_text(lang) takes an
explicit language. The free functions' lang may differ from the charting language: star names,
hours, zodiac signs, stems and branches and flowing stars are all re-translated by key into the
target language, byte-identical to a chart cast in that language.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
astrolabe | &Astrolabe | Yes | — | The natal chart |
horoscope | &HoroscopeData | Yes | — | The result of get_horoscope |
lang | Language | Yes | — | Output language, which switches both the section headings and the star names |
Return value String, sectioned plain text; the natal text closes with a patterns section, and
each horoscope scope carries a patterns line and flowing-star lines from its own perspective.
Example
use x_iztro::*;
let chart = by_solar("2000-8-16", 2, Gender::Female, true, Language::EnUS, Config::default())?;
print!("{}", chart.to_text());Output
=== Basic Info ===
Gender: female
Solar Date: 2000-8-16
Lunar Date: 二〇〇〇年七月十七
Chinese Date: geng chen - jia shen - bing woo - geng yin
Time: Tiger hour (03:00~05:00)
Zodiac Sign: leo
Zodiac Animal: dragon
Soul Palace Branch: woo
Body Palace Branch: xu
Soul Star: rebel
Body Star: scholar
Five Elements Class: wood 3rd
Birth-Year Mutagen: sunA, generalB, moonC, fortunateD
=== Palaces ===
--- wealth ---
Stem-Branch: wuyin
Decadal: 43-52
Age Fortune Years: 9, 21, 33, 45, 57, 69, 81, 93, 105, 117
Twelve Gods: dissipated, gossip, sorrowing, varied
Major Stars: general([+1])[B], minister([+3])
Minor Stars: horse
Adjective Stars: considery, senior, ageless, psychic, gourmet, gloomy, upset
(the other eleven palaces follow the same format and are omitted here)
=== Patterns ===
- Empress and Minister Facing the Palace(soul): empress([+3]), minister([+3])The complete output with a field-by-field walkthrough is on Semantic text.
This is an addition of x-iztro's beyond iztro, available in all three languages. Wiring it to a model is covered on Docs for AI.