FreeAstroAPI LogoFreeAstroAPI
返回指南
中文命理

用 Python 计算 BaZi 四柱

学习如何用 Python 从出生日期计算 Four Pillars of Destiny (八字),包括 lunar calendar、Heavenly Stems、Earthly Branches 和实用代码示例。

什么是 BaZi(四柱八字)?

BaZi (八字) 字面意思是“八个字”。它根据出生日期和时间,推导出 Year、Month、Day、Hour 四个柱。每个柱由一个 Heavenly Stem (天干 / Tiān Gān) 和一个 Earthly Branch (地支 / Dì Zhī) 组成。

这八个字用来描述出生时刻的五行气场,并进一步分析性格、事业、关系和人生周期。


基础元素

10 个 Heavenly Stems (天干)

StemPinyinElementPolarity
JiǎWoodYang
WoodYin
BǐngFireYang
DīngFireYin
EarthYang
EarthYin
GēngMetalYang
XīnMetalYin
RénWaterYang
GuǐWaterYin

12 个 Earthly Branches (地支)

BranchPinyinZodiacElement
RatWater
ChǒuOxEarth
YínTigerWood
MǎoRabbitWood
ChénDragonEarth
SnakeFire
HorseFire
WèiGoatEarth
ShēnMonkeyMetal
YǒuRoosterMetal
DogEarth
HàiPigWater

六十甲子

10 个 Stems 和 12 个 Branches 按顺序组合,形成 60 个单位的循环。这是中国历法系统的基础,用来表示年、月、日、时。

循环从 甲子 (Jiǎ Zǐ) 开始,到 癸亥 (Guǐ Hài) 结束。要确定某一刻对应的 Stem-Branch,需要精确处理节气,尤其是月柱边界。


用 Python 计算四柱

Python 中最实用的方式是使用 lunar-python。它处理 Gregorian calendar、Chinese lunar calendar 和 sexagenary cycle 之间的转换。

安装

pip install lunar-python

基础计算

from lunar_python import Solar

# Birth data: May 15, 1990 at 10:30 AM
year, month, day = 1990, 5, 15
hour, minute = 10, 30

# Create a Solar (Gregorian) date object
solar = Solar.fromYmdHms(year, month, day, hour, minute, 0)

# Convert to Lunar and then to BaZi (EightChar)
lunar = solar.getLunar()
eight_char = lunar.getEightChar()

# Extract the Four Pillars
print("Year Pillar:", eight_char.getYear())    # e.g., 庚午
print("Month Pillar:", eight_char.getMonth())  # e.g., 辛巳
print("Day Pillar:", eight_char.getDay())      # e.g., 丙寅
print("Hour Pillar:", eight_char.getTime())    # e.g., 癸巳

输出:

Year Pillar:  庚午
Month Pillar: 辛巳
Day Pillar:   丙寅
Hour Pillar:  癸巳

提取单独的 Stem 和 Branch

# Stems (天干)
print("Year Stem:", eight_char.getYearGan())   # 庚
print("Month Stem:", eight_char.getMonthGan()) # 辛
print("Day Stem:", eight_char.getDayGan())     # 丙
print("Hour Stem:", eight_char.getTimeGan())   # 癸

# Branches (地支)
print("Year Branch:", eight_char.getYearZhi())   # 午
print("Month Branch:", eight_char.getMonthZhi()) # 巳
print("Day Branch:", eight_char.getDayZhi())     # 寅
print("Hour Branch:", eight_char.getTimeZhi())   # 巳

Hidden Stems (藏干)

每个 Earthly Branch 都包含隐藏天干。lunar-python 可以直接取出:

# Hidden stems for each pillar
print("Year Hidden:", eight_char.getYearHideGan())   # ['丁', '己']
print("Month Hidden:", eight_char.getMonthHideGan()) # ['丙', '庚', '戊']
print("Day Hidden:", eight_char.getDayHideGan())     # ['甲', '丙', '戊']
print("Hour Hidden:", eight_char.getTimeHideGan())   # ['丙', '庚', '戊']

Ten Gods (十神)

Ten Gods 描述各柱元素和 Day Master 的关系,是 BaZi 解释的核心。

# The Day Master is the Day Stem
day_master = eight_char.getDayGan()
print(f"Day Master: {day_master}")  # 丙 (Bing Fire)

# Ten Gods for each pillar's stem
print("Year Ten God:", eight_char.getYearShiShenGan())   # Direct Wealth
print("Month Ten God:", eight_char.getMonthShiShenGan()) # Indirect Wealth
print("Hour Ten God:", eight_char.getTimeShiShenGan())   # Direct Resource

计算 Luck Cycle (大运)

10 年一轮的 Luck Pillars (Da Yun) 根据出生盘和性别计算:

# 1 = Male, 0 = Female
sex = 1

yun = eight_char.getYun(sex)
print(f"Luck cycle starts at age: {yun.getStartYear()}")
print(f"Direction: {'Forward' if yun.isForward() else 'Backward'}")

for da_yun in yun.getDaYun():
    if da_yun.getIndex() == 0:
        continue  # Skip the base period
    print(f"Age {da_yun.getStartAge()}-{da_yun.getEndAge()}: {da_yun.getGanZhi()}")

