JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 88
  • Score
    100M100P100Q87291F
  • License MIT

A fork of alvamind's comprehensive Bazi calculator for personal use

Package Exports

  • @aharris02/bazi-calculator-by-alvamind
  • @aharris02/bazi-calculator-by-alvamind/package.json

Readme

Bazi Calculator (TypeScript Port)

⚠️ This is a fork of the original bazi-calculator-by-alvamind and incorporates work from bazica by tommitoan, published by @aharris02 for compatibility with modern TypeScript builds and deployment environments (e.g. Vercel).

npm version License: MIT TypeScript Downloads

A modern, accurate, and comprehensive Bazi (八字 / Four Pillars of Destiny) calculator and analyzer with robust timezone handling and advanced features.

InstallationQuick StartDocumentationContributing

📢 Disclaimer

This package is provided for educational and research purposes only. The calculations and interpretations should not be used as the sole basis for making important life decisions. Chinese Metaphysics and Bazi analysis require professional expertise and years of study.

✨ Key Features

Core Calculations

  • Four Pillars (四柱) Calculation: Accurate Year, Month, Day, and Hour pillar determination
  • Timezone-Aware Processing: Requires IANA timezone strings (e.g., America/New_York, Asia/Shanghai)
  • Unknown Birth Time Handling: Gracefully calculates when exact birth time is unknown
  • Luck Pillars Calculation: Determines 10-year Luck Pillar sequence with direction and precise start age
  • Gender Normalization: Accepts various gender inputs but normalizes to 'male' or 'female, since Bazi is based on binary genders

Analysis Components

  • Five Elements (五行) Analysis: Element distribution with relationship weighting
  • Day Master (日主) Analysis: Stem, Element, Yin/Yang properties
  • Eight Mansions (八宅) Feng Shui: Life Gua calculation with favorable/unfavorable directions
  • Destiny Indicators: Nobleman (貴人), Intelligence Star (文昌), Sky Horse (天馬), Peach Blossom (桃花)

Technical Features

  • 🔒 Type-safe with TypeScript
  • 📦 ES Module Support
  • 🌐 Timezone-correct calculations via date-fns-tz
  • 📝 Comprehensive Type Definitions
  • ⚡ Optimized Performance

🚀 Installation

# Using npm
npm install @aharris02/bazi-calculator-by-alvamind date-fns date-fns-tz

# Using yarn
yarn add @aharris02/bazi-calculator-by-alvamind date-fns date-fns-tz

# Using pnpm
pnpm add @aharris02/bazi-calculator-by-alvamind date-fns date-fns-tz

Note: This library requires date-fns and date-fns-tz as peer dependencies for robust date and timezone handling.

🎯 Quick Start

import { BaziCalculator } from '@aharris02/bazi-calculator-by-alvamind';
import { toDate } from 'date-fns-tz'; // Essential for timezone-aware Date creation

// Define Birth Details
const dateString = '1990-05-10T12:30:00';
const timezone = 'Asia/Shanghai';
const gender = 'male';

// Create a timezone-aware Date object (IMPORTANT!)
const birthDate = toDate(dateString, { timeZone: timezone });

// Initialize calculator with modern constructor
const calculator = new BaziCalculator(
  birthDate,    // Date object (timezone-aware)
  gender,       // Gender ('male' or any other string -> 'female')
  timezone,     // IANA Timezone string
  true          // Is birth time known? (default: true)
);

// Get complete analysis
const analysis = calculator.getCompleteAnalysis();

// Display Chinese characters
console.log(calculator.toString()); // 庚午年辛巳月乙酉日壬午時

📖 Detailed Documentation

Birth Time Known Example

import { BaziCalculator } from '@aharris02/bazi-calculator-by-alvamind';
import { toDate, formatInTimeZone } from 'date-fns-tz';
import { isValid } from 'date-fns';

// 1. Define Birth Details
const year = 1995;
const month = 6; // 1-12
const day = 8;
const hour = 22; // 0-23
const minute = 5;
const gender = 'male'; // or 'female', 'nonbinary', 'other', etc.
const timeZone = 'Asia/Ho_Chi_Minh'; // IANA Timezone String is crucial!
const isTimeKnown = true; // Explicitly state time is known

