问题:
你需要查找星期中某一天最后出现的日期,比如星期五。
解决方案:
Python的datetime模块中有工具函数和类可以帮助你执行这样的计算。下面是对类似这样的问题的一个通用解决方案:
from datetime import datetime, timedelta
weekdays = [
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday'
]
def get_previous_byday(dayname, start_date=None):
if start_date is None:
start_date = datetime.today()
day_num = start_date.weekday()
day_num_target = weekdays.index(dayname)
day_ago = (7 + day_num - day_num_target) % 7
if day_ago == 0:
day_ago = 7
target_date = start_date - timedelta(days=day_ago)
return target_date
print(datetime.today()) # ->2022-03-14 17:48:44.521281
print(get_previous_byday('Monday')) # ->2022-03-07 17:48:44.521281
print(get_previous_byday('Tuesday')) # ->2022-03-08 17:48:44.521281
print(get_previous_byday('Friday')) # ->2022-03-11 17:48:44.521281
可选的start_date参数可以由另外一个datetime实例来提供。比如:
print(get_previous_byday('Sunday',datetime(2022,5,5)))# ->2022-05-01 00:00:00
讨论:
上面的算法原理是这样的,先将开始日期和目标日期映射到星期数组的位置上(星期一的索引为0),然后通过模运算计算出日期要经过多少天才能到达开始日期。然后用开始日期减去那个时间差即得到结果日期。
如果你要像这样执行大量的日期计算的话,你最好安装第三方包python-dateutil来替代。比如,下面是使用dateutile模块中的relativedelta()函数执行同样的计算:
from datetime import datetime
from dateutil.relativedelta import relativedelta
from dateutil.rrule import *
d=datetime.now()
print(d) # ->2022-03-15 09:59:43.523158
print(d+relativedelta(weekday=FR))# ->2022-03-18 09:59:43.523158
print(d+relativedelta(weekday=FR(-1))) # ->2022-03-11 09:59:43.523158