时区和真太阳时

BaZi 计算里最容易出错的是本地时间。很多专业实践会使用 True Solar Time,也就是太阳实际位置对应的时间,而不是民用钟表时间。

核心步骤:

  1. Longitude Correction:按出生地在时区中的经度位置修正。
  2. Equation of Time:补偿地球轨道偏心率。
from datetime import datetime, timedelta

def get_true_solar_time(dt, longitude, timezone_meridian):
    """
    Calculate True Solar Time from civil time.
    
    Args:
        dt: datetime object in local civil time
        longitude: Birth location longitude (degrees, East positive)
        timezone_meridian: Standard meridian for the timezone (e.g., 120 for UTC+8)
    
    Returns:
        Adjusted datetime representing True Solar Time
    """
    # Longitude correction: 4 minutes per degree from standard meridian
    long_correction_minutes = (longitude - timezone_meridian) * 4
    
    # Equation of Time approximation (simplified)
    # E = 9.87 * sin(2B) - 7.53 * cos(B) - 1.5 * sin(B)
    import math
    day_of_year = dt.timetuple().tm_yday
    b = (2 * math.pi / 365) * (day_of_year - 81)
    eot_minutes = 9.87 * math.sin(2*b) - 7.53 * math.cos(b) - 1.5 * math.sin(b)
    
    total_correction = timedelta(minutes=long_correction_minutes + eot_minutes)
    return dt + total_correction

完整 chart 示例

from lunar_python import Solar

def calculate_bazi_chart(year, month, day, hour, minute, sex=1):
    """
    Calculate a complete Bazi chart.
    
    Returns a dictionary with all four pillars and their components.
    """
    solar = Solar.fromYmdHms(year, month, day, hour, minute, 0)
    lunar = solar.getLunar()
    eight_char = lunar.getEightChar()
    
    pillars = []
    labels = ["year", "month", "day", "hour"]
    
    stems = [
        eight_char.getYearGan(),
        eight_char.getMonthGan(),
        eight_char.getDayGan(),
        eight_char.getTimeGan()
    ]
    
    branches = [
        eight_char.getYearZhi(),
        eight_char.getMonthZhi(),
        eight_char.getDayZhi(),
        eight_char.getTimeZhi()
    ]
    
    for i, label in enumerate(labels):
        pillars.append({
            "label": label,
            "stem": stems[i],
            "branch": branches[i],
            "pillar": f"{stems[i]}{branches[i]}"
        })
    
    return {
        "day_master": eight_char.getDayGan(),
        "pillars": pillars,
        "lunar_date": f"{lunar.getYearInChinese()}年 {lunar.getMonthInChinese()}月 {lunar.getDayInChinese()}"
    }

# Example usage
chart = calculate_bazi_chart(1990, 5, 15, 10, 30, sex=1)
print(f"Day Master: {chart['day_master']}")
print(f"Lunar Date: {chart['lunar_date']}")
for p in chart['pillars']:
    print(f"{p['label'].capitalize()} Pillar: {p['pillar']}")

自己算还是用 API?

自己用 Python 计算很适合学习,但生产应用还要处理:

  1. Maintenance:timezone 数据和规则会变化。
  2. Accuracy:True Solar Time 需要准确经纬度和高质量 ephemeris,例如 NASA JPL DE405。
  3. Complexity:Rat hour、Early vs Late limit、Blind Years 等边界需要领域知识。

如果你需要稳定精度和专业功能,专门的 API 会省掉很多维护工作。


Open Source Libraries

LibraryPurposeLicense
lunar-pythonChinese calendar and Bazi calculationsMIT
pytzTimezone handlingMIT
timezonefinderTimezone lookup from coordinatesMIT

试用免费 BaZi API

/api/v1/chinese/bazi endpoint 提供:

  • Complete Four Pillars with Pinyin romanization
  • Ten Gods relationships for every stem
  • Hidden Stems with element analysis
  • Symbolic Stars (Shen Sha) including Nobleman, Peach Blossom, and more
  • Branch interactions: Combinations, Clashes, Harmonies, Punishments
  • 10-year Luck Cycle calculation
  • Professional features: Day Master strength, Chart Structure, Yong Shen analysis

快速示例

import requests

url = "https://api.freeastroapi.com/api/v1/chinese/bazi"

payload = {
    "year": 1990,
    "month": 5,
    "day": 15,
    "hour": 10,
    "minute": 30,
    "lat": 28.6139,
    "lng": 77.2090,
    "sex": "M",
    "include_pinyin": True,
    "include_stars": True,
    "include_interactions": True,
    "include_professional": True
}

headers = {
    "Content-Type": "application/json",
    "x-api-key": "YOUR_API_KEY"
}

response = requests.post(url, headers=headers, json=payload)
print(response.json())

阅读完整 API 文档 →


开始构建

学习阶段可以直接用 lunar-python。如果要做产品,用 Bazi API 处理计算,把时间花在界面、解释和用户体验上。

获取免费 API Key →

继续阅读

全部指南