<?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: MINGXUAN LOU</title>
    <description>The latest articles on DEV Community by MINGXUAN LOU (@lmxjw3).</description>
    <link>https://dev.to/lmxjw3</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%2F4201413%2F08a88523-0784-4ace-8d41-60e1de00e67e.jpg</url>
      <title>DEV Community: MINGXUAN LOU</title>
      <link>https://dev.to/lmxjw3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lmxjw3"/>
    <language>en</language>
    <item>
      <title>Why Do BaZi Calculators Give Different Results for the Same Birth Date?</title>
      <dc:creator>MINGXUAN LOU</dc:creator>
      <pubDate>Sat, 24 Oct 2026 02:31:00 +0000</pubDate>
      <link>https://dev.to/lmxjw3/why-do-bazi-calculators-give-different-results-for-the-same-birth-date-bbf</link>
      <guid>https://dev.to/lmxjw3/why-do-bazi-calculators-give-different-results-for-the-same-birth-date-bbf</guid>
      <description>&lt;p&gt;&lt;em&gt;The surprising complexity of time zones, solar terms, and building a reliable Chinese astrology calculator.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You enter the same birth date into two different websites.&lt;/p&gt;

&lt;p&gt;Same date. Same time. Same city.&lt;/p&gt;

&lt;p&gt;But somehow, you get two different BaZi charts.&lt;/p&gt;

&lt;p&gt;Which one is correct?&lt;/p&gt;

&lt;p&gt;This is one of the most interesting problems I've encountered while working on Mingora, a Chinese astrology web app I've been building.&lt;/p&gt;

&lt;p&gt;At first glance, calculating a BaZi chart seems straightforward: take someone's birth date and time, apply a set of traditional calendar rules, and generate four pairs of Chinese characters.&lt;/p&gt;

&lt;p&gt;But once you start implementing those rules in software, things get surprisingly complicated.&lt;/p&gt;

&lt;p&gt;And most of the complexity comes from something developers already know can be painful: &lt;strong&gt;working with dates and times.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Quick Introduction to BaZi
&lt;/h2&gt;

&lt;p&gt;BaZi (八字), also known as the Four Pillars of Destiny, is a traditional Chinese astrology system.&lt;/p&gt;

&lt;p&gt;It represents a person's birth information using four pillars:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Year Pillar&lt;/strong&gt; — based on the year of birth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Month Pillar&lt;/strong&gt; — based on the solar-term month&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day Pillar&lt;/strong&gt; — based on the day of birth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hour Pillar&lt;/strong&gt; — based on a traditional two-hour period&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each pillar contains a Heavenly Stem and an Earthly Branch, producing eight Chinese characters in total.&lt;/p&gt;

&lt;p&gt;The underlying calendar calculations are deterministic, although different traditional conventions can produce different results.&lt;/p&gt;

&lt;p&gt;The challenge is making sure the software interprets the birth information correctly.&lt;/p&gt;

&lt;p&gt;Here are four reasons two calculators might disagree.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Time Zones Are More Complicated Than They Look
&lt;/h2&gt;

&lt;p&gt;Imagine someone was born at 11:30 PM in New York.&lt;/p&gt;

&lt;p&gt;A naive implementation might take the date and time, create a JavaScript &lt;code&gt;Date&lt;/code&gt; object, and start calculating.&lt;/p&gt;

&lt;p&gt;But what does 11:30 PM actually mean?&lt;/p&gt;

&lt;p&gt;Was daylight saving time active on that date?&lt;/p&gt;

&lt;p&gt;What was the historical UTC offset?&lt;/p&gt;

&lt;p&gt;Was the birth time entered in the user's current time zone or the birthplace's time zone?&lt;/p&gt;

&lt;p&gt;JavaScript timestamps represent an instant in time, but the original local birth date and its geographical context are equally important.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;birthDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1995-06-15T23:30:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This looks harmless.&lt;/p&gt;

&lt;p&gt;But the string has no explicit time zone. JavaScript interprets it as local time in the environment where the code runs.&lt;/p&gt;

&lt;p&gt;Run the same code in environments with different time zones, and you can get different timestamps.&lt;/p&gt;

&lt;p&gt;A more reliable approach is to keep the birthplace, local birth time, and time zone information together before performing calendar calculations.&lt;/p&gt;

&lt;p&gt;This is especially important for people born near midnight.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The Chinese Astrological Year Doesn't Start on January 1
&lt;/h2&gt;

&lt;p&gt;Here's another unexpected detail.&lt;/p&gt;

&lt;p&gt;In many BaZi calculation conventions, the year changes at &lt;strong&gt;Li Chun (立春)&lt;/strong&gt;, the Beginning of Spring, rather than on January 1 or Lunar New Year.&lt;/p&gt;

&lt;p&gt;Li Chun typically occurs around February 4, although the exact astronomical moment varies.&lt;/p&gt;

&lt;p&gt;So someone born in early February may belong to the previous BaZi year, even when their Gregorian birth year has already changed.&lt;/p&gt;

&lt;p&gt;The same principle applies to the Month Pillar.&lt;/p&gt;

&lt;p&gt;BaZi months are traditionally determined using solar-term boundaries rather than simply matching January to the first month, February to the second, and so on.&lt;/p&gt;

&lt;p&gt;This means a correct implementation needs to know when particular solar terms occur.&lt;/p&gt;

&lt;p&gt;It isn't enough to write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;month&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;birthDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMonth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Gregorian month number and the BaZi month branch are not interchangeable.&lt;/p&gt;

