计算两个datetime.date()日期之间的年份和月份差异

9

我希望计算两个datetime.date()日期之间的年份和月份差异。

例如:

d1 = date(2001,5,1)  
d2 = date(2012,1,1)   
d3 = date(2001,1,1)   
d4 = date(2012,5,1)   


diff1 = d2 - d1  
diff2 = d4 - d3

期望的结果:

diff1 == 10 years & 8 months. 
diff2 == 11 years & 4 months.

谢谢。
3个回答

27

如果您能够安装出色的dateutil包,您可以这样做:

>>> from dateutil import relativedelta as rdelta
>>> from datetime import date
>>> d1 = date(2001,5,1)
>>> d2 = date(2012,1,1)
>>> rd = rdelta.relativedelta(d2,d1)
>>> "{0.years} years and {0.months} months".format(rd)
'10 years and 8 months'

谢谢Burhan,我尝试了你的解决方案,它似乎按预期/准确地计算了年份和月份。感谢你的支持。 - Tom Fin

11
在Python中,两个datetime.date对象相减会得到一个datetime.timedelta对象,该对象具有days属性。
将天数差转换为年份和月份并没有明确定义;如果您将一年定义为365天,一个月定义为30天,则可以使用以下方法:
years, remainder = divmod(diff1.days, 365)
months = remainder // 30

或者,您可以定义平均年份和月份长度为(稍微)更准确:

avgyear = 365.2425        # pedants definition of a year length with leap years
avgmonth = 365.2425/12.0  # even leap years have 12 months
years, remainder = divmod(diff1.days, avgyear)
years, months = int(years), int(remainder // avgmonth)

使用后一种计算方法,您的第二个差异为11年零3个月。

完全同意您需要定义“1个月的差异”是什么意思。但是,如果非常挑剔,将其除以约30.45可能会得到更好的结果,因为平均而言,一个月的长度大约是这样长,因此在长时间内更准确。 - Stu Cox
@StuCox: 365/12.0 实际上是 30.416666666666668。是的,您可以将该值存储为平均月份长度。 - Martijn Pieters
不要忘记闰年...(每4年一次,但如果可被100整除,则不是,除非也可被400整除),因此每年365.2425天,除以12 = 30.436875。这太荒谬了。 - Stu Cox
@TomFin:说实话,我认为relativedelta解决方案也是最好的! - Martijn Pieters
在Python 3中:years, remainder = divmod(abs(diff1), YEAR); months = remainder // (YEAR / 12),其中YEAR = timedelta(365.2425)。如果结果是整数年和月,则我们可以忽略每四年一次的一天误差(对于year=365)。 - jfs
显示剩余2条评论

1

timedelta对象没有关于月份的信息,你最好直接计算年份和月份

>>> d2.year - d1.year + (d2.month - d1.month)/12,  (d2.month - d1.month)%12
(10, 8)
>>> d4.year - d3.year + (d4.month - d3.month)/12,  (d4.month - d3.month)%12
(11, 4)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接