Python计算两个日期相差月数的实现方案

宋时安
宋时安
发布时间:2026-10-13| 3人浏览过
原创

本文针对Python标准库及dateutil模块在计算两个日期相差月数时存在的精度或功能缺失问题,提供了一套自定义解决方案。通过对比rrule模块的测试结果,展示了手动处理大小月及闰年差异的方法,最终实现返回整数月与小数月的精确计算结果。

近期因业务需求,需要计算两个日期之间相隔的月数。经过搜索发现,Python中似乎缺乏直接计算两个日期月数差的内置模块。相比之下,Java、C#等语言通常提供如(date1-date2).months这样的现成方法。对此结果感到意外,同时也觉得Python的日期处理模块在实际使用中并不够便捷。

需要说明的是,datetime、calendar以及dateutil等常见模块均已被尝试,但未能直接满足需求。其中部分模块甚至存在计算错误。具体而言,datetime.timedelta仅支持计算日、时、分、秒的差值,对年和月的处理并不支持。网络上虽然存在大量相关讨论,但往往难以直接适用。

网上流传较广的dateutil.rrule示例,经实际测试发现结果存在偏差,具体测试情况如下所示:

import datetime

from dateutil import rrule

d1 = datetime.date(2016, 2, 29)
d2 = datetime.date(2019, 3, 31)

months = rrule.rrule(rrule.MONTHLY, dtstart=d1, until=d2).count()

print(f"months={months}")

面对上述测试结果,该方案显然不可靠。

因此,下面提供一段自行编写的代码以实现准确计算:

该代码执行后,将返回包含整数月和小数月的结果元组。

import datetime

import calendar as c



d1 = datetime.date(2016, 2, 29)

d2 = datetime.date(2019, 3, 31)



def calmonths(startdate, enddate):

# 计算两个日期相隔月差

samemonthdate = None

try:

samemonthdate = datetime.date(enddate.year, enddate.month,

startdate.day)

except Exception as e:

print(e)

samemonthdate = datetime.date(enddate.year, enddate.month,

c.monthrange(enddate.year,

enddate.month)[1])


holdmonths = 0

decimalmonth = 0.0

if samemonthdate > enddate:

premanthdate = None

try:

premanthdate = datetime.date(enddate.year, enddate.month - 1,

startdate.day)

except Exception as e:

print(e)

premanthdate = datetime.date(enddate.year, enddate.month - 1,

c.monthrange(

enddate.year,

enddate.month - 1)[1])

currmonthdays = (samemonthdate - premanthdate).days

holdmonths = (premanthdate.year - startdate.year

) * 12 + premanthdate.month - startdate.month

decimalmonth = (enddate - premanthdate).days / currmonthdays


elif samemonthdate < enddate:

nextmonthdate = None

try:

nextmonthdate = datetime.date(enddate.year, enddate.month + 1,

startdate.day)

except Exception as e:

nextmonthdate = datetime.date(enddate.year, enddate.month + 1,

c.monthrange(

enddate.year,

enddate.month + 1)[1])

currmonthdays = (nextmonthdate - samemonthdate).days

holdmonths = (samemonthdate.year - startdate.year

) * 12 + samemonthdate.month - startdate.month

decimalmonth = (enddate - samemonthdate).days / currmonthdays


else:

holdmonths = (enddate.year - startdate.year

) * 12 + enddate.month - startdate.month


return holdmonths, decimalmonth


months = calmonths(d1, d2)


print(f"months={months}")

以上即为本文分享的全部内容,希望能为读者在相关场景下的学习与应用提供参考,欢迎继续支持。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。