// 2. Create a Timezone-Aware Date Object
// IMPORTANT: Use date-fns-tz's toDate for correct initial parsing
const dateString = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}T${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}:00`;
const birthDate = toDate(dateString, { timeZone });

if (!isValid(birthDate)) {
  console.error("Invalid Date constructed. Check inputs and timezone.");
  // Handle error appropriately
} else {
    // 3. Instantiate the Calculator
    // Gender normalizes internally: non-'male' inputs become 'female' for calculations
    const calculator = new BaziCalculator(birthDate, gender, timeZone, isTimeKnown);

    // 4. Get the Complete Analysis
    const analysis = calculator.getCompleteAnalysis();

    if (analysis) {
        console.log("--- Four Pillars (Simple) ---");
        console.log(analysis.mainPillars);
        // Example: { year: {...}, month: {...}, day: {...}, time: {...} }

        console.log("\n--- Luck Pillars Summary ---");
        if (analysis.luckPillars) {
            console.log(`Direction: ${analysis.luckPillars.incrementRule === 1 ? 'Forward' : 'Backward'}`);
            console.log(`Timing Known: ${analysis.luckPillars.isTimingKnown}`);
            console.log(`Start Age: ${analysis.luckPillars.startAgeYears}y ${analysis.luckPillars.startAgeMonths}m ${analysis.luckPillars.startAgeDays}d`);
        }

        console.log("\n--- Basic Analysis ---");
        console.log(analysis.basicAnalysis);

        console.log("\n--- Chart String ---");
        console.log(calculator.toString()); // Output: 乙亥年 壬午月 庚午日 丁亥時
    }
}

Unknown Birth Time Example

import { BaziCalculator } from '@aharris02/bazi-calculator-by-alvamind';
import { toDate } from 'date-fns-tz';
import { isValid } from 'date-fns';

const year = 1995;
const month = 6;
const day = 8;
const hour = 12; // Placeholder Hour (e.g., noon)
const minute = 0; // Placeholder Minute
const gender = 'male';
const timeZone = 'Asia/Ho_Chi_Minh';
const isTimeKnown = false; // <<< Indicate time is unknown

const dateString = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}T${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}:00`;
const birthDate = toDate(dateString, { timeZone });

if (isValid(birthDate)) {
    const calculator = new BaziCalculator(birthDate, gender, timeZone, isTimeKnown);
    const analysis = calculator.getCompleteAnalysis();

    if (analysis) {
        console.log("--- Analysis (Unknown Time) ---");

        console.log("Pillars:", analysis.mainPillars);
        // Output will have time: null

        console.log("Pillars String:", calculator.toString());
        // Output: 乙亥年 壬午月 庚午日 ??時

        console.log("Luck Pillars Timing Known:", analysis.luckPillars?.isTimingKnown);
        // Output: false

        console.log("Luck Pillars Start Age:", analysis.luckPillars?.startAgeYears);
        // Output: null

        console.log("Five Factors:", analysis.basicAnalysis?.fiveFactors);
        // Output: May be less accurate or null if calculation requires hour
    }
}

API Reference

BaziCalculator Class

class BaziCalculator {
  constructor(
    birthDateTime: Date,     // Timezone-aware Date object
    genderInput?: string,    // 'male', 'female', or any other (defaults to 'male')
    timezoneInput?: string,  // IANA timezone string (defaults to 'UTC')
    isTimeKnownInput?: boolean // Whether the exact hour/minute are known (defaults to true)
  )

  // Main methods
  calculatePillars(): Pillars | null
  calculateLuckPillars(): LuckPillarsResult | null
  calculateBasicAnalysis(): BasicAnalysis | null
  getCompleteAnalysis(): CompleteAnalysis | null
  toString(): string
}

Data Files

This library relies on internal JSON data for calculations:

  • lunar-new-year.json: Used for determining the Lunar Year for the Year Pillar.
  • solar-term.json: Used for determining the Month Branch and Luck Pillar timing.

These files are bundled with the library.

📝 Important Notes

Calculation Methods

  • Timezone-aware calculations using IANA timezone strings
  • Traditional Chinese time system (12 two-hour periods)
  • Standard Stem-Branch (干支) system
  • Eight Mansions Feng Shui principles
  • Support for unknown birth time calculations

Limitations

  • Luck Pillar Start Time precision depends on solar term data
  • Currently does not include 10 Gods (十神), advanced Symbolic Stars, or Pillar interaction analysis
  • Calculations use standard timezone time, not Real Solar Time adjusted for longitude
  • For professional consultations, please consult a qualified Bazi practitioner

🤝 Contributing

We welcome contributions! See our Contributing Guidelines for details.

📄 License

MIT License - see the LICENSE file for details.


Based on the original work by Alvamind