Python:两个日期时间之间的月份差异

44
我想知道如何计算这个时间差的准确月数:
可能重复:
在Python中查找两个日期之间的月份的最佳方法
date1 = datetime.strptime(str('2011-08-15 12:00:00'), '%Y-%m-%d %H:%M:%S')
date2 = datetime.strptime(str('2012-02-15'), '%Y-%m-%d')

date2-date1的结果为

datetime.timedelta(183, 43200)

我想知道确切的月数,此例中应返回5而不是6(因为小时数)。

这个问题已经在这里得到了回答:https://dev59.com/D2855IYBdhLWcg3w_5qm - Dan
1
一旦您确定“确切的月份数”是什么意思,回答这个问题就会更容易。一个月的持续时间并不是固定的;它可以从28到31天不等。1月1日和2月1日之间的距离比2月1日和3月1日之间的距离更远;您是否都称这两个间隔为“正好1个月”? - Keith Thompson
2
这篇帖子说得太好了!使用dateutil.relativedelta即可计算两个日期之间的月数。 - srodriguex
4个回答

86
你可以使用 python-dateutil 库。
In [4]: from datetime import datetime

In [5]: date1 = datetime.strptime(str('2011-08-15 12:00:00'), '%Y-%m-%d %H:%M:%S')

In [6]: date2 = datetime.strptime(str('2012-02-15'), '%Y-%m-%d')

In [7]: from dateutil import relativedelta

In [8]: r = relativedelta.relativedelta(date1, date2)

In [9]: r
Out[9]: relativedelta(months=-5, days=-30, hours=-12)

9
虽然relativedelta.relativedelta(date(2015, 9, 30), date(2015, 10, 1)).months返回为0是正确的,但如果你想知道这两个日期之间相差几个月可能会得出与预期不符的结果。请注意此点。 - ezdazuzena
2
这对我有用。你只需要计算年数,乘以12再加上月份。 - kryo

29

只有您知道必须满足的要求,但是这两个日期之间有183天和43200个SI秒的事实突显了确定“真正”有多少个月存在固有的主观性。

一个月是30天,还是(365/12)天,或者是((365 * 4 + 1)/ 48)天,等等?

一天总是86400秒吗?还是要计算历史闰秒,或者预测未来日期的闰秒?

这些决策会影响您所需的算法对接近这些边界的某些输入日期给出的答案。

在我看来,为此目的考虑月份作为时间的原子单位并使用以下公式更直观:(date2.year - date1.year) * 12 + (date2.month - date1.month)


3
这很高效并且解释得很清楚,对我的问题有帮助。 - almost a beginner

26

通过使用calendar模块来查找每个月有多少天,你可以简单地计算月份数量。

from calendar import monthrange
from datetime import datetime, timedelta

def monthdelta(d1, d2):
    delta = 0
    while True:
        mdays = monthrange(d1.year, d1.month)[1]
        d1 += timedelta(days=mdays)
        if d1 <= d2:
            delta += 1
        else:
            break
    return delta

6
这种方法的优点是模块依赖性少,且没有循环——可以通过直接计算找到月份。
import datetime as dt

def months_between(date1,date2):
    if date1>date2:
        date1,date2=date2,date1
    m1=date1.year*12+date1.month
    m2=date2.year*12+date2.month
    months=m2-m1
    if date1.day>date2.day:
        months-=1
    elif date1.day==date2.day:
        seconds1=date1.hour*3600+date1.minute+date1.second
        seconds2=date2.hour*3600+date2.minute+date2.second
        if seconds1>seconds2:
            months-=1
    return months

date1 = dt.datetime.strptime('2011-08-15 12:00:00', '%Y-%m-%d %H:%M:%S')
date2 = dt.datetime.strptime('2012-02-15', '%Y-%m-%d')
print(months_between(date1,date2))
# 5

date1 = dt.datetime.strptime('2011-08-15 12:00:00', '%Y-%m-%d %H:%M:%S')
date2 = dt.datetime.strptime('2012-02-15 11:59:00', '%Y-%m-%d %X')
print(months_between(date1,date2))
# 5

date2 = dt.datetime.strptime('2012-02-15 12:00:00', '%Y-%m-%d %X')
print(months_between(date1,date2))
# 6

date2 = dt.datetime.strptime('2012-02-15 12:00:01', '%Y-%m-%d %X')
print(months_between(date1,date2))
# 6

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