一、创作原因
因为家里人口比较多,有时候会忘记某人的生日或者是重要的日子,所以做了一个记录、提醒的网站。
二、制作分享
# 导入必要的库
import lunardate # 处理农历日期转换
from datetime import datetime, date # 处理公历日期和当前时间
import warnings
warnings.filterwarnings('ignore') # 忽略无关警告
def lunar_to_current_solar(lunar_month: int, lunar_day: int) -> date | None:
"""
将指定的农历月日转换为今年对应的公历日期
:param lunar_month: 农历月(整数)
:param lunar_day: 农历日(整数)
:return: 今年对应的公历日期(date对象),转换失败返回None
"""
try:
current_year = datetime.now().year
# 创建今年的农历日期对象(自动处理闰月等特殊情况)
lunar_date_obj = lunardate.LunarDate(current_year, lunar_month, lunar_day)
# 转换为公历日期
solar_date_obj = lunar_date_obj.toSolarDate()
return solar_date_obj
except ValueError as e:
print(f"⚠️ 农历日期转换失败:{e}")
return None
def calculate_age(birth_lunar_year: int) -> int:
"""
根据农历出生年计算今年的年龄
:param birth_lunar_year: 农历出生年(整数)
:return: 今年的年龄(整数)
"""
current_year = datetime.now().year
return current_year - birth_lunar_year
def input_lunar_date(prompt: str) -> tuple[int, int, int] | None:
"""
通用的农历日期输入函数(格式:年-月-日 或 月-日)
:param prompt: 输入提示语
:return: (年, 月, 日) 或 None(输入失败);重要日子返回(0, 月, 日)
"""
while True:
user_input = input(prompt).strip()
if not user_input:
print("❌ 输入不能为空,请重新输入!")
continue
# 拆分输入(支持 年-月-日 或 月-日 两种格式)
parts = user_input.split('-')
try:
if len(parts) == 3:
# 生日场景:年-月-日
year, month, day = map(int, parts)
if 1 <= month <= 12 and 1 <= day <= 30: # 农历日期基础校验
return year, month, day
else:
print("❌ 月份需1-12,日期需1-30,请重新输入!")
elif len(parts) == 2:
# 重要日子场景:月-日(无年份)
month, day = map(int, parts)
if 1 <= month <= 12 and 1 <= day <= 30:
return 0, month, day # 用0标记无年份
else:
print("❌ 月份需1-12,日期需1-30,请重新输入!")
else:
print("❌ 格式错误!请按指定格式输入(年-月-日 或 月-日)")
except ValueError:
print("❌ 输入必须为数字,请重新输入!")
def batch_input_family_birthdays() -> dict:
"""
批量输入家庭成员生日信息
:return: 家庭成员字典 {姓名: (农历年, 农历月, 农历日)}
"""
family_birthdays = {}
print("\n===== 开始输入家庭成员生日(输入完成后按回车结束)=====")
while True:
name = input("请输入家庭成员姓名(直接回车结束输入):").strip()
if not name:
break # 空输入则结束
# 输入该成员的农历生日
date_result = input_lunar_date(f"请输入{name}的农历生日(格式:年-月-日,例如:1995-8-15):")
if date_result:
family_birthdays[name] = date_result
print(f"✅ 已记录 {name} 的生日:{date_result[0]}年{date_result[1]}月{date_result[2]}日")
return family_birthdays
def batch_input_important_days() -> dict:
"""
批量输入重要日子信息
:return: 重要日子字典 {日子名称: (农历月, 农历日)}
"""
important_days = {}
print("\n===== 开始输入重要日子(输入完成后按回车结束)=====")
while True:
day_name = input("请输入重要日子名称(如:结婚纪念日、春节,直接回车结束输入):").strip()
if not day_name:
break
# 输入该日子的农历日期(仅月-日)
date_result = input_lunar_date(f"请输入{day_name}的公历日期(格式:月-日,例如:1-1):")
if date_result:
_, month, day = date_result
important_days[day_name] = (month, day)
print(f"✅ 已记录 {day_name}:公历{month}月{day}日")
return important_days
def generate_reminder(date_obj: date, title: str) -> str:
"""
生成通用的提醒文案
:param date_obj: 公历日期对象
:param title: 提醒标题(如“张三的生日”、“春节”)
:return: 提醒文案字符串
"""
today = datetime.now().date()
days_diff = (date_obj - today).days
if days_diff == 0:
return f"🎉 今日提醒:{title}(公历{date_obj}),今天就是当天!"
elif days_diff > 0:
return f"🎯 即将到来:{title}(公历{date_obj}),还有{days_diff}天!"
else:
# 今年已过,计算明年的日期
next_year = today.year + 1
next_lunar_date = lunardate.LunarDate(next_year, date_obj.month, date_obj.day)
next_solar_date = next_lunar_date.toSolarDate()
next_days_diff = (next_solar_date - today).days
return f"📝 已过备忘:{title}今年(公历{date_obj})已过,明年是{next_solar_date},还有{next_days_diff}天!"
主函数:
def main():
"""主函数:整合所有功能"""
print("===== 家庭生日&重要日子提醒工具 =====")
# 1. 批量输入家庭成员生日
family_birthdays = batch_input_family_birthdays()
# 2. 批量输入重要日子
important_days = batch_input_important_days()
# 3. 输出并提醒家庭成员生日
if family_birthdays:
print("\n" + "=" * 80)
print("🎂 家庭成员今年生日信息汇总")
print("=" * 80)
for name, (birth_year, lunar_month, lunar_day) in family_birthdays.items():
# 转换为今年的公历生日
solar_birthday = lunar_to_current_solar(lunar_month, lunar_day)
if solar_birthday:
age = calculate_age(birth_year)
reminder = generate_reminder(solar_birthday, f"{name}的{age}岁生日")
print(f"\n【{name}】")
print(f" 农历生日:{birth_year}年{lunar_month}月{lunar_day}日")
print(f" 今年公历生日:{solar_birthday}")
print(f" 今年年龄:{age}岁")
print(f" 提醒:{reminder}")
# 4. 输出并提醒重要日子
if important_days:
print("\n" + "=" * 80)
print("🎊 重要日子今年日期汇总")
print("=" * 80)
current_year = datetime.now().year
for day_name, (lunar_month, lunar_day) in important_days.items():
# 创建今年的公历日期对象(自动处理闰月等特殊情况)
solar_day = datetime(current_year, lunar_month, lunar_day).date()
if solar_day:
reminder = generate_reminder(solar_day, day_name)
print(f"\n【{day_name}】")
print(f" 公历日期:{lunar_month}月{lunar_day}日")
print(f" 今年公历日期:{solar_day}")
print(f" 提醒:{reminder}")
# 无数据提示
if not family_birthdays and not important_days:
print("\n⚠️ 未记录任何家庭成员生日或重要日子!")
if __name__ == "__main__":
# 安装依赖(首次运行需执行)
# pip install lunardate
main()

57

被折叠的 条评论
为什么被折叠?



