Files
----/后端源码/yifan.action-ai.cn/app/utils/lunar_util.py

70 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
import datetime
from cnlunar import Lunar
ZODIAC = ['', '', '', '', '', '', '', '', '', '', '', '']
SHICHEN = ['子时', '丑时', '寅时', '卯时', '辰时', '巳时', '午时', '未时', '申时', '酉时', '戌时', '亥时', '子时']
TIANGAN = ['', '', '', '', '', '', '', '', '', '']
DIZHI = ['', '', '', '', '', '', '', '', '', '', '', '']
WEEKDAYS = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
def get_zodiac(year: int) -> str:
"""根据年份计算生肖"""
return ZODIAC[(year - 4) % 12]
def get_ganzhi_year(year: int) -> str:
"""根据年份计算干支年(如:甲辰)"""
idx = (year - 4) % 60
return TIANGAN[idx % 10] + DIZHI[idx % 12]
def get_ganzhi_month(year: int, month: int) -> str:
"""简化算法计算干支月"""
idx = (year * 12 + month + 13) % 60
return TIANGAN[idx % 10] + DIZHI[idx % 12]
def get_ganzhi_day(dt_date: datetime.date) -> str:
"""基于儒略日计算干支日"""
a = (14 - dt_date.month) // 12
y = dt_date.year + 4800 - a
m = dt_date.month + 12 * a - 3
jdn = dt_date.day + (153 * m + 2) // 5 + 365 * y + y // 4 - y // 100 + y // 400 - 32045
idx = (jdn + 49) % 60
return TIANGAN[idx % 10] + DIZHI[idx % 12]
def _has_valid_time(dt: datetime.datetime) -> bool:
"""判断时间部分是否有效(非 00:00:00"""
return dt.hour != 0 or dt.minute != 0 or dt.second != 0
def get_shichen_ke(dt: datetime.datetime) -> tuple[str, int]:
"""根据时间计算时辰和刻数,返回 (时辰, 刻)"""
lunar = Lunar(dt)
shichen = SHICHEN[lunar.twohourNum]
minutes_in_shichen = (dt.hour * 60 + dt.minute) % 120
ke = minutes_in_shichen // 15 + 1
return shichen, ke
def format_lunar_date(dt: datetime.datetime, with_time: bool = True) -> str:
"""
将公历日期格式化为农历字符串。
with_time=True 且时间有效时,追加时辰刻数。
返回示例:(乙巳年 五月初六 申时3刻 或 (乙巳年 五月初六)
"""
lunar = Lunar(dt)
lunar_year = f"{lunar.year8Char}"
lunar_month = lunar.lunarMonthCn.replace('', '').replace('', '')
lunar_day = lunar.lunarDayCn
if with_time and _has_valid_time(dt):
shichen, ke = get_shichen_ke(dt)
return f"{lunar_year} {lunar_month}{lunar_day} {shichen}{ke}刻)"
return f"{lunar_year} {lunar_month}{lunar_day}"