FreeAstroAPI LogoFreeAstroAPI
返回指南
中文命理作者

用 Python 计算八字四柱

学习如何用 Python 根据出生日期计算四柱八字,包括农历、天干、地支和实用代码示例。

什么是八字(四柱八字)?

八字字面意思是“八个字”。它根据出生日期和时间推导出年、月、日、时四柱。每柱由一个天干(Tiān Gān)和一个地支(Dì Zhī)组成。

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


基础元素

十天干

天干拼音五行阴阳
甲Jiǎ木阳
乙Yǐ木阴
丙Bǐng火阳
丁Dīng火阴
戊Wù土阳
己Jǐ土阴
庚Gēng金阳
辛Xīn金阴
壬Rén水阳
癸Guǐ水阴

十二地支

地支拼音生肖五行
子Zǐ鼠水
丑Chǒu牛土
寅Yín虎木
卯Mǎo兔木
辰Chén龙土
巳Sì蛇火
午Wǔ马火
未Wèi羊土
申Shēn猴金
酉Yǒu鸡金
戌Xū狗土
亥Hài猪水

六十甲子

10 个天干与 12 个地支按顺序组合,形成 60 个单位的循环。这是中国历法的基础,用来表示年、月、日、时。

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


用 Python 计算四柱

在 Python 中,最实用的方式是使用 lunar-python。它负责公历、农历和六十甲子之间的转换。

安装

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:  癸巳

分别提取天干和地支

# 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())   # 巳

藏干

每个地支都包含藏干。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())   # ['丙', '庚', '戊']

十神

十神描述各柱五行与日主的关系,是八字解读的核心。

# 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

计算大运

每 10 年一轮的大运柱(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()}")

时区和真太阳时

八字计算中最容易出错的是本地时间。许多专业方法会使用真太阳时,也就是太阳实际位置对应的时间,而不是民用钟表时间。

核心步骤:

  1. 经度校正:按出生地在时区中的经度位置修正。
  2. 均时差:补偿地球轨道偏心率。
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

完整星盘示例

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. 维护:时区数据和规则会变化。
  2. 精度:真太阳时需要准确的经纬度和高质量星历,例如 NASA JPL DE405。
  3. 复杂度:子时、早晚子时界限、盲年等边界需要领域知识。

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


自建实现可用的开源库

如果你希望自行维护八字实现,以下开源库可以作为基础组件。FreeAstroAPI 本身是专有托管服务,不公开实现源代码。

库用途许可证
lunar-python中国历法与八字计算MIT
pytz时区处理MIT
timezonefinder根据坐标查询时区MIT

试用免费八字 API

/api/v1/chinese/bazi 端点提供:

  • 带拼音罗马化的完整四柱
  • 每个天干的十神关系
  • 带五行分析的藏干
  • 包含贵人、桃花等的神煞
  • 地支关系:合、冲、会、刑
  • 十年大运计算
  • 专业功能:日主强弱、格局、用神分析

快速示例

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。如果要做产品,用八字 API 处理计算,把时间投入到界面、解读和用户体验上。

获取免费 API Key →

继续阅读

全部指南