2011-08-10 27 views
28

可能重复:
Best way to find the months between two dates (in python)的Python:以月2个日期时间差

我想知道我怎么能有个确切的数量有区别的:

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) 

我想知道个月的确切数量,在这种情况下,它应该返回,而不是6(因为小时)

+0

这个问题已经在这里找到答案:http://stackoverflow.com/questions/4039879 /最好的方式来查找python – Dan

+0

不是日期时间与几小时 –

+1

一旦你决定什么“确切的月份数”意味着这将更容易回答。一个月不是固定的持续时间;它可以从28天到31天不等。 1月1日和2月1日比2月1日和3月1日更远;你是否称为“正好一个月”? –

回答

22

使用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 
5

这样做的好处这种方式是有几个模块依赖性和不循环 - 可以通过直接计算找到月份。

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 
52

您可以使用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) 
+5

虽然:'relativedelta.relativedelta(日期(2015,9,30),日期(2015,10,1))。months'产生0这是正确的,但可能不反映预期的结果,如果你想知道月份是不同的 – ezdazuzena

13

只有你自己知道,你必须满足的要求,但事实证明,有这两个日期之间183天和43200 SI秒凸显固有的主观性决定多少个月是“真的”是。

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

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

这些决定会影响答案,您似乎期望的算法会为您提供某些接近这些边界的输入日期。

在我看来,它更直观的考虑个月的时间原子单位为了这个目的而使用这个公式:(date2.year - date1.year) * 12 + (date2.month - date1.month)

+0

这是高效的,很好的解释,为我的问题工作。 –