基于Python+Flask实现农历转换API实战指南

 更新时间:2025年12月31日 14:23:27   作者:weixin_46244623  
这篇文章主要为大家详细介绍了如何基于 lunar-python 农历算法库,使用 Flask 封装了一套 完整、可直接部署的农历转换 REST API,感兴趣的小伙伴可以了解下

在国内业务系统中,农历(阴历) 仍然被广泛使用,例如:

  • 农历生日、纪念日
  • 传统节日(春节、除夕、中秋)
  • 日历 / 黄历 / 命理类应用
  • 本地化系统展示

本文基于 lunar-python 农历算法库,使用 Flask 封装了一套 完整、可直接部署的农历转换 REST API,支持:

  • 公历 → 农历
  • 农历 → 公历(支持闰月)
  • 当前农历日期查询
  • 干支、生肖、节气、节日
  • 完整中文描述

支持时间范围:1900 – 2100 年

一、技术选型说明

lunar-python

选择 lunar-python 的原因:

  • 农历算法成熟、权威
  • API 设计清晰
  • 支持干支、生肖、节气、节日
  • 支持闰月(负数月份表示)
  • 纯 Python,无外部依赖
pip install lunar-python

Flask

  • 轻量
  • 易于部署
  • 非常适合工具型 API / 内部服务
pip install flask

二、API 设计说明

本示例实现了 4 个接口:

接口说明
/api/to_lunar公历 → 农历
/api/to_solar农历 → 公历(支持闰月)
/api/today_lunar获取当前农历
/服务状态 & 接口说明

三、核心设计:统一农历数据结构

为了方便前端或其他系统使用,先对 lunar-python 的返回结果进行统一格式化

农历信息格式化函数

def format_lunar(lunar):
    """统一格式化农历信息(完全适配 lunar_python 最新版)"""
    month = lunar.getMonth()  # 可能为负数(闰月)
    is_leap_month = month < 0
    abs_month = abs(month)

    festivals = lunar.getFestivals()          # 标准农历节日
    other_festivals = lunar.getOtherFestivals()  # 其他扩展节日

    return {
        "lunar_year": lunar.getYear(),
        "lunar_month": abs_month,
        "lunar_day": lunar.getDay(),
        "is_leap_month": is_leap_month,
        "chinese_string": lunar.toFullString(),
        "full_info": lunar.toFullString(),
        "ganzhi_year": lunar.getYearInChinese(),
        "ganzhi_month": lunar.getMonthInChinese(),
        "ganzhi_day": lunar.getDayInChinese(),
        "shengxiao": lunar.getYearShengXiao(),
        "jieqi": lunar.getJieQi() if lunar.getJieQi() else None,
        "festivals": festivals if festivals else None,
        "other_festivals": other_festivals if other_festivals else None
    }

设计说明

闰月判断:month < 0

节日区分:

  • getFestivals():传统节日(春节、除夕)
  • getOtherFestivals():扩展节日

输出结构稳定,方便前端直接使用

四、公历 → 农历 API

接口定义

GET /api/to_lunar

参数

参数说明
year公历年
month公历月
day公历日

代码实现

@app.route('/api/to_lunar', methods=['GET'])
def to_lunar():
    try:
        year = int(request.args.get('year'))
        month = int(request.args.get('month'))
        day = int(request.args.get('day'))

        solar = Solar.fromYmd(year, month, day)
        lunar = solar.getLunar()

        return jsonify({
            "success": True,
            "solar_date": f"{year}-{month:02d}-{day:02d}",
            "lunar": format_lunar(lunar)
        })
    except Exception as e:
        return jsonify({
            "success": False,
            "error": str(e)
        }), 400

示例请求

/api/to_lunar?year=2025&month=2&day=1

五、农历 → 公历 API(支持闰月)

接口定义

GET /api/to_solar

参数

参数说明
year农历年
month农历月
day农历日
leap是否闰月(true / false)

关键点:闰月处理

lunar_month = -month if leap else month

这是 lunar-python 的标准用法。

代码实现

