在实际的开发中,我们经常要设计一些工具类,对于时间来说,有时候需要将其处理成时间段。
例如,对于2024年08月01日
到2024年08月16日
的时间段,我们如何将其处理成时间段[2024-08-01, 2024-08-03], [2024-08-04, 2024-08-10], [2024-08-11, 2024-08-16]
。如下表所示:
周日 | 周一 | 周二 | 周三 | 周四 | 周五 | 周六 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 |
这里,我们采用迭代就可以实现,通过计算每个阶段的开始日期和结束日期,先根据当前阶段开始日期计算当周周日的日期,再判断总的结束日期是否在周日前,如果在,则将第一段时间的结束日期确定为总的结束日期。如果在超出了周日,则将周日定为该阶段的结束日期,以此类推。
这里我们用到几个函数
datetime.datetime.strptime
:将字符串转为日期对象
datetime.timedelta
: 计算当前日期前推或后推后的日期。
datetime.weekday
: 计算当前日期是星期几,其中0代表周末,1代表周一,2代表周二,以此类推。
def split_date_range(start_date_input: str, end_date_input: str) -> list:
# 将输入的日期字符串转换为日期对象
start_date = datetime.datetime.strptime(start_date_input, '%Y-%m-%d')
end_date = datetime.datetime.strptime(end_date_input, '%Y-%m-%d')
periods = []
current_date = start_date
while current_date <= end_date:
sunday = current_date + datetime.timedelta(days=(6 - current_date.weekday()))
if sunday <= end_date:
periods.append((current_date.strftime('%Y-%m-%d'), sunday.strftime('%Y-%m-%d')))
else:
periods.append((current_date.strftime('%Y-%m-%d'), end_date.strftime('%Y-%m-%d')))
break
# 更新当前日期为周的结束日期的下一天,以便开始下一个周期
current_date = sunday + datetime.timedelta(days=1)
return periods
这样我们就可以推算每一周的时间阶段了
如果我们只要工作日的时间阶段呢?应该如何修改这段程序,可以把周期的结束时间调整为周五的日期,也就是周日往前推2天。
周日 | 周一 | 周二 | 周三 | 周四 | 周五 | 周六 |
---|---|---|---|---|---|---|
1 | 2 | |||||
5 | 6 | 7 | 8 | 9 | ||
12 | 13 | 14 | 15 | 16 |
程序如下:
def split_date_range(start_date_input: str, end_date_input: str) -> list:
start_date = datetime.datetime.strptime(start_date_input, '%Y-%m-%d')
end_date = datetime.datetime.strptime(end_date_input, '%Y-%m-%d')
periods = []
current_date = start_date
while current_date <= end_date:
sunday = current_date + datetime.timedelta(days=(6 - current_date.weekday()))
friday = current_date + datetime.timedelta(days=(6 - 2 - current_date.weekday()))
if friday <= end_date:
periods.append((current_date.strftime('%Y-%m-%d'), friday.strftime('%Y-%m-%d')))
else:
periods.append((current_date.strftime('%Y-%m-%d'), end_date.strftime('%Y-%m-%d')))
break
current_date = sunday + datetime.timedelta(days=1)
return periods
就会自动把周六日的时间去掉,得到的时间就变为了: