如何在 Python 中将日期范围划分为月份?

新手上路,请多包涵

我有以下日期范围:

 begin: 2018-02-15
end: 2018-04-23

我想实现以下目标:

 ["2018-02-15 - 2018-02-28", "2018-03-01 - 2018-03-31", "2018-04-01 - 2018-04-23"]

本质上,我想将给定的日期范围划分为几个月。我想不出在 Python 中完成此操作的方法。

我已经考虑了 这里 的解决方案,但是,这会根据指定的时间间隔拆分日期范围。我希望能够动态拆分日期范围。

因此,给定从 2018 年 2 月 15 日到 2018 年 4 月 23 日的日期范围,我希望能够获得该范围内的各个月份,如下所示:

  • 2018年2月15日至2018年2月28日
  • 2018年3月1日至2018年3月31日
  • 2018年4月1日至2018年4月23日

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

阅读 682
2 个回答

在一个循环中;从第一天开始,不断增加一天,直到到达结束日期;每当月份更改时保存日期。

 import datetime
begin = '2018-02-15'
end = '2018-04-23'

dt_start = datetime.datetime.strptime(begin, '%Y-%m-%d')
dt_end = datetime.datetime.strptime(end, '%Y-%m-%d')
one_day = datetime.timedelta(1)
start_dates = [dt_start]
end_dates = []
today = dt_start
while today <= dt_end:
    #print(today)
    tomorrow = today + one_day
    if tomorrow.month != today.month:
        start_dates.append(tomorrow)
        end_dates.append(today)
    today = tomorrow

end_dates.append(dt_end)

out_fmt = '%d %B %Y'
for start, end in zip(start_dates,end_dates):
    print('{} to {}'.format(start.strftime(out_fmt), end.strftime(out_fmt)))

结果:

 >>>
15 February 2018 to 28 February 2018
01 March 2018 to 31 March 2018
01 April 2018 to 23 April 2018
>>>


您可能会想出一种方法来获取开始日期和结束日期之间的月份范围;为每个月份的第一天创建一个日期时间对象,存储它们和它们之前的日子。但是跨越年份变化的日期可能会有问题。

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

要使用方便的日期 _对象_,请始终使用标准模块 datetime 。这会包装您的字符串格式日期,并允许更轻松的计算以及定制的输出格式。

不幸的是,它似乎遗漏了一条重要信息:给定年份的每个月的 最后 一天(这对于 Februari 来说是必需的)。还有一个附加模块 calendar 返回 一个月的最后一天,但是因为这就是你所需要的,并且有一个简单的 datetime 基于函数做同样的事情,我选择了后者。

有了它,您可以设置任何 begin 日期并将其附加到您的列表中,连同该月的最后一天,然后将 begin 设置为 下个月 的第一天并继续直到您通过 end

警告/微调:我意识到如果 beginend 都落在 一个月内,它就不会工作。这需要临时检查,所以我将初始的 while begin < end 更改为 while True 并将跨越结束日期的检查移动到单独的行中。

此外, 跨年 需要再次单独测试,因为声明 month+1 将在 12 月失败。

 import datetime

# borrowed from https://stackoverflow.com/a/13565185
# as noted there, the calendar module has a function of its own
def last_day_of_month(any_day):
    next_month = any_day.replace(day=28) + datetime.timedelta(days=4)  # this will never fail
    return next_month - datetime.timedelta(days=next_month.day)

begin = "2018-02-15"
end = "2018-04-23"

def monthlist(begin,end):
    begin = datetime.datetime.strptime(begin, "%Y-%m-%d")
    end = datetime.datetime.strptime(end, "%Y-%m-%d")

    result = []
    while True:
        if begin.month == 12:
            next_month = begin.replace(year=begin.year+1,month=1, day=1)
        else:
            next_month = begin.replace(month=begin.month+1, day=1)
        if next_month > end:
            break
        result.append ([begin.strftime("%Y-%m-%d"),last_day_of_month(begin).strftime("%Y-%m-%d")])
        begin = next_month
    result.append ([begin.strftime("%Y-%m-%d"),end.strftime("%Y-%m-%d")])
    return result

date_list = monthlist(begin,end)
print (date_list)

结果是

[ ['2018-02-15', '2018-02-28'],
  ['2018-03-01', '2018-03-31'],
  ['2018-04-01', '2018-04-23'] ]

(为了便于阅读,略有格式化)

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

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题