在给定日期后找到第一个星期一的日期


Answers:


130
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)

8
你也可以做((day - today) + 7) % 7,以获得天DIFF
jstaab

2
@jstaab或简化为(day - today) % 7。减法中的负结果将按照您的预期进行处理。例如-1 % 7给出6
法学徒

54

这是上面略显笨拙的答案的简洁概括。

# 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)

这个答案来不及收集赞成票,为时已晚,但这是我的最爱。
ASalazar

2
干净,但需要两个提醒。1.如果工作日与day和date.weekday()相匹配,则返回相同的日期。day应该采用weekday()格式,而不是isoweekday()
bhtabor

7
可以,但是在+7服用时不必要%7。更改为:onDay = lambda date, day: date + datetime.timedelta(days=(day-date.weekday())%7)
扎克·西格尔

1
另外,由于Python的datetime程序包具有一个date类(我个人经常导入),所以我将其date视为关键字,并且不命名变量date。我将其更改为:onDay = lambda dt, day: dt + datetime.timedelta(days=(day-dt.weekday())%7)提醒自己,输入格式是Pythondatetime.date变量。(此外,在Javascript中,date它是标准类型,您不应命名变量date。)
Zach Siegel,

1
解决bhtabor的问题:1.确保返回下周的星期一,即使date本身就是星期一,也请更改为onDay = lambda date, day: date + datetime.timedelta(days=(day-date.weekday()-1)%7+1)。同样重要的是:2.改变date.weekday()date.isoweekday()是否day应为Monday..Sunday值1..7而不是0..6。
ElRudi

26

尝试

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

使用,下一个星期一是星期一之后的7天,星期二之后是6天,依此类推,并且还使用Python的datetime类型将星期一报告为0,...,星期日报告为6


有趣的是-当我尝试使用datetime(2013,1,1)+ timedelta(days =(7-datetime(2013,1,1).. dayday())查找datetime(2013,1,1)之后的下一个星期日时))”,我得到的是“ datetime.datetime(2013,1,7,0,0)”,它是星期一。
fixxxer 2013年

2
@fixxxer-就像答案中所说的那样:代码以某种datetime方式使用了API的一些属性,只有在您寻找星期一时,该属性才有效。提供的代码phihag较为笼统,可以找到任何即将到来的星期几。
德克(Dirk)2013年

您认为在timedelta中使用6而不是7会有所帮助吗?
fixxxer

@fixxxer:为什么不简单使用提供的代码phihag?它可以做您想要的:next_weekday(datetime.date(2013,1,1), 6)datetime.date(2013, 1, 6),星期天。我的代码在(ab)中使用Python的datetimeAPI的某些属性是“可爱的”,并且仅回答问题的“查找下一个星期一”部分,但回答程度不够一般,不足以回答“查找下一个xxx天”的问题。
德克(Dirk)2013年

@fixxxer:使用“可爱”代码查找下一个星期日d + timedelta(6 - d.weekday() or 13 - d.weekday()):(如果Sunday == 6是一周的最后一天,则相当于phihag的代码)
jfs

6

这是ring中的计算示例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年后您会发现这个答案非常有帮助;-)


5

您可以开始添加一天的日期对象,并在星期一停止。

>>> d = datetime.date(2011, 7, 2)
>>> while d.weekday() != 0: #0 for monday
...     d += datetime.timedelta(days=1)
... 
>>> d
datetime.date(2011, 7, 4)

4

另一个简单而优雅的解决方案是使用pandas偏移量。
我发现在玩日期时它非常有用且功能强大。
-如果您想要第一个星期日,只需将频率更改为freq ='W-SUN'。
-如果您要在下几个星期日进行更改,请更改offsets.Day(天)。
-使用大熊猫偏移量可以忽略假期,仅在工作日等时使用。
您还可以使用apply方法轻松地将此方法应用于整个DataFrame。

# 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)

3

另一种选择使用规则

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


2
import datetime

d = datetime.date(2011, 7, 2)
while d.weekday() != 0:
    d += datetime.timedelta(1)

0
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)

-1

给定日期后的下一个星期一:

import datetime

def get_next_monday(year, month, day):
    date0 = datetime.date(year, month, day)
    next_monday = date0 + datetime.timedelta(7 - date0.weekday() or 7)
    return next_monday

print get_next_monday(2011, 7, 2)
print get_next_monday(2015, 8, 31)
print get_next_monday(2015, 9, 1)

2011-07-04
2015-09-07
2015-09-07


-1

通过列表理解?

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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.