Как пройти в прошлую пятницу?
Код ниже должен вернуться в прошлую пятницу, 16:00:00. Но он возвращается в пятницу предыдущей недели. Как это исправить?
now = datetime.datetime.now()
test = (now - datetime.timedelta(days=now.weekday()) + timedelta(days=4, weeks=-1))
test = test.replace(hour=16,minute=0,second=0,microsecond=0)
Upd. Сейчас я использую следующий подход - это лучший?
now = datetime.datetime.now()
if datetime.datetime.now().weekday() > 4:
test = (now - datetime.timedelta(days=now.weekday()) + timedelta(days=4))
else:
test = (now - datetime.timedelta(days=now.weekday()) + timedelta(days=4, weeks=-1))
test = test.replace(hour=16,minute=0,second=0,microsecond=0)
UPD2. Просто чтобы привести пример. Предположим, что сегодня 5 октября 2012 года. Если текущее время равно или меньше 16:00, оно должно вернуться 28 сентября 2012 года, в противном случае - 5 октября 2012 года.
6 ответов
Как и в связанном вопросе, вам нужно использовать datetime.date
объекты вместо datetime.datetime
, Чтобы получить datetime.datetime
в конце концов, вы можете использовать datetime.datetime.combine()
:
import datetime
current_time = datetime.datetime.now()
# get friday, one week ago, at 16 o'clock
last_friday = (current_time.date()
- datetime.timedelta(days=current_time.weekday())
+ datetime.timedelta(days=4, weeks=-1))
last_friday_at_16 = datetime.datetime.combine(last_friday, datetime.time(16))
# if today is also friday, and after 16 o'clock, change to the current date
one_week = datetime.timedelta(weeks=1)
if current_time - last_friday_at_16 >= one_week:
last_friday_at_16 += one_week
dateutil
библиотека отлично подходит для таких вещей:
>>> from datetime import datetime
>>> from dateutil.relativedelta import relativedelta, FR
>>> datetime.now() + relativedelta(weekday=FR(-1))
datetime.datetime(2012, 9, 28, 9, 42, 48, 156867)
Самое простое решение без зависимости:
from datetime import datetime, timedelta
def get_last_friday():
now = datetime.now()
closest_friday = now + timedelta(days=(4 - now.weekday()))
return (closest_friday if closest_friday < now
else closest_friday - timedelta(days=7))
Это было заимствовано у Джона Клемента, но это полное решение:
>>> from datetime import datetime
>>> from dateutil.relativedelta import relativedelta, FR
>>> lastFriday = datetime.now() + relativedelta(weekday=FR(-1))
>>> lastFriday.replace(hour=16,minute=0,second=0,microsecond=0)
datetime.datetime(2012, 9, 28, 16, 0, 0, 0)
Принцип тот же, что и в вашем другом вопросе.
Получить пятницу текущей недели и, если мы позже, вычтите одну неделю.
import datetime
from datetime import timedelta
now = datetime.datetime.now()
today = now.replace(hour=16,minute=0,second=0,microsecond=0)
sow = (today - datetime.timedelta(days=now.weekday()))
this_friday = sow + timedelta(days=4)
if now > this_friday:
test = this_friday
else:
test = this_friday + timedelta(weeks=-1)
Может быть хромым, но для меня самое простое. Получите последний день текущего месяца и начните проверку в цикле (который не будет стоить ничего, так как максимальное количество циклов до того, как будет найдена последняя пятница - 7) для пятницы. если последний день не является пятницей декремента и чека накануне.
import calendar
from datetime import datetime, date
def main():
year = datetime.today().year
month = datetime.today().month
x = calendar.monthrange(year,month)
lastday = x[1]
while True:
z = calendar.weekday(year, month, lastday)
if z != 4:
lastday -= 1
else:
print(date(year,month,lastday))
break
if __name__ == "__main__":
main()