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

周叙
周叙
发布时间:2026-10-11 | 4人浏览过
原创

针对国内业务系统中广泛使用的农历日期展示与计算需求,本文介绍如何使用 Python 的 lunar-python 库结合 Flask 框架,快速搭建一套支持公历转农历、农历反推公历(含闰月处理)、实时查询及干支生肖节气的 REST API。服务覆盖 1900 至 2100 年,结构清晰且无需外部依赖,可直接集成至日历应用或小程序后端。

环境准备与核心数据结构

在国内日历、黄历、命理及本地化系统中,农历(阴历)的精准转换是常见刚需。为实现高效稳定的日期处理,本文选用成熟且权威的纯 Python 算法库 lunar-python,配合轻量级 Web 框架 Flask 进行封装。该组合无外部系统依赖,原生支持干支、生肖、节气、扩展节日及闰月(负数月份标识),非常适合内部工具服务或独立部署。

第 1 步:安装依赖库

在项目环境中执行以下命令安装核心组件:

pip install lunar-python flask

注:安装包名为 lunar-python,但在 Python 代码中需通过 import lunar_python 调用。

第 2 步:封装统一农历数据格式

为方便前端或其他业务系统直接使用,首先对算法库的原始返回值进行标准化清洗。重点处理闰月标识(getMonth()<0 为闰月)以及传统节日与扩展节日的分类:


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(),
        "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
    }

REST API 接口开发与逻辑

基于 Flask 路由机制,依次定义四个核心端点。所有接口均包含基础的异常捕获,确保非法输入时返回 400 状态码及详细错误提示。

第 3 步:实现公历转农历接口

通过 GET 请求接收年月日参数,调用 Solar.fromYmd() 转为阳历实例后获取农历:


@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)}")
        return jsonify({"success": False, "error": str(e)}), 400

测试请求示例:GET /api/to_lunar?year=2025&month=2&day=1

第 4 步:实现农历转公历接口(闰月适配)

反向转换需额外处理闰月参数。在 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:
        app.logger.error(f"Error in to_solar: {str(e)}")
        return jsonify({"success": False, "error": str(e)}), 400

第 5 步:添加当前农历查询接口

适用于首页日签、黄历看板等场景。利用 datetime.now() 获取服务器当前时间并解析:


@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:
        tb = traceback.format_exc()
        app.logger.error(f"Error in today_lunar: {str(e)}\n{tb}")
        return jsonify({"success": False, "error": "Internal Server Error", "detail": str(e), "traceback": tb}), 500

服务部署与运行配置

第 6 步:启动服务并访问验证

将上述路由函数整合至同一文件中,添加入口启动代码。开发阶段启用调试模式便于查看报错栈:


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

启动后访问 http://localhost:5006/ 将返回健康检查 JSON,包含各接口路径说明。实际生产环境中,建议移除 debug=True 并将 host 绑定至指定内网 IP,同时配置 Nginx 反向代理或 Gunicorn 承载高并发请求。

常见问题与排查建议

  • 闰月识别失败:确保 to_solar 接口的 leap 参数正确传递布尔值,并在代码中转换为负数月份。Lunar.fromYmd(2025, -2, 5) 等效于闰二月。
  • 时区偏差:datetime.now() 依赖服务器系统时区。若业务跨地域,建议在入口处显式指定时区(如 zoneinfo.ZoneInfo("Asia/Shanghai"))以保证农历日切分准确。
  • 日志未持久化:示例代码使用 app.logger,默认仅输出至控制台。生产环境建议通过 logging.config.dictConfig 配置文件轮转策略。

总结

本文基于 lunar-python + Flask 实现了一套功能完整、结构清晰、可直接部署的农历转换 API。该方案不依赖外部命令行工具,原生支持闰月解析与干支节气计算,返回的 JSON 结构经过统一清洗,极大降低了前后端联调成本。无论是日历类应用、生日提醒系统还是企业微信/钉钉机器人内部工具,均可平滑接入。以上就是基于Python+Flask实现农历转换API实战指南的详细内容,更多关于Python农历转换API与内部服务集成的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表