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

Python判断给定日期是否恰好为一个月前及边界问题修复方案

自然月前推校验规则实现

需求说明

判断给定日期是否恰好是今日的一个月前,按自然月对齐日度,而非间隔固定30天,例如今日为2021年11月1日,则一个月前应为2021年10月1日。

原有代码问题

原有实现逻辑如下:

today = fields.Date.from_string(fields.Date.today())
if today.month == 1:
    one_month_ago = today.replace(year=today.year - 1, month=12)
else:
    extra_days = 0
    while True:
        try:
            one_month_ago = today.replace(month=today.month - 1, day=today.day - 
                      extra_days)
            break
        except ValueError:
            extra_days += 1
if one_month_ago == given_date:
    # do something
else:
    # do something

该代码仅覆盖了常规场景,存在两类边界问题:

  • 给定日期为2021年3月31日、今日为2021年4月30日时,原有逻辑从4月30日前推只能得到3月30日,无法匹配3月31日的给定日期
  • 1月29日-31日对应2月无对应日期的场景下,判断结果不符合预期

优化实现

方案1:依赖dateutil库(推荐)

直接使用时间偏移工具类同时覆盖正反校验逻辑,代码简洁易维护:

from dateutil.relativedelta import relativedelta

today = fields.Date.today()
# 同时覆盖常规场景和月末边界场景
is_match = (today + relativedelta(months=-1) == given_date) or (given_date + relativedelta(months=1) == today)

if is_match:
    # 符合条件的业务逻辑
    pass
else:
    # 不符合条件的业务逻辑
    pass

方案2:无第三方依赖实现

如果不能引入额外依赖,可以通过原生日期操作实现边界场景兼容:

def is_exact_one_month_ago(given_date, today):
    # 校验常规场景:今日减1个月等于给定日期
    prev_year = today.year - 1 if today.month == 1 else today.year
    prev_month = 12 if today.month == 1 else today.month - 1
    try:
        if today.replace(year=prev_year, month=prev_month) == given_date:
            return True
    except ValueError:
        pass
    
    # 校验月末边界场景:给定日期是当月最后一天,且加1个月后的月末等于今日
    # 计算给定日期当月最后一天
    given_month_last = given_date
    while True:
        try:
            given_month_last = given_month_last.replace(day=given_month_last.day + 1)
        except ValueError:
            break
    # 计算给定日期加1个月后的月末
    next_year = given_date.year + 1 if given_date.month == 12 else given_date.year
    next_month = 1 if given_date.month == 12 else given_date.month + 1
    next_month_last = given_date.replace(year=next_year, month=next_month, day=1)
    while True:
        try:
            next_month_last = next_month_last.replace(day=next_month_last.day + 1)
        except ValueError:
            break
    
    return given_date == given_month_last and next_month_last == today

# 调用示例
today = fields.Date.from_string(fields.Date.today())
if is_exact_one_month_ago(given_date, today):
    # 符合条件的业务逻辑
    pass
else:
    # 不符合条件的业务逻辑
    pass

内容的提问来源于stack exchange,提问作者Faizan Ahmad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 10:18:00