<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hyunbin Kim</title>
    <description>The latest articles on DEV Community by Hyunbin Kim (@beachcombers).</description>
    <link>https://dev.to/beachcombers</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4094013%2F2b82e6af-19d7-4040-84fe-3722caa4aed3.jpg</url>
      <title>DEV Community: Hyunbin Kim</title>
      <link>https://dev.to/beachcombers</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/beachcombers"/>
    <language>en</language>
    <item>
      <title>Why every BaZi calculator disagrees with the almanac</title>
      <dc:creator>Hyunbin Kim</dc:creator>
      <pubDate>Tue, 25 Aug 2026 12:02:44 +0000</pubDate>
      <link>https://dev.to/beachcombers/why-every-bazi-calculator-disagrees-with-the-almanac-19nf</link>
      <guid>https://dev.to/beachcombers/why-every-bazi-calculator-disagrees-with-the-almanac-19nf</guid>
      <description>&lt;p&gt;Every Four Pillars calculator — saju in Korea, BaZi in China — agrees on the easy 95% of the job. Feed it a birth date and it maps that instant onto a traditional calendar: four pillars, each a heavenly stem paired with an earthly branch.&lt;/p&gt;

&lt;p&gt;The remaining 5% is boundaries. And at the boundaries, nearly all of them quietly disagree with the printed almanac they claim to reproduce.&lt;/p&gt;

&lt;p&gt;I maintain a saju reading service, and getting these four cases right was most of the actual engineering. Here they are, with the failing inputs.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. A solar term is an instant, not a date
&lt;/h2&gt;

&lt;p&gt;The year pillar does not turn on January 1, and not on lunar new year either. It turns at 입춘 (ipchun, "start of spring") — one of the 24 solar terms, defined by the sun's apparent longitude. In 2024 that moment was &lt;strong&gt;February 4, 16:27 KST&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A calculator that applies solar terms at &lt;em&gt;day&lt;/em&gt; granularity says "February 4 → new year pillar" and hands the wrong year to everyone born that morning.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx k-saju 2024-02-04 04:00
&lt;span class="c"&gt;# year 癸卯 — still the old year pillar, because 04:00 &amp;lt; 16:27&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fix is unglamorous: store term boundaries as instants and compare instants. The subtlety is that this correction applies to the &lt;strong&gt;year and month&lt;/strong&gt; pillars only — the day pillar runs on its own sexagenary count and must not be touched.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The 23:00 hour belongs to two days at once
&lt;/h2&gt;

&lt;p&gt;Traditional practice starts the day at 23:00, not midnight — the hour of the Rat (자시). So for a birth at 23:31, there are two defensible answers about which day's stem the hour pillar derives from, and schools split on it.&lt;/p&gt;

&lt;p&gt;The convention this engine declares: the &lt;strong&gt;day pillar keeps clock midnight&lt;/strong&gt;, while the &lt;strong&gt;hour stem takes the next day's stem&lt;/strong&gt; (the 야자시 rule).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx k-saju 2000-05-15 23:31
&lt;span class="c"&gt;# day 癸酉, hour 甲子&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am not claiming this is the One True Rule. I am claiming it should be written down. Most tools pick a side in silence, which is how two calculators give one person two charts and neither can explain why.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The clock is not the sun
&lt;/h2&gt;

&lt;p&gt;Korea keeps time on the 135°E meridian. Seoul sits near 127°E. That is about &lt;strong&gt;32 minutes&lt;/strong&gt; of difference between civil noon and solar noon — before you add the equation of time, which swings solar noon by up to ~16 minutes across the year.&lt;/p&gt;

&lt;p&gt;Hour pillars are two-hour buckets. A half-hour error puts a birth in the wrong bucket often enough to matter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx k-saju 2000-05-05 09:30 &lt;span class="nt"&gt;--lon&lt;/span&gt; 124.7   &lt;span class="c"&gt;# hour 丙辰&lt;/span&gt;
npx k-saju 2000-05-05 09:30               &lt;span class="c"&gt;# hour 丁巳  (Seoul default)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same wall clock, different hour pillar, purely from longitude.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Foreign births need absolute time
&lt;/h2&gt;

&lt;p&gt;This one bites hardest. A solar term is an astronomical instant, global. If someone is born in New York on February 3 at 16:00, that is already February 4 in Korea — and possibly already past the term.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx k-saju 2024-02-03 16:00 &lt;span class="nt"&gt;--place&lt;/span&gt; new-york
&lt;span class="c"&gt;# year 甲辰 — the new year pillar, on a local date of "Feb 3"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare local &lt;em&gt;dates&lt;/em&gt; against KST term &lt;em&gt;dates&lt;/em&gt; and you get this backwards. Convert both to absolute time and compare instants, and it falls out correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing claims instead of asserting them
&lt;/h2&gt;

&lt;p&gt;All four examples above are golden tests. The README table's example commands &lt;em&gt;are&lt;/em&gt; the test inputs, so a claim that drifts from the code fails CI rather than sitting there being wrong.&lt;/p&gt;

&lt;p&gt;That matters more than usual in this domain, because "accuracy" claims here normally hide two things: which school's conventions were chosen, and where the dataset runs out. Mine, stated openly: minute-exact term instants cover 2020–2030 (dataset range) and degrade to day granularity outside it; luck-pillar start ages use day-granular boundaries and can differ from a paper almanac by ±1 year.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is deliberately missing
&lt;/h2&gt;

&lt;p&gt;Interpretation. The library turns a birth instant into symbolic coordinates and stops.&lt;/p&gt;

&lt;p&gt;I think that split is the honest one. The calendar math is verifiable — you can check it against an almanac and I can hand you a test suite. What those eight characters &lt;em&gt;mean&lt;/em&gt; is not verifiable, and blending the two is how this whole genre earned its reputation. (My commercial product does write readings, with an LLM that is structurally forbidden from touching a number.)&lt;/p&gt;

&lt;p&gt;The engine is MIT: &lt;strong&gt;&lt;a href="https://github.com/bunhine0452/k-saju" rel="noopener noreferrer"&gt;https://github.com/bunhine0452/k-saju&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx k-saju 1995-03-16 07:30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have ever tried to reconcile two calculators at 2 a.m., issue #1 — extending minute-exact solar terms to 1900–2050 astronomically — is open and genuinely fun.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>opensource</category>
      <category>javascript</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
