查找给定日期后第一个星期一的日期

ghi*_*man 57 python date

鉴于特定日期,比如2011-07-02,如何在该日期之后找到下周一(或该工作日的任何工作日)的日期?

phi*_*hag 104

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)
Run Code Online (Sandbox Code Playgroud)

  • 你也可以做`((今天 - 今天)+ 7)%7`来获得一天的差异 (7认同)
  • 我认为只有'(今天 - 今天)%7'才能做到这一点 (6认同)
  • @jstaab 或者简化为“(天 - 今天)% 7”。减法中的负结果将按照您的预期进行处理。例如,“-1 % 7”给出“6”。 (3认同)

use*_*533 44

这是上面稍微重要的答案的简洁和通用的替代方案.

# 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)
Run Code Online (Sandbox Code Playgroud)

  • 非常干净,你有我的投票. (2认同)
  • 干净,但需要两个提醒。1.如果工作日与天和date.weekday()相匹配,则返回相同的日期。2.日期应采用工作日()格式,而不是isoweekday() (2认同)
  • 可以,但是当您使用%7时,不需要+7。将其更改为:`onDay = lambda date,day:date + datetime.timedelta(days =(day-date.weekday())%7)` (2认同)
  • 另外,由于 Python 的 `datetime` 包有一个 `date` 类(我个人经常导入),我将 `date` 视为关键字并且不将变量命名为 `date`。我会将其更改为:`onDay = lambda dt, day: dt + datetime.timedelta(days=(day-dt.weekday())%7)` 以提醒自己输入的格式是 Python `datetime。日期`变量。(另外,在 Javascript 中,`date` 是一个标准类型,你不应该将变量命名为 `date`。) (2认同)

Dir*_*irk 22

尝试

>>> dt = datetime(2011, 7, 2)
>>> dt + timedelta(days=(7 - dt.weekday()))
datetime.datetime(2011, 7, 4, 0, 0)
Run Code Online (Sandbox Code Playgroud)

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

  • @fixxxer - 正如答案中所说:代码以某种方式使用了`datetime` API 的一些属性,如果您正在寻找星期一,这些属性只会起作用。`phihag` 提供的代码更通用,可以找到任何即将到来的星期几。 (2认同)

Chr*_*son 9

另一种选择是使用 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]
Run Code Online (Sandbox Code Playgroud)

rrule 文档:https ://dateutil.readthedocs.io/en/stable/rrule.html


fre*_*ger 7

这是 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))
Run Code Online (Sandbox Code Playgroud)

将打印:

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
Run Code Online (Sandbox Code Playgroud)

如您所见,它正确地给您下周一、周二、周三、周四、周五和周六。它也知道这2018-04-15是一个星期日并返回当前星期日而不是下一个星期日。

我相信你会在 7 年后发现这个答案非常有帮助 ;-)


Utk*_*ver 6

dateutil对于这种操作有一个特殊的功能,这是我见过的最优雅的方式。

from datetime import datetime
from dateutil.relativedelta import relativedelta, MO

first_monday_date = (datetime(2011,7,2) + relativedelta(weekday=MO(0))).date()
Run Code Online (Sandbox Code Playgroud)

如果你想要日期时间

first_monday_date = datetime(2011,7,2) + relativedelta(weekday=MO(0))
Run Code Online (Sandbox Code Playgroud)


utd*_*mir 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)
Run Code Online (Sandbox Code Playgroud)


小智 5

另一个简单优雅的解决方案是使用 Pandas 偏移量。
我发现它在玩日期时非常有用和强大。
- 如果您想要第一个星期日,只需将频率修改为 freq='W-SUN'。
- 如果您想要几个下周日,请更改 offsets.Day(days)。
- 使用 Pandas 抵消允许您忽略假期,仅使用工作日等。
您还可以使用 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)
Run Code Online (Sandbox Code Playgroud)