I built a free Korean astrology (Saju) calculator and wanted to share what makes the math interesting.
What's Saju?
Saju is the Korean tradition of Chinese 4-pillar astrology (BaZi). Your birth year, month, day, and hour each get encoded as a Heavenly Stem + Earthly Branch pair, giving you 8 characters that describe your "energetic signature."
The interesting parts
1. Solar terms via Meeus algorithm
The year boundary isn't January 1 — it's the solar term Ipchun (立春, ~Feb 4), the moment the sun reaches 315° ecliptic longitude. To compute this precisely, I implemented the Meeus astronomical algorithm:
def apparent_solar_longitude(jd):
t = (jd - 2451545.0) / 36525.0
l0 = (280.46646 + 36000.76983 * t + 0.0003032 * t * t) % 360
m = math.radians((357.52911 + 35999.05029 * t - 0.0001537 * t * t) % 360)
c = ((1.914602 - 0.004817 * t - 0.000014 * t * t) * math.sin(m)
+ (0.019993 - 0.000101 * t) * math.sin(2 * m)
+ 0.000289 * math.sin(3 * m))
return (l0 + c) % 360
Then Newton-style iteration to find the exact JD when longitude crosses 315°.
2. Late-Zi hour rule
The day pillar transitions at 23:00 local time, not midnight. If you're born between 23:00 and 24:00, your day pillar rolls forward to the next day. Common bug in online calculators.
3. Sixty-pillar cycle (六十甲子)
Ten Heavenly Stems × Twelve Earthly Branches, but they pair only on matching parity (Yang-Yang or Yin-Yin), so you get LCM(10, 12) / 2 = 30 paired combos × 2 polarities = 60 pillars.
def get_pillar_index(stem, branch):
for i in range(60):
if i % 10 == stem and i % 12 == branch:
return i
Try it
No signup, no email. Pure Python on Flask, hosted on PythonAnywhere free tier.
Open to feedback on the math or interpretation logic.
For further actions, you may consider blocking this person and/or reporting abuse
