news 2026/5/3 3:51:52

基于 Flask + lunar-python 的农历转换 API 实战(公历 ↔ 农历 / 干支 / 生肖 / 节日)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于 Flask + lunar-python 的农历转换 API 实战(公历 ↔ 农历 / 干支 / 生肖 / 节日)

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

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

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

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

支持时间范围:1900 – 2100 年


一、技术选型说明

1️⃣ lunar-python

选择lunar-python的原因:

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

2️⃣ Flask

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

二、API 设计说明

本示例实现了 4 个接口:

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

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

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

农历信息格式化函数

defformat_lunar(lunar):"""统一格式化农历信息(完全适配 lunar_python 最新版)"""month=lunar.getMonth()# 可能为负数(闰月)is_leap_month=month<0abs_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()iflunar.getJieQi()elseNone,"festivals":festivalsiffestivalselseNone,"other_festivals":other_festivalsifother_festivalselseNone}

设计说明

  • 闰月判断month < 0

  • 节日区分

    • getFestivals():传统节日(春节、除夕)
    • getOtherFestivals():扩展节日
  • 输出结构稳定,方便前端直接使用


四、公历 → 农历 API

接口定义

GET /api/to_lunar

参数

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

代码实现

@app.route('/api/to_lunar',methods=['GET'])defto_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()returnjsonify({"success":True,"solar_date":f"{year}-{month:02d}-{day:02d}","lunar":format_lunar(lunar)})exceptExceptionase:returnjsonify({"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=-monthifleapelsemonth

这是lunar-python的标准用法。

代码实现

@app.route('/api/to_solar',methods=['GET'])defto_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=-monthifleapelsemonth lunar=Lunar.fromYmd(year,lunar_month,day)solar=lunar.getSolar()returnjsonify({"success":True,"lunar":format_lunar(lunar),"solar_date":solar.toYmd()})exceptExceptionase:returnjsonify({"success":False,"error":str(e)}),400

六、获取当前农历日期 API

接口定义

GET /api/today_lunar

代码实现

@app.route('/api/today_lunar',methods=['GET'])deftoday_lunar():try:now=datetime.now()today_solar=Solar.fromDate(now)today_lunar=today_solar.getLunar()returnjsonify({"success":True,"solar_date":today_solar.toYmd(),"solar_datetime":today_solar.toYmdHms(),"timestamp":now.isoformat(),"lunar":format_lunar(today_lunar)})exceptExceptionase:returnjsonify({"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 flaskimportFlask, request, jsonify from lunar_pythonimportSolar, Lunar from datetimeimportdatetimeimporttraceback app=Flask(__name__)def format_lunar(lunar):"""统一格式化农历信息(完全适配 lunar_python 最新版)""" month=lunar.getMonth()# 可能为负数(闰月)is_leap_month=month<0abs_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()iflunar.getJieQi()elseNone,"festivals":festivalsiffestivalselseNone,# 传统农历节日列表"other_festivals":other_festivalsifother_festivalselseNone# 其他节日}@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()returnjsonify({"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()}")returnjsonify({"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=-monthifleapelsemonth lunar=Lunar.fromYmd(year, lunar_month, day)solar=lunar.getSolar()returnjsonify({"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()}")returnjsonify({"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()returnjsonify({"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}")returnjsonify({"success":False,"error":"Internal Server Error","detail":error_msg,"traceback":tb}),500@app.route('/',methods=['GET'])def home():returnjsonify({"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

特点:

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/26 3:08:48

Vugu实战指南:7步掌握Go语言WebAssembly开发新范式

Vugu实战指南&#xff1a;7步掌握Go语言WebAssembly开发新范式 【免费下载链接】vugu Vugu: A modern UI library for GoWebAssembly (experimental) 项目地址: https://gitcode.com/gh_mirrors/vu/vugu Vugu是一个创新的现代化UI库&#xff0c;专为Go语言和WebAssembly…

作者头像 李华
网站建设 2026/5/2 20:42:14

5分钟上手Hexo主题Solitude:打造优雅简约的个人博客空间

5分钟上手Hexo主题Solitude&#xff1a;打造优雅简约的个人博客空间 【免费下载链接】hexo-theme-solitude 一个优雅的Heo风格的Hexo主题&#xff0c;接近Heo&#xff0c;完整度高。 项目地址: https://gitcode.com/gh_mirrors/hexo/hexo-theme-solitude 还在为博客主题…

作者头像 李华
网站建设 2026/5/1 4:09:10

WeKnora实战部署:从零搭建智能文档问答系统

WeKnora实战部署&#xff1a;从零搭建智能文档问答系统 【免费下载链接】WeKnora LLM-powered framework for deep document understanding, semantic retrieval, and context-aware answers using RAG paradigm. 项目地址: https://gitcode.com/GitHub_Trending/we/WeKnora …

作者头像 李华
网站建设 2026/4/30 10:11:15

专业B站视频下载工具完整使用手册

专业B站视频下载工具完整使用手册 【免费下载链接】bilidown 哔哩哔哩视频解析下载工具&#xff0c;支持 8K 视频、Hi-Res 音频、杜比视界下载、批量解析&#xff0c;可扫码登录&#xff0c;常驻托盘。 项目地址: https://gitcode.com/gh_mirrors/bilid/bilidown 还在为…

作者头像 李华
网站建设 2026/4/25 13:15:40

如何评估TensorFlow-v2.9镜像的计算性能与显存占用

如何评估 TensorFlow-v2.9 镜像的计算性能与显存占用 在深度学习项目从实验走向落地的过程中&#xff0c;一个稳定、高效的运行环境往往决定了整个开发流程的成败。尽管模型架构和数据质量备受关注&#xff0c;但底层框架的性能表现——尤其是容器化镜像在真实硬件上的计算效率…

作者头像 李华
网站建设 2026/5/2 21:21:37

智能补全失效深度修复指南:让DBeaver SQL编辑器重新流畅如初

智能补全失效深度修复指南&#xff1a;让DBeaver SQL编辑器重新流畅如初 【免费下载链接】dbeaver DBeaver 是一个通用的数据库管理工具&#xff0c;支持跨平台使用。* 支持多种数据库类型&#xff0c;如 MySQL、PostgreSQL、MongoDB 等&#xff1b;提供 SQL 编辑、查询、调试等…

作者头像 李华