Найти дату первого понедельника после заданной даты - PullRequest
49 голосов
/ 02 июля 2011

Учитывая определенную дату, скажем 2011-07-02, как я могу найти дату следующего понедельника (или любого дня недели в этом отношении) после этой даты?

Ответы [ 11 ]

95 голосов
/ 02 июля 2011
import datetime
def next_weekday(d, weekday):
    days_ahead = weekday - d.weekday()
    if days_ahead <= 0: # Target day already happened this week
        days_ahead += 7
    return d + datetime.timedelta(days_ahead)

d = datetime.date(2011, 7, 2)
next_monday = next_weekday(d, 0) # 0 = Monday, 1=Tuesday, 2=Wednesday...
print(next_monday)
39 голосов
/ 06 июня 2016

Вот краткая и обобщенная альтернатива слегка весомым ответам выше.

# Returns the date of the next given weekday after
# the given date. For example, the date of next Monday.
# NB: if it IS the day we're looking for, this returns 0.
# consider then doing onDay(foo, day + 1).
onDay = lambda date, day: date + datetime.timedelta(days=(day-date.weekday()+7)%7)
21 голосов
/ 02 июля 2011

Попробуйте

>>> dt = datetime(2011, 7, 2)
>>> dt + timedelta(days=(7 - dt.weekday()))
datetime.datetime(2011, 7, 4, 0, 0)

, используя, чтобы следующий понедельник был через 7 дней после понедельника, через 6 дней после вторника, и так далее, а также используя, что тип Python datetime сообщает о понедельнике как0, ..., воскресенье как 6.

4 голосов
/ 02 июля 2011

Вы можете начать добавление объекта на один день к дате и остановиться, когда наступит понедельник.

>>> d = datetime.date(2011, 7, 2)
>>> while d.weekday() != 0: #0 for monday
...     d += datetime.timedelta(days=1)
... 
>>> d
datetime.date(2011, 7, 4)
3 голосов
/ 15 апреля 2018

Это пример вычислений внутри кольца mod 7.

import datetime


def next_day(given_date, weekday):
    day_shift = (weekday - given_date.weekday()) % 7
    return given_date + datetime.timedelta(days=day_shift)

now = datetime.date(2018, 4, 15) # sunday
names = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday',    
         'saturday', 'sunday']
for weekday in range(7):
    print(names[weekday], next_day(now, weekday))

выведет:

monday 2018-04-16
tuesday 2018-04-17
wednesday 2018-04-18
thursday 2018-04-19
friday 2018-04-20
saturday 2018-04-21
sunday 2018-04-15

Как вы видите, это правильно даст вам следующий понедельник, вторник, среда, четвергПятница и суббота.И он также понял, что 2018-04-15 - воскресенье и вернул текущее воскресенье вместо следующего.

Я уверен, что вы найдете этот ответ чрезвычайно полезным после 7 лет; -)

2 голосов
/ 26 июня 2017
import datetime

d = datetime.date(2011, 7, 2)
while d.weekday() != 0:
    d += datetime.timedelta(1)
2 голосов
/ 08 июня 2017

Еще одно простое элегантное решение - использовать смещения панд.
Я нахожу это очень полезным и надежным при игре с датами.
- Если вы хотите первое воскресенье, просто измените частоту на freq = 'W-SUN'.
- Если вы хотите пару следующих воскресений, измените смещения. День (дни).
- Использование смещений панд позволяет игнорировать праздники, работать только с рабочими днями и т. Д.
Вы также можете легко применить этот метод ко всему DataFrame, используя метод apply.

# Getting the closest monday from a given date
closest_monday = pd.date_range(start=date, end=date + offsets.Day(6), freq='W-MON')[0]

# Adding a 'ClosestMonday' column with the closest monday for each row in a pandas df using apply
# Require you to have a 'Date' column in your df
def get_closest_monday(row):
    return pd.date_range(start=row.Date, end=row.Date + offsets.Day(6), freq='W-MON')[0]

df['ClosestMonday'] = df.apply(lambda row: get_closest_monday(row), axis=1)
0 голосов
/ 04 января 2019

Другая альтернатива использует rrule

from dateutil.rrule import rrule, WEEKLY, MO
from datetime import date

next_monday = rrule(freq=WEEKLY, dtstart=date.today(), byweekday=MO, count=1)[0]

Правовые документы: https://dateutil.readthedocs.io/en/stable/rrule.html

0 голосов
/ 04 апреля 2016
weekday = 0 ## Monday
dt = datetime.datetime.now().replace(hour=0, minute=0, second=0) ## or any specific date
days_remaining = (weekday - dt.weekday() - 1) % 7 + 1
next_dt = dt + datetime.timedelta(days_remaining)
0 голосов
/ 07 октября 2015

через понимание списка?

from datetime import *
[datetime.today()+timedelta(days=x) for x in range(0,7) if (datetime.today()+timedelta(days=x)).weekday() % 7 == 0]

(0 at the end is for next monday, returns current date when run on monday)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...