@app.route('/api/to_solar', methods=['GET'])
def to_solar():
    try:
        year = int(request.args.get('year'))
        month = int(request.args.get('month'))
        day = int(request.args.get('day'))
        leap = request.args.get('leap', 'false').lower() in ('true', '1', 'yes')

        lunar_month = -month if leap else month
        lunar = Lunar.fromYmd(year, lunar_month, day)
        solar = lunar.getSolar()

        return jsonify({
            "success": True,
            "lunar": format_lunar(lunar),
            "solar_date": solar.toYmd()
        })
    except Exception as e:
        return jsonify({
            "success": False,
            "error": str(e)
        }), 400

六、获取当前农历日期 API

接口定义

GET /api/today_lunar

代码实现

@app.route('/api/today_lunar', methods=['GET'])
def today_lunar():
    try:
        now = datetime.now()
        today_solar = Solar.fromDate(now)
        today_lunar = today_solar.getLunar()

        return jsonify({
            "success": True,
            "solar_date": today_solar.toYmd(),
            "solar_datetime": today_solar.toYmdHms(),
            "timestamp": now.isoformat(),
            "lunar": format_lunar(today_lunar)
        })
    except Exception as e:
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500

适合:

  • 首页日历
  • 今日农历展示
  • 黄历 / 日签应用

七、服务启动与运行

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5006, debug=True)

启动后访问:http://localhost:5006/

即可看到接口说明。

八、返回 JSON 示例(简化)

{
  "lunar_year": 2024,
  "lunar_month": 12,
  "lunar_day": 4,
  "is_leap_month": false,
  "chinese_string": "甲辰年 腊月初四",
  "shengxiao": "龙",
  "festivals": ["春节"]
}

九、完整代码

from flask import Flask, request, jsonify
from lunar_python import Solar, Lunar
from datetime import datetime
import traceback

app = Flask(__name__)

def format_lunar(lunar):
    """统一格式化农历信息(完全适配 lunar_python 最新版)"""
    month = lunar.getMonth()  # 可能为负数(闰月)
    is_leap_month = month < 0
    abs_month = abs(month)

    festivals = lunar.getFestivals()  # 标准农历节日(如春节、除夕)
    other_festivals = lunar.getOtherFestivals()  # 其他扩展节日

    return {
        "lunar_year": lunar.getYear(),
        "lunar_month": abs_month,
        "lunar_day": lunar.getDay(),
        "is_leap_month": is_leap_month,
        "chinese_string": lunar.toFullString(),
        "full_info": lunar.toFullString(),
        "ganzhi_year": lunar.getYearInChinese(),
        "ganzhi_month": lunar.getMonthInChinese(),
        "ganzhi_day": lunar.getDayInChinese(),
        "shengxiao": lunar.getYearShengXiao(),
        "jieqi": lunar.getJieQi() if lunar.getJieQi() else None,
        "festivals": festivals if festivals else None,  # 传统农历节日列表
        "other_festivals": other_festivals if other_festivals else None  # 其他节日
    }

@app.route('/api/to_lunar', methods=['GET'])
def to_lunar():
    try:
        year = int(request.args.get('year'))
        month = int(request.args.get('month'))
        day = int(request.args.get('day'))

        solar = Solar.fromYmd(year, month, day)
        lunar = solar.getLunar()

        return jsonify({
            "success": True,
            "solar_date": f"{year}-{month:02d}-{day:02d}",
            "lunar": format_lunar(lunar)
        })
    except Exception as e:
        app.logger.error(f"Error in to_lunar: {str(e)}\n{traceback.format_exc()}")
        return jsonify({
            "success": False,
            "error": str(e),
            "detail": str(e)
        }), 400

@app.route('/api/to_solar', methods=['GET'])
def to_solar():
    try:
        year = int(request.args.get('year'))
        month = int(request.args.get('month'))
        day = int(request.args.get('day'))
        leap = request.args.get('leap', 'false').lower() in ('true', '1', 'yes')

        lunar_month = -month if leap else month
        lunar = Lunar.fromYmd(year, lunar_month, day)
        solar = lunar.getSolar()

        return jsonify({
            "success": True,
            "lunar": format_lunar(lunar),
            "solar_date": solar.toYmd()
        })
    except Exception as e:
        app.logger.error(f"Error in to_solar: {str(e)}\n{traceback.format_exc()}")
        return jsonify({
            "success": False,
            "error": str(e),
            "detail": str(e)
        }), 400

