Как рассчитать следующую пятницу в 3 часа ночи?
Как вы можете рассчитать следующую пятницу в 3 часа ночи как объект datetime
?
Уточнение:, то есть расчетная дата всегда должна быть больше 7 дней и меньше или равна 14.
Переход с слегка измененной версией Отметить решение:
def _next_weekday(day_of_week=4, time_of_day=datetime.time(hour=3), dt=None):
if dt is None: dt = datetime.datetime.now()
dt += datetime.timedelta(days=7)
if dt.time() < time_of_day: dt = dt.combine(dt.date(), time_of_day)
else: dt = dt.combine(dt.date(), time_of_day) + datetime.timedelta(days=1)
return dt + datetime.timedelta((day_of_week - dt.weekday()) % 7)
Ответы
Ответ 1
Здесь функция и тест соответствуют требованиям OP:
import datetime
_3AM = datetime.time(hour=3)
_FRI = 4 # Monday=0 for weekday()
def next_friday_3am(now):
now += datetime.timedelta(days=7)
if now.time() < _3AM:
now = now.combine(now.date(),_3AM)
else:
now = now.combine(now.date(),_3AM) + datetime.timedelta(days=1)
return now + datetime.timedelta((_FRI - now.weekday()) % 7)
if __name__ == '__main__':
start = datetime.datetime.now()
for i in xrange(7*24*60*60):
now = start + datetime.timedelta(seconds=i)
then = next_friday_3am(now)
assert datetime.timedelta(days=7) < then - now <= datetime.timedelta(days=14)
assert then.weekday() == _FRI
assert then.time() == _3AM
Ответ 2
Если вы установите dateutil, вы можете сделать что-то вроде этого:
import datetime
import dateutil.relativedelta as reldate
def following_friday(dt):
rd=reldate.relativedelta(
weekday=reldate.FR(+2),
hours=+21)
rd2=reldate.relativedelta(
hour=3,minute=0,second=0,microsecond=0)
return dt+rd+rd2
Выше hours=+21
сообщает relativedelta
увеличивать значение dt
на 21 час до начала следующей пятницы. Итак, если dt
- 12 марта 2010 года в 2 часа ночи, добавление 21 часа составляет 11 вечера того же дня, но если dt
после 3 часов, то добавление 21 часа нажимает dt
в субботу.
Вот несколько тестовых кодов.
if __name__=='__main__':
today=datetime.datetime.now()
for dt in [today+datetime.timedelta(days=i) for i in range(-7,8)]:
print('%s --> %s'%(dt,following_friday(dt)))
который дает:
2010-03-05 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-06 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-07 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-08 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-09 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-10 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-11 20:42:09.246124 --> 2010-03-19 03:00:00
2010-03-12 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-13 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-14 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-15 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-16 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-17 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-18 20:42:09.246124 --> 2010-03-26 03:00:00
2010-03-19 20:42:09.246124 --> 2010-04-02 03:00:00
а до 3 утра:
two = datetime.datetime(2010, 3, 12, 2, 0)
for date in [two+datetime.timedelta(days=i) for i in range(-7,8)]:
result = following_friday(date)
print('{0}-->{1}'.format(date,result))
дает:
2010-03-05 02:00:00-->2010-03-12 03:00:00
2010-03-06 02:00:00-->2010-03-19 03:00:00
2010-03-07 02:00:00-->2010-03-19 03:00:00
2010-03-08 02:00:00-->2010-03-19 03:00:00
2010-03-09 02:00:00-->2010-03-19 03:00:00
2010-03-10 02:00:00-->2010-03-19 03:00:00
2010-03-11 02:00:00-->2010-03-19 03:00:00
2010-03-12 02:00:00-->2010-03-19 03:00:00
2010-03-13 02:00:00-->2010-03-26 03:00:00
2010-03-14 02:00:00-->2010-03-26 03:00:00
2010-03-15 02:00:00-->2010-03-26 03:00:00
2010-03-16 02:00:00-->2010-03-26 03:00:00
2010-03-17 02:00:00-->2010-03-26 03:00:00
2010-03-18 02:00:00-->2010-03-26 03:00:00
2010-03-19 02:00:00-->2010-03-26 03:00:00
Ответ 3
Мне нравится dateutil для таких задач в целом, но я не понимаю эвристики, которые вы хотите - поскольку я использую слова, если я скажу "в следующую пятницу", и в четверг я буду иметь в виду завтра (возможно, я слишком много работал и потерял информацию о том, какой день недели). Если вы можете точно указать свою эвристику, они, безусловно, могут быть запрограммированы, но если они странные и причудливые, вы вряд ли найдете их уже запрограммированными для вас в существующих пакетах; -).
Ответ 4
Основываясь на вашем разъяснении... Я думаю, вы можете сделать что-то вроде этого:
from datetime import *
>>> today = datetime.today()
>>> todayAtThreeAm = datetime(today.year, today.month, today.day, 3)
>>> todayAtThreeAm
datetime.datetime(2010, 3, 12, 3, 0)
>>> nextFridayAtThreeAm = todayAtThreeAm + timedelta(12 - today.isoweekday())
>>> nextFridayAtThreeAm
datetime.datetime(2010, 3, 19, 3, 0)
Примечание isoweekday()
возвращает от 1 до 7 в понедельник в воскресенье. 12 - пятница на следующей неделе. Итак, 12 - today.isoweekday() дает вам правильную временную дельту, которую вы должны добавить к сегодняшнему дню.
Надеюсь, что это поможет.