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) *Palace

Parameters

ParameterTypeRequiredDefaultDescription
nameKeyOrNamestringYes—A palace-name key, "bodyPalace", "originalPalace", or a translated palace name
indexintYes—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: wealth

Edge 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

ParameterTypeRequiredDefaultDescription
keyOrNamestringYes—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) *SurroundedPalaces

Return 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: true

IsSurrounded / 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) bool

Parameters

ParameterTypeRequiredDefaultDescription
nameKeyOrNamestringYes—A palace-name key or a translated name
stars...stringYes—Star keys, variadic

Return value

MethodMeaning
IsSurroundedEvery listed star is in the surrounded set
IsSurroundedOneOfAt least one listed star is in the surrounded set
NotSurroundedNone 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
true

The 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

ParameterTypeRequiredDefaultDescription
targetPalaceTargetYes—A non-empty Key addresses by palace-name key (PalaceBody / PalaceOriginal also accepted); otherwise Index is used

Return value *FlankingPalaces, with two *Palace fields:

FieldOffsetDescription
Previous-1The preceding palace
Next+1The 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:

MethodMeaning
Have(stars ...string) boolThe two palaces together hold every star in the list
NotHave(stars ...string) boolNeither palace holds any of them
HaveOneOf(stars ...string) boolThe two together hold at least one
HaveMutagen(mutagenKey string) boolEither palace carries that natal mutagen
NotHaveMutagen(mutagenKey string) boolNeither 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 true

The 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

ParameterTypeRequiredDefaultDescription
targetDatestringYes—Target solar date in YYYY-M-D
targetTimeIndexuint8Yes—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  yisi

ToText / 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-12

The 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

ParameterTypeDescription
targetPalaceTargetAs for PalaceToText
optsTextOptionsOutput 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
soulPalace

The 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.

On this page