Why Two BaZi Calculators Disagree About Your Chart

12 min read
Hiroshi Kagawa
chinese-astrologyBaZiFour PillarsDay Boundary

One birth moment, three different BaZi charts. See what the day boundary, year boundary and hour clock conventions move, and how to pin the one you want.

TL;DR

  • Two BaZi calculators disagree because the Four Pillars have three unsettled conventions, not because one of them is broken.
  • A birth at 23:30 on 1990-06-15 in Shanghai returns 辛亥 day and 庚子 hour, 辛亥 day and 戊子 hour, or 壬子 day and 庚子 hour, depending on the day boundary school alone.
  • Two of those readings hand you a different Day Master, which is the value every other judgement in the chart is measured against.
  • RoxyAPI types all three switches as request parameters and echoes the applied set back in a conventions object, so a chart is reproducible instead of a black box.

Somebody sends you a BaZi chart their teacher drew, you run the same birth data through your own code, and the day pillar comes back different. Nothing is broken. The Four Pillars of Destiny are a calendar system with three genuinely open conventions inside it, and a calculator that does not tell you which one it applied is asking you to guess. This post walks the one that moves the most, the day boundary, using a birth moment where all three schools separate cleanly, then shows how far a single convention travels into the finished reading, and finishes on how to pin every convention so a chart can be reproduced by anyone holding the same birth data.

Why do two BaZi calculators disagree about the same birth data?

Because casting the pillars is not one algorithm, it is one algorithm plus three unsettled choices, and different lineages resolve them differently. The three are: which instant starts the sexagenary day, which instant starts the sexagenary year, and which clock the hour branch is read from. Each is a real practice question with real schools behind it. None of them is a rounding error, and none of them has a settled answer.

1 hour

Births between 23:00 and 23:59 are the only ones where the three day boundary schools return different pillars. A 14:30 birth and a 00:30 birth on the same dates return identical pillars under all three. Method notes: RoxyAPI methodology.

The day boundary is the sharpest of the three because its blast radius is disproportionate to its window. It touches one hour in twenty four, and inside that hour it can move the day pillar, and the day pillar stem is the Day Master, which is the reference point the whole reading is built on. A calculator that resolves that choice for you without saying so is the reason the two charts on your desk do not match.

Ready to build this? Chinese Astrology API gives you the Four Pillars with every convention typed, defaulted and echoed back on the response. See pricing.

What does the day boundary switch actually move?

It moves the day pillar, the hour pillar, or both, for a birth in the late zi hour. Take 15 June 1990 at 23:30 in Shanghai. The year pillar is 庚午 and the month pillar is 壬午 under every school, because those turn on solar term instants and no boundary convention touches them. The bottom half of the chart is where the three answers appear:

dayBoundaryDay pillarHour pillarWhat the school says
split-zi (the default here)辛亥 xin-hai庚子 geng-ziThe day turns at 00:00, but the hour stem is taken from the day that is about to begin
midnight辛亥 xin-hai戊子 wu-ziThe day turns at 00:00 and 23:00 to 23:59 is the late zi hour of the day that is ending, so the hour stem comes from that day
early-zi壬子 ren-zi庚子 geng-ziThe whole day turns at 23:00, so the birth already belongs to the sixteenth

The hour stem is not chosen independently. It is derived from the governing day stem by the Five Rats rule, under which the ten day stems fold into five starting points: the pairs 甲/己, 乙/庚, 丙/辛, 丁/壬 and 戊/癸 each begin their zi hour on the same stem. A 辛 day starts on 戊子, a 壬 day starts on 庚子. That is why midnight returns 戊子 while both other schools return 庚子, and it is arithmetic you can check by hand.

How far does one convention travel into the reading?

All the way to the verdict. Because the day pillar stem is the Day Master, split-zi and early-zi do not just print two different characters, they hand a practitioner two different subjects. Everything downstream is measured against that subject, so the element balance, the strength verdict and the branch interactions all move with it.

Same birth moment, one parameter changed, taken from live responses:

Readingsplit-zimidnightearly-zi
Day Master辛 Metal, yin辛 Metal, yin壬 Water, yang
Strength verdictbalanced, score -0.6balanced, score -0.6very-strong, score 4.1
favorableElementsemptyemptyWood, Fire, Earth
Wood / Fire / Earth / Metal / Water0 / 2 / 0 / 3 / 30 / 2 / 1 / 2 / 30 / 2 / 0 / 2 / 4
Branch interactions found335

Read the Metal row across. Metal is excess at three under the first school, balanced at two under the other two, and the elements a reading would recommend flip from an empty list to Wood, Fire and Earth. Two extra clashes appear under early-zi because the day branch becomes 子, which clashes the 午 sitting in both the year and the month. One switch, a different chart, a different prescription.

This is the reason a support ticket that says "your chart is wrong" is usually a convention mismatch rather than a defect. Before debugging arithmetic, compare the conventions the two systems applied. If the other system does not publish them, that comparison is not available and the disagreement cannot be resolved.

Which clock does the hour branch read from?

Civil time by default, and that is a convention too. The hour branch covers two clock hours, so it depends on which clock you read. clock takes the time exactly as a birth certificate records it. local-mean shifts to the mean sun over the birth longitude, worth up to 59 minutes at the edge of a wide time zone. solar adds the equation of time on top, worth up to a further 16 minutes.

