How accurate are BaZi calculators? Ten Chinese calendar libraries vs NASA JPL
Updated October 21, 2026
Two free BaZi calculators can give the same birth two different charts. Usually one of them is not broken: they disagree about a boundary. Before building our own calculator we wanted to know which boundaries, by how much, and which answer the sky supports, so we tested the libraries most calculators are built on against an astronomical ephemeris. This page publishes the results.
The method
The year and month pillars change at the twelve 節 (jie) solar terms, the moments the sun reaches a multiple of 15° of longitude starting from 315° for 立春, the Start of Spring. That is an astronomical event with a single correct instant, so it can be checked.
- Truth: apparent solar longitude from skyfield 1.55 with NASA JPL's DE421 ephemeris, found by bisection to the second.
- Independent libraries: astronomy-engine 2.1.19, ephem 4.2.1, sxtwl 2.0.7 (壽星), cnlunar 0.2.5, lunisolar 2.6.0 and k-saju 0.1.4.
- The 壽星 family: lunar-javascript 1.7.7 (6tail), plus tyme4ts, lunaris and lunar_python, which share its algorithm and so are not independent checks of it.
All times below are Beijing time (UTC+8), the convention Chinese almanacs use.
Start of Spring, to the second
| Year | JPL DE421 | lunar-javascript | sxtwl | astronomy-engine | ephem |
|---|---|---|---|---|---|
| 1976 | 02-05 00:39:26 | 00:39:28 | 00:39:27 | 00:39:11 | 00:39:22 |
| 1984 | 02-04 23:18:44 | 23:18:44 | 23:18:44 | 23:18:42 | 23:18:38 |
| 1990 | 02-04 10:13:59 | 10:14:00 | 10:14:00 | 10:13:58 | 10:13:55 |
| 2000 | 02-04 20:40:22 | 20:40:24 | 20:40:24 | 20:40:18 | 20:40:13 |
| 2024 | 02-04 16:27:07 | 16:27:07 | 16:26:53 | 16:26:49 | 16:26:56 |
| 2027 | 02-04 09:46:18 | 09:46:18 | 09:45:59 | 09:46:24 | 09:46:02 |
lunar-javascript was within 2 seconds of DE421 on every one of the ten terms we tested. Its correction for the slowing of the Earth's rotation (ΔT) for 2024 is 69.17 s, against the 69.18 s published by the IERS. The others drift by up to about 20 seconds, mostly because they estimate ΔT differently: astronomy-engine uses 73.9 s for 2024, which puts its Start of Spring about 18 seconds early.
Twenty seconds sounds harmless, and for almost everyone it is. It matters only for a birth inside that window, and then it decides the year pillar and the zodiac animal.
Where the pillars actually disagree
Seconds are rarely the problem. When we compared full four-pillar charts, every disagreement came from one of three sources.
| Birth (Beijing time) | Pillars from DE421 | Who disagrees, and why |
|---|---|---|
| 2000-01-01 00:30 | 己卯 丙子 戊午 壬子 | nobody |
| 1990-02-04 10:00 | 己巳 丁丑 庚子 辛巳 | sxtwl, cnlunar and lunisolar give 庚午 戊寅: they switch the year on the day of the Start of Spring, not at its instant (10:13:59) |
| 1984-02-04 23:30 | 甲子 丙寅 己巳 甲子 | the "same day" late-Zi rule keeps the day pillar 戊辰 |
| 2027-02-04 09:40 | 丙午 辛丑 甲寅 己巳 | day-level libraries give 丁未 壬寅, six minutes before the true instant |
| 2024-02-04 16:27:00 | 癸卯 乙丑 戊戌 庚申 | k-saju and astronomy-engine give 甲辰: their Start of Spring is about 18 s early |
1. The solar term is treated as a day, not an instant
Several libraries switch the year and month on the calendar day of a 節 term. Anyone born earlier that day, before the actual moment, gets the next year's or month's pillar. Twelve term-days a year each carry this risk, so it is by far the most common source of a wrong chart. Hours count here, not seconds.
2. The late Zi hour (23:00–24:00)
Tradition is genuinely split on whether a birth between 23:00 and midnight belongs to the next day (子初換日) or keeps its calendar day and takes a "late Zi" hour (早晚子時). Neither is a bug, but a calculator should say which it uses. lunar-javascript defaults to keeping the day; libraries differ.
3. Seconds of ΔT
The rarest case: a birth within about twenty seconds of a term. Only an ephemeris-grade ΔT settles it.
Beyond BaZi: Zi Wei Dou Shu and the Six Lines
The same approach turned up problems in the other systems.
- Zi Wei Dou Shu. iztro 2.6.2, the most complete open-source Zi Wei library, matched two independent libraries (fortel-ziweidoushu and ziwei-lite) on the Life and Body palaces, the element bureau and all fourteen main stars across 1,800 charts, and its calendar agreed with lunar-javascript on all 73,384 days from 1900 to 2100. But for a late-Zi birth at the end of a lunar month it advances the day without the month: 22 of the 24 such charts we tried were wrong (1996-08-13 23:xx is one). A calculator built on it should avoid that input path.
- Six Lines (納甲六爻). We swept nine npm packages through 1,920 cases (64 hexagrams × 10 day stems × 3 moving-line patterns) against a reference built only from the classical tables. Three matched every case structurally, though one computed its own solar terms 5 minutes early to 7 minutes late. Two more offered only partial data; the rest put a hexagram in the wrong palace, misnamed one, switched terms by the day, or called a paid remote API. None chose the 用神 (use spirit) by question category.
What this means if you use a calculator
- Born within a day of a 節 term? That is the first week of most Western months; see the 24 solar terms. Check that your calculator uses the exact instant. Enter the birth an hour either side of the term: the year or month pillar should flip at the right minute, not at midnight.
- Born between 23:00 and midnight? Find out which late-Zi rule the calculator follows, and decide which school you follow.
- Born far from your time zone's meridian, or under daylight saving? The hour, and sometimes the day, depends on true solar time.
How TianEon handles it
Our BaZi calculator compares the birth instant with each 節 instant to the second, using lunar-javascript, whose terms matched DE421 throughout. The late-Zi rule is an explicit setting (next day by default, same day if you prefer), and the chart lists the true-solar-time corrections it applied. The Zi Wei wrapper never takes iztro's faulty late-Zi path, and our Six Lines engine is written in-house from the classical tables. In the test suite it is compared against two independent libraries on 10,240 and 7,680 generated cases, with no mismatches. The cases above are kept as regression tests, so a library upgrade that changes any of them fails the build.
The AI that writes our readings receives the finished chart and may not change it. The calendar is arithmetic; only the prose is written by a model.
Reusing these results
You are welcome to quote or link this page. If you maintain a calculator or library and want the full case list, or think we got a case wrong, write to us.