@app.route('/api/today_lunar', methods=['GET'])
def today_lunar():
    try:
        app.logger.info("Calling /api/today_lunar")
        
        now = datetime.now()
        today_solar = Solar.fromDate(now)
        app.logger.info(f"Today solar: {today_solar.toYmd()} {today_solar.toYmdHms()}")

        today_lunar = today_solar.getLunar()

        return jsonify({
            "success": True,
            "solar_date": today_solar.toYmd(),
            "solar_datetime": today_solar.toYmdHms(),
            "timestamp": now.isoformat(),
            "lunar": format_lunar(today_lunar)
        })

    except Exception as e:
        error_msg = str(e)
        tb = traceback.format_exc()
        app.logger.error(f"Error in today_lunar: {error_msg}\n{tb}")

        return jsonify({
            "success": False,
            "error": "Internal Server Error",
            "detail": error_msg,
            "traceback": tb
        }), 500

@app.route('/', methods=['GET'])
def home():
    return jsonify({
        "message": "Lunar Calendar API is running! (lunar_python fully adapted)",
        "current_time": datetime.now().isoformat(),
        "endpoints": {
            "to_lunar": "/api/to_lunar?year=2025&month=12&day=24",
            "to_solar": "/api/to_solar?year=2025&month=11&day=5&leap=false",
            "today_lunar": "/api/today_lunar"
        }
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5006, debug=True)

十、适用场景

日历 / 黄历系统

农历生日管理

中国本土化应用

Web / 小程序后端

内部工具 API

总结

本文基于 lunar-python + Flask 实现了一套功能完整、结构清晰、可直接部署的农历转换 API

特点:

  • 不依赖外部命令
  • 支持闰月
  • 返回结构友好
  • 易于扩展

非常适合用于实际生产项目。

到此这篇关于基于Python+Flask实现农历转换API实战指南的文章就介绍到这了,更多相关Python农历转换API内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python脚本设置系统时间的两种方法

    python脚本设置系统时间的两种方法

    这篇文章主要介绍了python脚本设置系统时间的两种方法,其一是调用socket直接发送udp包到国家授时中心,其二是调用ntplib包,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • 基于Python开发一个文件头签名分析工具

    基于Python开发一个文件头签名分析工具

    本文介绍了一个功能强大的文件头签名分析工具的实现原理和开发过程,该工具通过读取文件头部二进制签名来识别文件真实类型,即使用户修改了文件扩展名也能准确判断,文章详细解析了核心算法、GUI设计以及技术实现细节,为开发类似工具提供了完整参考,需要的朋友可以参考下
    2025-05-05
  • Python实现图片格式转换

    Python实现图片格式转换

    经常会遇到图片格式需要转换的情况,这篇文章主要为大家详细介绍了Python实现图片格式转换,文中示例代码介绍的非常详细、实用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • Python中使用正则表达式精准匹配IP地址的案例

    Python中使用正则表达式精准匹配IP地址的案例

    Python的正则表达式(re模块)是完成这个任务的利器,但你知道怎么写才能准确匹配各种合法的IP地址吗,今天我们就来详细探讨这个问题,感兴趣的朋友一起看看吧
    2025-04-04
  • Python全栈之for循环

    Python全栈之for循环

    这篇文章主要为大家介绍了Python for循环,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-11-11
  • Python 带星号(* 或 **)的函数参数详解

    Python 带星号(* 或 **)的函数参数详解

    这篇文章主要介绍了Python 带星号(* 或 **)的函数参数详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • tensorflow实现在函数中用tf.Print输出中间值

    tensorflow实现在函数中用tf.Print输出中间值

    今天小编就为大家分享一篇tensorflow实现在函数中用tf.Print输出中间值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-01-01
  • pandas 使用merge实现百倍加速的操作

    pandas 使用merge实现百倍加速的操作

    这篇文章主要介绍了pandas 使用merge实现百倍加速的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • Python数据可视化之画图

    Python数据可视化之画图

    今天小编就为大家分享一篇关于Python数据可视化之画图,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Python使用email​库创建和解析电子邮件详解

    Python使用email​库创建和解析电子邮件详解

    在现代软件开发中,处理电子邮件是一项常见的任务,本文将介绍如何使用Python的​​email​​库来创建和解析电子邮件,有需要的小伙伴可以参考一下
    2025-09-09

最新评论