Astrolabe object

The fields of Astrolabe, its lookup methods, and the surrounded-palace predicates.

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
nameKeyOrNamestringYesA palace-name key, "bodyPalace", "originalPalace", or a translated palace name
indexintYesPalace 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
keyOrNamestringYesA 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
nameKeyOrNamestringYesA palace-name key or a translated name
stars...stringYesStar 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.


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
targetDatestringYesTarget solar date in YYYY-M-D
targetTimeIndexuint8YesTarget 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 ---

For pattern text see PatternsToText on Patterns.


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