Astrolabe object
The fields of Astrolabe, its lookup methods, and the surrounded and flanking palaces.
Astrolabe is what charting produces and the entry point for every query. It holds all the data of
the twelve palaces along with chart-level information such as the four pillars, the soul and body
stars and the five elements class.
chart, _ := iztro.BySolar("2000-8-16", 2, iztro.GenderFemale, true, iztro.LanguageEnUS, nil)The examples on this page chart with "en-US", so the display values in the output are English.
Charting in another language changes only those display strings; the *Key fields and the results of
every predicate stay the same.
Fields
Palace / PalaceByIndex
Purpose Fetch a palace by name, as the Body palace or the palace of origin, or by index.
Zi Wei meaning The twelve palaces are the skeleton of a chart. Once the Soul palace is fixed the other eleven follow counterclockwise in a fixed order. The "Body palace" is whichever of the twelve also carries that flag, marking where acquired effort concentrates; the "palace of origin" is the one whose stem matches the birth-year stem, marking where matters originate.
Signature
func (a *Astrolabe) Palace(nameKeyOrName string) *Palace
func (a *Astrolabe) PalaceByIndex(index int) *PalaceParameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
nameKeyOrName | string | Yes | — | A palace-name key, "bodyPalace", "originalPalace", or a translated palace name |
index | int | Yes | — | Palace index 0–11, where 0 is the Yin palace |
Return value *Palace. nil when the name is misspelled or the index is out of range;
a palace name such as "soulPalace", plus "bodyPalace" and "originalPalace", resolves on every
chart as long as it is spelled correctly.
Example
soul := chart.Palace(iztro.PalaceSoul)
fmt.Println(soul.Name, soul.HeavenlyStem+soul.EarthlyBranch)
fmt.Println("body:", chart.Palace("bodyPalace").Name)
fmt.Println("origin:", chart.Palace("originalPalace").Name)
fmt.Println("Yin palace:", chart.PalaceByIndex(0).Name)Output
soul renwoo
body: career
origin: spouse
Yin palace: wealthEdge cases and pitfalls
Star
Purpose Find a star by key and get the palace it sits in at the same time.
Signature
func (a *Astrolabe) Star(keyOrName string) (*Star, *Palace)Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
keyOrName | string | Yes | — | A star key or a translated name |
Return value (*Star, *Palace). Both are nil when the star is not on this chart.
Example
ziwei, palace := chart.Star(iztro.StarZiweiMaj)
fmt.Println(ziwei.Name, "sits in", palace.Name)
fmt.Println("its opposite palace is", ziwei.OppositePalace().Name)
fmt.Println("brightness", ziwei.Brightness, "mutagen", ziwei.Mutagen)Output
emperor sits in soul
its opposite palace is surface
brightness [+3] mutagen An empty mutagen string means this star has no natal mutagen.
Edge cases and pitfalls
The search covers only the three groups of major, minor and adjective stars. The Changsheng, Boshi,
Sui-qian and Jiang-qian gods are one-per-palace marks rather than star lists — read them from fields
like palace.Changsheng12Key.
SurroundedPalaces / SurroundedPalacesByIndex
Purpose Fetch the surrounded palaces of a target palace.
Zi Wei meaning The surrounded set is the most commonly used reading scope in Zi Wei Dou Shu: the palace itself, its opposite (the palace +6), the career position (+4) and the wealth position (+8). The four are read together rather than the palace alone, because the stars of the opposite and trine palaces bear on the palace's affairs just as much.
Signature
func (a *Astrolabe) SurroundedPalaces(nameKeyOrName string) *SurroundedPalaces
func (a *Astrolabe) SurroundedPalacesByIndex(index int) *SurroundedPalacesReturn value *SurroundedPalaces, holding the four *Palaces Target / Opposite / Wealth /
Career. SurroundedPalaces returns nil on a misspelled name; SurroundedPalacesByIndex takes the
index modulo 12, so negative indices and indices above 11 wrap correctly and only a zero-valued chart
(fewer than twelve palaces) gives nil.
Its predicates are on Surrounded palaces.
Example
sp := chart.SurroundedPalaces(iztro.PalaceSoul)
fmt.Println(sp.Target.Name, sp.Opposite.Name, sp.Wealth.Name, sp.Career.Name)
fmt.Println("Ziwei in the surrounded set:", sp.Have(iztro.StarZiweiMaj))Output
soul surface wealth career
Ziwei in the surrounded set: trueIsSurrounded / IsSurroundedOneOf / NotSurrounded
Purpose Test the surrounded palaces of a palace straight from the chart, skipping the step of fetching the set first.
Signature
func (a *Astrolabe) IsSurrounded(nameKeyOrName string, stars ...string) bool
func (a *Astrolabe) IsSurroundedOneOf(nameKeyOrName string, stars ...string) bool
func (a *Astrolabe) NotSurrounded(nameKeyOrName string, stars ...string) boolParameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
nameKeyOrName | string | Yes | — | A palace-name key or a translated name |
stars | ...string | Yes | — | Star keys, variadic |
Return value
| Method | Meaning |
|---|---|
IsSurrounded | Every listed star is in the surrounded set |
IsSurroundedOneOf | At least one listed star is in the surrounded set |
NotSurrounded | None of the listed stars is in the surrounded set |
Example
fmt.Println(chart.IsSurrounded(iztro.PalaceSoul, iztro.StarZiweiMaj, iztro.StarTianxiangMaj))
fmt.Println(chart.IsSurroundedOneOf(iztro.PalaceSoul, iztro.StarQishaMaj, iztro.StarPojunMaj))
fmt.Println(chart.NotSurrounded(iztro.PalaceSoul, iztro.StarHuoxingMin))Output
true
false
trueThe Soul palace holds only Ziwei, while Tianxiang sits in the Wealth palace, one of the trine — hence the first line is true. Neither Qisha nor Pojun is in any of the four, hence the second is false.
Edge cases and pitfalls
What passing no stars returns
With no stars at all, IsSurrounded and NotSurrounded return true ("all elements satisfy" and "no
element fails" both hold vacuously) while IsSurroundedOneOf returns false.
FlankingPalaces
Purpose Get a palace's flanking pair: the two palaces immediately before and after it on the chart.
Zi Wei meaning Phrases like "Qing Yang and Tuo Luo flank Ji" or "Sun and Moon flank the Soul palace" are about exactly this pair. Flanking and the surrounded set are two non-overlapping lines of evidence: the surrounded set asks how one group of energies echoes itself, flanking asks what stands on either side.
Signature
func (a *Astrolabe) FlankingPalaces(target PalaceTarget) (*FlankingPalaces, error)
func (a *Astrolabe) FlankingPalacesContext(ctx context.Context, target PalaceTarget) (*FlankingPalaces, error)Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
target | PalaceTarget | Yes | — | A non-empty Key addresses by palace-name key (PalaceBody / PalaceOriginal also accepted); otherwise Index is used |
Return value *FlankingPalaces, with two *Palace fields:
| Field | Offset | Description |
|---|---|---|
Previous | -1 | The preceding palace |
Next | +1 | The following palace |
The twelve palaces form a ring — indices wrap modulo 12, so palace 0 is preceded by palace 11.
Both fields are palaces of this chart, so Palace's flying-mutagen and surrounded-set queries work as usual.
The five predicates are named and defined exactly as on the surrounded set; only the scope changes to these two palaces:
| Method | Meaning |
|---|---|
Have(stars ...string) bool | The two palaces together hold every star in the list |
NotHave(stars ...string) bool | Neither palace holds any of them |
HaveOneOf(stars ...string) bool | The two together hold at least one |
HaveMutagen(mutagenKey string) bool | Either palace carries that natal mutagen |
NotHaveMutagen(mutagenKey string) bool | Neither one does |
Stars are variadic and may be written as constants such as StarZiweiMaj or as star names in the
chart's language.
Example
f, _ := chart.FlankingPalaces(iztro.PalaceTarget{Key: iztro.PalaceSoul})
fmt.Println(f.Previous.Name, "/", f.Next.Name)
fmt.Println(f.Have(iztro.StarTianjiMaj, iztro.StarTuoluoMin))
fmt.Println(f.HaveOneOf(iztro.StarHuoxingMin))
w, _ := chart.FlankingPalaces(iztro.PalaceTarget{Key: iztro.PalaceWealth})
fmt.Println(w.Previous.Name, "/", w.Next.Name)
fmt.Println(w.HaveMutagen(iztro.MutagenLu), w.HaveMutagen(iztro.MutagenJi))Output
siblings / parents
true
false
health / children
true trueThe Soul palace sits in woo, flanked by siblings (si) and parents (wei). Tianji sits in siblings and
Tuoluo in parents — different palaces, yet Have still holds. Huoxing sits in spouse, outside the pair,
so HaveOneOf is false. Wealth sits in yin, flanked by health (Tiantong) and children (Taiyang);
this chart's natal stem geng turns Taiyang to Lu and Tiantong to Ji, so both mutagen questions are true.
Edge cases and pitfalls
Horoscope / HoroscopeNow
Purpose Compute the horoscope for a target date, starting from this chart.
Signature
func (a *Astrolabe) Horoscope(targetDate string, targetTimeIndex uint8) (*Horoscope, error)
func (a *Astrolabe) HoroscopeNow() (*Horoscope, error)Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
targetDate | string | Yes | — | Target solar date in YYYY-M-D |
targetTimeIndex | uint8 | Yes | — | Target hour index 0–12, which fixes the hourly scope |
HoroscopeNow takes the current date and hour from the local clock and has no parameters.
Return value *Horoscope — a horoscope object holding this chart, so palace lookups across the
six scopes need not be passed the astrolabe again.
Details on the horoscope object.
Example
h, _ := chart.Horoscope("2025-6-1", 0)
fmt.Println("decadal", h.Decadal.HeavenlyStem+h.Decadal.EarthlyBranch)
fmt.Println("yearly ", h.Yearly.HeavenlyStem+h.Yearly.EarthlyBranch)Output
decadal gengchen
yearly yisiToText / PalaceToText / SurroundedPalacesToText
Purpose Semantic text for the chart, a single palace or the surrounded palaces: a complete description for language models and people.
Signature
func (a *Astrolabe) ToText() (string, error)
func (a *Astrolabe) PalaceToText(target PalaceTarget) (string, error)
func (a *Astrolabe) SurroundedPalacesToText(target PalaceTarget) (string, error)Each has a Context variant. With a non-empty Key, PalaceTarget locates the palace by name key
(PalaceSoul etc.; PalaceBody / PalaceOriginal are also accepted), otherwise by Index (0–11).
Emits in the charting language; the full format is on
Semantic text.
Example
text, _ := chart.PalaceToText(iztro.PalaceTarget{Key: iztro.PalaceSoul})
fmt.Println(strings.Split(text, "\n")[0])Output
### soul (ren woo) · Decadal 3-12The single-palace text is exactly that palace's section under the natal text's Palaces
heading; the surrounded-palaces text opens with ## soul Trine & Opposite followed by four
sections — the target, its opposite, the wealth position and the career position — each headed
with its role (### Target Palace · soul (ren woo) · Decadal 3-12) and with fact lines identical
to the palace text. For pattern text see PatternsToText on Patterns.
ToTextWith / PalaceToTextWith / SurroundedPalacesToTextWith
Purpose The text of the matching ToText, with readings from a knowledge pack woven in
according to opts: after each palace's fact lines come that palace's star readings
(**star(brightness) [A]**: body, with a same-palace major-star combination
**A × B (same palace)**: first; the twelve gods carry no reading), after the pattern list come
the pattern readings (with a Conditions: line), and the natal text closes with ## Mutagen Notes.
Signature
func (a *Astrolabe) ToTextWith(opts TextOptions) (string, error)
func (a *Astrolabe) PalaceToTextWith(target PalaceTarget, opts TextOptions) (string, error)
func (a *Astrolabe) SurroundedPalacesToTextWith(target PalaceTarget, opts TextOptions) (string, error)Parameters
| Parameter | Type | Description |
|---|---|---|
target | PalaceTarget | As for PalaceToText |
opts | TextOptions | Output options. The Knowledge field names the source of readings: BuiltinKnowledge() takes the bundled default pack for the chart language, KnowledgeFrom(pack) uses the given pack; the PatternConfig field sets the pattern criteria for both the pattern section and the pattern readings; the zero value TextOptions{} behaves like the method without With |
Each has a Context variant. Where the readings are inserted and how they are deduplicated is on
Text with readings.
Example (on a zh-CN chart, since the bundled pack is Chinese)
plain, _ := chart.ToText()
text, _ := chart.ToTextWith(iztro.TextOptions{Knowledge: iztro.BuiltinKnowledge()})
fmt.Println(utf8.RuneCountInString(plain), utf8.RuneCountInString(text))
var heads []string
for _, l := range strings.Split(text, "\n") {
if strings.HasPrefix(l, "## ") {
heads = append(heads, l)
}
}
fmt.Println(strings.Join(heads, " "))Output
3389 20767
## 基本信息 ## 十二宫总览 ## 格局 ## 十二宫 ## 四化释义The two texts differ in their ## headings only by the closing 四化释义 (Mutagen Notes):
readings do not get sections of their own but sit right after the palace or pattern they belong
to.
Edge cases and pitfalls
BuiltinKnowledge() on a chart whose language has no bundled pack (only zh-CN has one) returns
ErrInvalidArgument rather than silently dropping the readings; on an English chart give the pack
explicitly with KnowledgeFrom(pack).
How it relates to JSON
Astrolabe and every type beneath it carry json tags whose names match the field contract of JS
iztro. json.Marshal(chart) is therefore already the DTO you can hand to a frontend or another
process:
b, err := json.Marshal(chart)
if err != nil {
log.Fatal(err)
}
var v map[string]any
_ = json.Unmarshal(b, &v)
fmt.Println(v["solarDate"], v["genderKey"], v["timeIndex"])
fmt.Println(v["palaces"].([]any)[4].(map[string]any)["nameKey"])Output
2000-8-16 female 2
soulPalaceThe custom mutagen and brightness tables in Config do not enter the JSON — they are charting
input rather than result, and echoing them back would break the field contract with JS iztro.