&lt;p&gt;For developers, this is a good example of why calendar systems should be modeled explicitly rather than treated as formatting variations of the same date.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Clock Time Isn't Always Solar Time
&lt;/h2&gt;

&lt;p&gt;This was one of the more fascinating parts of the project for me.&lt;/p&gt;

&lt;p&gt;Modern time zones standardize clock time across large geographical areas.&lt;/p&gt;

&lt;p&gt;But the Sun doesn't follow those administrative boundaries.&lt;/p&gt;

&lt;p&gt;Two cities in the same time zone can experience solar noon at noticeably different clock times.&lt;/p&gt;

&lt;p&gt;Consider China.&lt;/p&gt;

&lt;p&gt;The entire country officially uses UTC+8, even though it spans a huge range of longitudes.&lt;/p&gt;

&lt;p&gt;Beijing is located near 116.4°E, while the standard meridian for UTC+8 is 120°E.&lt;/p&gt;

&lt;p&gt;Since Earth rotates approximately 15 degrees per hour, every degree of longitude corresponds to roughly four minutes of solar time.&lt;/p&gt;

&lt;p&gt;A simplified longitude correction looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getLongitudeCorrection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;utcOffsetHours&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;standardMeridian&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;utcOffsetHours&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;longitude&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;standardMeridian&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is the correction in minutes.&lt;/p&gt;

&lt;p&gt;For Beijing, the longitude component is approximately -14.4 minutes.&lt;/p&gt;

&lt;p&gt;However, that is only part of the story.&lt;/p&gt;

&lt;p&gt;Calculating &lt;strong&gt;true solar time&lt;/strong&gt;, also called local apparent solar time, requires an additional adjustment known as the &lt;em&gt;Equation of Time&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It accounts for the difference between mean solar time and apparent solar time throughout the year.&lt;/p&gt;

&lt;p&gt;Depending on the BaZi convention being used, these adjustments can affect the Hour Pillar, especially when a birth happens close to a two-hour boundary.&lt;/p&gt;

&lt;p&gt;And that's how two calculators can produce different charts even when both appear to accept exactly the same input.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Different Traditional Conventions Exist
&lt;/h2&gt;

&lt;p&gt;Not every disagreement is a programming bug.&lt;/p&gt;

&lt;p&gt;Some differences come from the rules a calculator chooses to follow.&lt;/p&gt;

&lt;p&gt;One particularly interesting example is &lt;strong&gt;Zi Hour (子时)&lt;/strong&gt;, which traditionally spans 11:00 PM to 1:00 AM.&lt;/p&gt;

&lt;p&gt;Some calculation conventions treat 11:00 PM as the beginning of the next astrological day.&lt;/p&gt;

&lt;p&gt;Others distinguish between early and late Zi Hour and handle the Day Pillar differently.&lt;/p&gt;

&lt;p&gt;Consider someone born at 11:30 PM.&lt;/p&gt;

&lt;p&gt;Two implementations using different day-boundary conventions may calculate different Day Pillars.&lt;/p&gt;

&lt;p&gt;Neither result necessarily indicates that the developer made a mistake.&lt;/p&gt;

&lt;p&gt;The important thing is to make these conventions explicit, document them, and apply them consistently.&lt;/p&gt;

&lt;p&gt;From a software engineering perspective, that means calculation rules should be testable and reproducible.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned Building My Own Calculator
&lt;/h2&gt;

&lt;p&gt;While working on Mingora, I started to appreciate how much detail goes into turning a traditional calendar system into a modern web application.&lt;/p&gt;

&lt;p&gt;The interesting part wasn't just generating eight characters.&lt;/p&gt;

&lt;p&gt;It was dealing with the edge cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Births close to solar-term boundaries&lt;/li&gt;
&lt;li&gt;Historical time zones and daylight saving time&lt;/li&gt;
&lt;li&gt;Longitude-based time adjustments&lt;/li&gt;
&lt;li&gt;Birth times near midnight&lt;/li&gt;
&lt;li&gt;Different conventions for day and hour boundaries&lt;/li&gt;
&lt;li&gt;Missing or uncertain birth-time information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the kinds of problems that don't always show up in a simple demo, but become important when real people start using a tool.&lt;/p&gt;

&lt;p&gt;I eventually separated the underlying chart calculations from the interpretation layer and open-sourced the TypeScript calculation engine.&lt;/p&gt;

&lt;p&gt;If you're curious about how these rules work in practice, you can experiment with the &lt;a href="https://mingora.app/bazi-calculator" rel="noopener noreferrer"&gt;free BaZi calculator on Mingora&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It lets you enter a birth date, time, and city to explore the Four Pillars, Day Master, Five Elements, and time adjustments.&lt;/p&gt;

&lt;p&gt;The calculation engine is also available on &lt;a href="https://github.com/mingora-app/bazi" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; for developers interested in the implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Working with dates and times is already difficult in ordinary applications.&lt;/p&gt;

&lt;p&gt;Add historical time zones, astronomical events, geographical coordinates, and centuries-old calendar conventions, and the problem becomes much more interesting.&lt;/p&gt;

&lt;p&gt;My biggest takeaway is that &lt;strong&gt;a reliable calculator isn't just about implementing formulas correctly. It's about defining your assumptions clearly and handling boundary conditions consistently.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That lesson applies far beyond Chinese astrology.&lt;/p&gt;

&lt;p&gt;Whether you're building scheduling software, financial systems, astronomical tools, or anything involving international dates, the smallest time-related assumptions can sometimes produce the biggest differences.&lt;/p&gt;

&lt;p&gt;And that's exactly what makes these problems worth solving.&lt;/p&gt;

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