当前位置: 首页 > article >正文

python 打印阳历对应的日农历时间

在这里插入图片描述

代码逻辑

  1. 使用print("首周数据示例:")输出标题
  2. 遍历data["weeks"][0]中的每一天数据
  3. 如果当天数据存在,则分别打印阳历和农历日期

输出格式

  • 阳历格式:阳历 {day['solar_day']} 号
  • 农历格式:农历 {day['lunar_day']} 号

示例输出

import datetime
import lunardate

# Debug import
print(f"lunardate version: {lunardate.__version__ if hasattr(lunardate, '__version__') else 'unknown'}")
print(f"lunardate dir: {dir(lunardate.LunarDate)}")

class LunarSolarCalendar:
    """阳历农历双历日历生成器"""
    
    # 农历月份和日期的中文表示
    LUNAR_MONTHS = {
        1: '正月', 2: '二月', 3: '三月', 4: '四月', 
        5: '五月', 6: '六月', 7: '七月', 8: '八月',
        9: '九月', 10: '十月', 11: '冬月', 12: '腊月'
    }
    
    LUNAR_DAYS = {
        1: '初一', 2: '初二', 3: '初三', 4: '初四', 5: '初五',
        6: '初六', 7: '初七', 8: '初八', 9: '初九', 10: '初十',
        11: '十一', 12: '十二', 13: '十三', 14: '十四', 15: '十五',
        16: '十六', 17: '十七', 18: '十八', 19: '十九', 20: '二十',
        21: '廿一', 22: '廿二', 23: '廿三', 24: '廿四', 25: '廿五',
        26: '廿六', 27: '廿七', 28: '廿八', 29: '廿九', 30: '三十'
    }

    def __init__(self, year: int, month: int, day: int = None):
        """
        初始化日历对象
        :param year: 年份(大于0的整数)
        :param month: 月份(1-12的整数)
        :param day: 日期(1-31的整数,可选)
        """
        self._validate_input(year, month, day)
        self.year = year
        self.month = month
        self.day = day
        self._solar_days = self._get_month_days()
        self._first_weekday = self._get_first_weekday()

    @staticmethod
    def _validate_input(year, month, day=None):
        """验证输入有效性"""
        if not isinstance(year, int) or year < 1:
            raise ValueError("年份必须为大于0的整数")
        if not isinstance(month, int) or month < 1 or month > 12:
            raise ValueError("月份必须为1-12之间的整数")
        if day is not None:
            if not isinstance(day, int) or day < 1 or day > 31:
                raise ValueError("日期必须为1-31之间的整数")
            # 检查日期是否超过当月最大天数
            max_days = [31,29 if year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) else 28,
                       31,30,31,30,31,31,30,31,30,31][month-1]
            if day > max_days:
                raise ValueError(f"{year}{month}月最大日期为{max_days}日")

    def _get_month_days(self) -> int:
        """获取当月天数"""
        if self.month == 2:
            return 29 if self._is_leap_year() else 28
        return [31,28,31,30,31,30,31,31,30,31,30,31][self.month-1]

    def _is_leap_year(self) -> bool:
        """判断是否为闰年"""
        return self.year % 4 == 0 and (self.year % 100 != 0 or self.year % 400 == 0)

    def _get_first_weekday(self) -> int:
        """获取当月第一天星期几(周一到周日对应0-6)"""
        return datetime.date(self.year, self.month, 1).weekday()

    def _get_lunar_str(self, solar_date: datetime.date) -> str:
        """获取农历日期字符串"""
        lunar = lunardate.LunarDate.fromSolarDate(solar_date.year, solar_date.month, solar_date.day)
        month_str = (
            f"闰{self.LUNAR_MONTHS[lunar.month]}" 
            if lunar.isLeapMonth 
            else self.LUNAR_MONTHS[lunar.month]
        )
        return f"{month_str}{self.LUNAR_DAYS[lunar.day]}" if lunar.day == 1 else self.LUNAR_DAYS[lunar.day]

    def generate(self) -> dict:
        """
        生成日历数据
        :return: 包含完整日历数据的字典结构
        """
        calendar_matrix = []
        current_day = 1
        
        # 生成每周数据
        for week_num in range(6):
            week = []
            for weekday in range(7):
                # 计算当前格子的实际位置
                pos = week_num * 7 + weekday
                if pos < self._first_weekday or current_day > self._solar_days:
                    week.append(None)
                else:
                    date = datetime.date(self.year, self.month, current_day)
                    week.append({
                        "solar_day": current_day,
                        "lunar_day": self._get_lunar_str(date),
                        "is_current_month": True,
                        "weekday": weekday,
                        "date": date.isoformat(),
                        "is_selected": self.day == current_day if self.day is not None else False
                    })
                    current_day += 1
            calendar_matrix.append(week)
        
        # 添加元数据
        return {
            "year": self.year,
            "month": self.month,
            "day": self.day,
            "total_days": self._solar_days,
            "weeks": calendar_matrix,
            "lunar_month": self._get_lunar_month_str()
        }

    def _get_lunar_month_str(self) -> str:
        """获取农历月份描述"""
        try:
            lunar = lunardate.LunarDate.fromSolarDate(self.year, self.month, 1)
            return (
                f"闰{self.LUNAR_MONTHS[lunar.month]}" 
                if lunar.isLeapMonth 
                else self.LUNAR_MONTHS[lunar.month]
            )
        except:
            return ""

# 使用示例
if __name__ == "__main__":
    # 创建2025年3月日历,并选中15日
    calendar = LunarSolarCalendar(2025, 3, 15)
    data = calendar.generate()
    
    # 打印日历标题
    print(f"\n{data['year']}{data['month']}月(农历{data['lunar_month']})")
    print("周一  周二  周三  周四  周五  周六  周日")
    print("-" * 42)
    
    # 打印日历内容
    for week in data["weeks"]:
        # 打印阳历日期
        solar_line = ""
        lunar_line = ""
        for day in week:
            if day:
                solar_line += f"{day['solar_day']:4d}  "
                lunar_line += f"{day['lunar_day']:<6}"
            else:
                solar_line += "     "
                lunar_line += "      "
        print(solar_line)
        print(lunar_line)
        print()


http://www.kler.cn/a/589193.html

相关文章:

  • .gitignore 文件用于 Git 应忽略的文件夹的格式
  • SNX币合规交易突破 XBIT去中心化交易所引领DEX安全新范式
  • Notepad++插件:快捷选择成对括号之间的内容
  • 【SpringMVC】常用注解:@RequestHeader
  • WEB UI自动化测试中,元素定位的八大定位方式详解
  • docker,centos容器开机启动程序
  • 手搓排列型枚举递归搜索树 全排列问题(dfs)
  • 南邮大一统计学想转码,考研还是就业?如何避免就业被卡?转专业难度大吗?是CC++或Java?
  • 深度学习多模态人脸情绪识别:从理论到实践
  • 提升fcp
  • “Ubuntu禁止root用户通过SSH直接登录”问题的解决
  • docker容器导出导入
  • soulip属地怎么不是我当前的位置
  • 【开原宝藏】30天学会CSS - DAY1 第一课
  • 前端缓存接口数据
  • 4、linux c 进程
  • Django系列教程(8)——函数视图及通用类视图
  • 仿“东方甄选”直播商城小程序运营平台
  • STC89C52单片机学习——第20节: [8-2]串口向电脑发送数据电脑通过串口控制LED
  • 防爆手机如何突破“安全与效率“悖论?解析AORO M8的双驱动创新