如何在两个Python日期时间范围内计算属于给定月份的天数?

时间:2017-11-03 14:28:06

标签: python django python-2.7 datetime

我有两个Python datetime,我想计算这些日期之间的天数,只计算属于我选择的月份的日期。范围可能会重叠多个月/年。

实施例: 如果我有2017-10-29& 2017-11-04我选择计算十月的日子,我得到3(29,30和10月31日)。

我无法找到一种直接的方法来做到这一点所以我认为我将使用datetime.timedelta(days=1) 迭代,并在每天属于的时候增加一个计数我选择的月份。

你知道一种更高效的方法吗?

我正在使用 Python 2.7.10 Django 框架。

3 个答案:

答案 0 :(得分:1)

您可以通过简单地减去两个日期时间对象来区分它们。

因此,我们首先得出两个日期之间的差异。 然后我们使用

生成两者之间的所有日期

gen = (start_date + datetime.timedelta(days = e) for e in range(diff + 1))

由于我们只想要指定日期之间的日期,因此我们应用过滤器。

filter(lambda x : x==10 , gen) 然后我们将它们总结。 最后的代码就是:

diff = start_date - end_date
gen = (start_date + datetime.timedelta(days = e) for e in range(diff + 1))
filtered_dates = filter(
    lambda x : x.month == 10  , 
    gen
)
count = sum(1 for e in filtered_dates)

您也可以使用reduce,但sum()更具可读性。

答案 1 :(得分:1)

迭代这些日子将是最直接的方式。否则,您需要知道给定月份中的天数,并且您需要针对不同场景使用不同的代码:

  1. 指定月份是第一个月的月份
  2. 指定月份是第二个日期的月份
  3. 指定月份介于第一个和第二个日期之间(如果日期超过两个月)
  4. 如果您想支持超过一年的日期,那么您需要输入包含月份年。

    你的例子符合方案#1,我想你可以这样做:

    >>> from datetime import datetime, timedelta
    >>>
    >>> first_date = datetime(2017, 10, 29)
    >>>
    >>> first_day_of_next_month = first_date.replace(month=first_date.month + 1, day=1)
    >>> last_day_of_this_month = first_day_of_next_month - timedelta(1)
    >>> number_of_days_in_this_month = last_day_of_this_month.day
    >>> number_of_days_in_this_month - first_date.day + 1
    3
    

    这就是为什么我建议按照您最初的预期方式实施它,如果存在性能问题,只能转向此。

答案 2 :(得分:0)

实现此目标的一种潜在方法是首先比较您比较的开始日期或结束日期是否与您想要选择的月份相同。

例如:

start = datetime(2017, 10, 29)
end = datetime(2017, 11, 4)

我们创建一个比较日期的函数:

def daysofmonth(start, end, monthsel):
    if start.month == monthsel:
        days = (datetime(start.year, monthsel+1, 1) - start).days
    elif end.month == monthsel:
        days = (end - datetime(end.year, monthsel, 1)).days
    elif not (monthsel > start.month) & (end.month > monthsel):
        return 0
    else:
        days = (datetime(start.year, monthsel+1, 1) - datetime(start.year, monthsel, 1)).days

    return days

因此,在我们的示例中,monthsel提供:

 >>> daysofmonth(start, end, 10)
 >>> 3