The gap is largest where a birth place sits a long way west of the meridian its civil time zone is centred on. Send longitude 87.6 east on a UTC plus 8 clock and the same 23:30 birth moves two branches:

hourClockHour pillarBranch
clock庚子 geng-zi子, the rat hour
local-mean戊戌 wu-xu戌, the dog hour
solar戊戌 wu-xu戌, the dog hour

Note what that does to the previous section: once the hour branch is no longer 子, the birth is no longer in the late zi hour at all, so the day boundary question stops applying. The three switches are not independent, which is the argument for stating all three rather than the one you happen to care about.

local-mean and solar both need longitude in the request and return a 400 without it. The error names the field and the fix rather than failing silently, which matters because a silent fallback to civil time is indistinguishable from a correct answer.

How to reproduce a BaZi chart you did not cast

Send the conventions, then read them back off the response. Every birth-data call starts with a place lookup, because the timezone that resolves the birth moment has to be the historically correct one for that date rather than the offset in force today.

curl -s "https://roxyapi.com/api/v2/location/search?q=Shanghai&limit=1" \
  -H "X-API-Key: YOUR_KEY"
# {"total":97,"limit":1,"offset":0,"cities":[{"city":"Shanghai","province":"Shanghai",
#  "country":"China","iso2":"CN","latitude":31.2222,"longitude":121.4581,
#  "timezone":"Asia/Shanghai","utcOffset":8,"population":24874500}]}

Feed timezone straight into POST /chinese-astrology/bazi/chart and name the conventions you want:

curl -s -X POST https://roxyapi.com/api/v2/chinese-astrology/bazi/chart \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "date": "1990-06-15",
    "time": "23:30:00",
    "timezone": "Asia/Shanghai",
    "dayBoundary": "midnight"
  }'

Every response carries the set that was actually applied, including the defaults you did not send:

{
  "conventions": {
    "dayBoundary": "midnight",
    "yearBoundary": "li-chun",
    "hourClock": "clock"
  }
}

The third field is the year boundary, the switch that decides whether a late-January or early-February birth belongs to the outgoing animal or the incoming one. It is typed and echoed exactly like the other two, and it deserves its own walkthrough rather than a footnote here.

The identifier fields stay English in every language

conventions.dayBoundary returns split-zi under ?lang=zh-Hans exactly as it does under ?lang=en, and so does every identifier in the payload. Machine values are canonical English; the reader-facing copy arrives as a sibling field beside it. On the day pillar of the chart above:

Field?lang=en?lang=es?lang=zh-Hans
branch.idhaihaihai
branch.animalpigpigpig
branch.animalLocalizedabsentCerdo
branch.elementLocalizedabsentAgua

Switch your code on animal, render animalLocalized. The sibling is absent in English on purpose, so an English caller gets the same payload it always did, and animalLocalized ?? animal is the whole rendering rule. Chinese astrology and feng shui are the two domains carrying Simplified and Traditional Chinese today, which is worth saying plainly rather than implying the whole catalogue is translated into both scripts. The same reproducibility problem in a different tradition is worked through in why two kundlis disagree.

FAQ

Why do BaZi calculators give different results for the same birth time?

Because the Four Pillars carry three unsettled conventions: the day boundary, the year boundary and the hour clock. Two calculators applying different conventions produce different pillars from identical input, and neither is doing the arithmetic wrong. RoxyAPI types all three as request parameters and returns the applied set in a conventions object on every BaZi response.

Which BaZi day boundary is correct, 23:00 or midnight?

Both are practised, and the choice belongs to the lineage a reading sits in rather than to the software. Turning the whole day at 23:00 is standard across Hong Kong, Taiwan and much of South East Asia, while turning it at 00:00 is the position recorded in the Ming compendium San Ming Tong Hui (三命通會). RoxyAPI defaults to the split reading that most software implements and lets you send dayBoundary explicitly to get either of the others.

Does the day boundary change my Day Master?

It can, for a birth between 23:00 and 23:59. In the worked example above, one convention returns a 辛 Metal Day Master and another returns a 壬 Water Day Master from the same birth moment, which changes the strength verdict and the favourable elements that follow from it. Outside that hour all three conventions return the same day pillar.

Is there a BaZi API that returns the Four Pillars as JSON?

Yes. POST /chinese-astrology/bazi/chart returns the four pillars with every Heavenly Stem and Earthly Branch, the hidden stems, the Ten God relations, the Na Yin element, the five-element balance and the branch interactions in one call, with the applied conventions echoed back. It is part of 209+ endpoints across 14+ insight domains on one RoxyAPI key.

How do I make a BaZi chart reproducible across two systems?

Record the conventions alongside the birth data, and pass them explicitly on every call rather than relying on a default. A chart that stores date, time, timezone, dayBoundary, yearBoundary and hourClock can be recast identically by anyone holding those six values. A chart that stores only the birth moment cannot, because the missing three are exactly the fields the two systems disagree on.

Conclusion

A BaZi chart is only reproducible if the conventions travel with it. The three switches are real practice questions with real lineages behind them, so the honest engineering answer is not to pick a winner but to make the choice explicit, defaulted and visible on the response. Build it on the Chinese Astrology API and every chart you ship can be recast, argued with, and reconciled against the one a practitioner drew by hand.