查找两个日期之间的月份的最佳方法

新手上路,请多包涵

我需要能够在 python 中准确地找到两个日期之间的月份。我有一个可行的解决方案,但它不是很好(如优雅)或快速。

 dateRange = [datetime.strptime(dateRanges[0], "%Y-%m-%d"), datetime.strptime(dateRanges[1], "%Y-%m-%d")]
months = []

tmpTime = dateRange[0]
oneWeek = timedelta(weeks=1)
tmpTime = tmpTime.replace(day=1)
dateRange[0] = tmpTime
dateRange[1] = dateRange[1].replace(day=1)
lastMonth = tmpTime.month
months.append(tmpTime)
while tmpTime < dateRange[1]:
    if lastMonth != 12:
        while tmpTime.month <= lastMonth:
            tmpTime += oneWeek
        tmpTime = tmpTime.replace(day=1)
        months.append(tmpTime)
        lastMonth = tmpTime.month

    else:
        while tmpTime.month >= lastMonth:
            tmpTime += oneWeek
        tmpTime = tmpTime.replace(day=1)
        months.append(tmpTime)
        lastMonth = tmpTime.month

所以只是为了解释一下,我在这里所做的是获取两个日期并将它们从 iso 格式转换为 python datetime 对象。然后我循环添加一个星期到开始日期时间对象并检查月份的数值是否更大(除非月份是十二月然后它检查日期是否更小),如果该值更大我将它附加到列表几个月并不断循环直到我到达我的结束日期。

它工作得很好,只是看起来不是一个好方法……

原文由 Joshkunz 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 447
2 个回答

2018-04-20 更新: 似乎 OP @Joshkunz 要求查找两个日期之间有 _哪些月份_,而不是两个日期之间有“多少个月”。所以我不确定为什么@JohnLaRooy 被点赞超过 100 次。 @Joshkunz 在原始问题下的评论中表示他想要实际日期 [或月份],而不是找到 _总月数_。

所以看起来问题是想要的,在两个日期之间 2018-04-112018-06-01

 Apr 2018, May 2018, June 2018

如果它介于 2014-04-112018-06-01 之间怎么办?那么答案就是

Apr 2014, May 2014, ..., Dec 2014, Jan 2015, ..., Jan 2018, ..., June 2018

所以这就是为什么我多年前有以下伪代码的原因。它只是建议将两个月作为终点并循环遍历它们,一次增加一个月。 @Joshkunz 提到他想要“月份”,他还提到他想要“日期”,但不知道确切的情况,很难写出准确的代码,但想法是使用一个简单的循环来遍历端点,并且一个月递增一次。

8年前的2010年的答案:

如果增加一周,那么它大约可以完成所需工作量的 4.35 倍。为什么不只是:

 1. get start date in array of integer, set it to i: [2008, 3, 12],
       and change it to [2008, 3, 1]
2. get end date in array: [2010, 10, 26]
3. add the date to your result by parsing i
       increment the month in i
       if month is >= 13, then set it to 1, and increment the year by 1
   until either the year in i is > year in end_date,
           or (year in i == year in end_date and month in i > month in end_date)

现在只是伪代码,还没有测试,但我认为沿着同一条线的想法会奏效。

原文由 nonopolarity 发布,翻译遵循 CC BY-SA 3.0 许可协议

从定义一些测试用例开始,然后你会发现这个函数非常简单,不需要循环

from datetime import datetime

def diff_month(d1, d2):
    return (d1.year - d2.year) * 12 + d1.month - d2.month

assert diff_month(datetime(2010,10,1), datetime(2010,9,1)) == 1
assert diff_month(datetime(2010,10,1), datetime(2009,10,1)) == 12
assert diff_month(datetime(2010,10,1), datetime(2009,11,1)) == 11
assert diff_month(datetime(2010,10,1), datetime(2009,8,1)) == 14

你应该在你的问题中添加一些测试用例,因为有很多潜在的角落案例要涵盖 - 有不止一种方法来定义两个日期之间的月数。

原文由 John La Rooy 发布,翻译遵循 CC BY-SA 3.0 许可协议

推荐问题