You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python的calendar库高亮多个日期?

问题:Python calendar库高亮多个日期实现问题

我用Python的calendar库打印日历,想高亮日历中的多个日期,但实现遇到困难。以下是我的代码:

from datetime import datetime
import calendar
from time import strptime

COL_BLUE = '\033[96m'
COL_END = '\033[0m'

dates_dict = {2023: {'Jul':[16, 18, 31],'Aug':[1]}}
curr_year = datetime.now().year
curr_month = datetime.now().month
curr_day = datetime.now().day

#ANSI escape sequences for colors
colored_day = COL_BLUE + str(curr_day) + COL_END

calendar_output = (calendar.month(curr_year, curr_month))

#finds the first occurrence of today's date and changes its color 
highlighted_day = calendar_output.replace(str(curr_day), colored_day, 1)

print(highlighted_day)


for year, months_of_the_year in dates_dict.items():
  print(year)
  for month, dates_list in months_of_the_year.items():    
    month_no = strptime(month.title(),'%b').tm_mon
    print(month, month_no)
    calendar_output = (calendar.month(year, month_no))
    print(dates_list)
    for dates in dates_list:
      colored_day = COL_BLUE + str(dates) + COL_END

      calendar_output = (calendar.month(curr_year, curr_month))   

      highlighted_day = calendar_output.replace(str(dates), colored_day, 1)
    print(highlighted_day)

当前输出与理想输出对比:左侧是当前仅能单次高亮或错误显示的结果,右侧是期望的可同时高亮多个目标日期的日历效果。


问题分析与修正

原代码核心问题:

  • 循环处理目标日期时,错误重复生成当前年月的日历,而非dates_dict中指定的目标年月,导致始终修改的是当前月日历
  • 每次循环都会重置calendar_output,之前的高亮操作被覆盖,最终仅显示最后一个日期的高亮
  • 简单字符串替换存在误匹配风险(比如日期1会被替换到11的第一个字符位置)

修正后的代码:

from datetime import datetime
import calendar
from time import strptime

COL_BLUE = '\033[96m'
COL_END = '\033[0m'

dates_dict = {2023: {'Jul': [16, 18, 31], 'Aug': [1]}}
curr_year = datetime.now().year
curr_month = datetime.now().month
curr_day = datetime.now().day

# 通用高亮日期函数:避免误匹配,支持多日期高亮
def highlight_dates(cal_text, target_dates):
    lines = cal_text.split('\n')
    for line_idx in range(len(lines)):
        line = lines[line_idx]
        for day in target_dates:
            day_str = str(day)
            # 处理一位数日期(日历中一位数日期前有空格,占两位宽度)
            if day < 10:
                match_str = f' {day_str}'
                pos = line.find(match_str)
                if pos != -1:
                    line = line[:pos] + f' {COL_BLUE}{day_str}{COL_END}' + line[pos+3:]
            # 处理两位数日期
            else:
                pos = line.find(day_str)
                # 确保匹配的是独立日期(前后为空格或行首尾)
                if pos != -1 and (pos == 0 or line[pos-1] == ' ') and (pos+2 >= len(line) or line[pos+2] == ' '):
                    line = line[:pos] + f'{COL_BLUE}{day_str}{COL_END}' + line[pos+2:]
        lines[line_idx] = line
    return '\n'.join(lines)

# 处理当前月日历,高亮今日
current_cal = calendar.month(curr_year, curr_month)
highlighted_current = highlight_dates(current_cal, [curr_day])
print(highlighted_current)

# 处理dates_dict中的目标日期
for year, months in dates_dict.items():
    print(year)
    for month_name, target_days in months.items():
        month_num = strptime(month_name.title(), '%b').tm_mon
        print(f'{month_name} ({month_num})')
        # 生成目标年月的日历
        target_cal = calendar.month(year, month_num)
        # 批量高亮所有目标日期
        highlighted_cal = highlight_dates(target_cal, target_days)
        print(highlighted_cal)

关键修改说明:

  • 新增highlight_dates函数,按行拆分日历文本,通过匹配日期的前后空格避免误替换
  • 区分处理一位数和两位数日期的显示格式,适配calendar库的输出规则
  • 循环中基于目标年月的日历逐步高亮所有日期,不再重置已修改的内容
  • 分离当前月与目标年月的日历处理逻辑,避免混淆

内容的提问来源于stack exchange,提问作者3kstc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 12:03:14