簡體   English   中英

查找給定日期之后的第一個星期一的日期

[英]Find the date for the first Monday after a given date

給定一個特定的日期,比如 2011-07-02,我怎樣才能找到該日期之后的下一個星期一(或任何工作日)的日期?

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)

這是上面略顯沉重的答案的簡潔通用的替代方案。

def onDay(date, day):
    """
    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).
    """
    days = (day - date.weekday() + 7) % 7
    return date + datetime.timedelta(days=days)

嘗試

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

使用,下一個星期一是星期一之后的 7 天,星期二之后的 6 天,依此類推,並且還使用 Python 的datetime類型將星期一報告為0 ,...,星期日報告為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 年后非常有幫助;-)

另一個簡單優雅的解決方案是使用 pandas 偏移量。

在玩日期時,我發現它非常有用和強大。

  • 如果您想要第一個星期日,只需將頻率修改為 freq='W-SUN'。
  • 如果您想要幾個下周日,請更改 offsets.Day(days)。
  • 使用 pandas 偏移量可以讓您忽略節假日,僅使用工作日等。

您還可以使用apply方法輕松地將此方法應用於整個 DataFrame。

import pandas as pd
import datetime

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

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


df = pd.DataFrame([datetime.date(2011, 7, 2)], columns=["Date"])
df["ClosestMonday"] = df.apply(lambda row: get_closest_monday(row), axis=1)
print(df)

另一種選擇使用 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]

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

您可以開始添加一天日期 object 並在星期一停止。

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

d = datetime.date(2011, 7, 2)
while d.weekday() != 0:
    d += datetime.timedelta(1)
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)

通常從今天開始從一周中的某一天找到任何日期:


def getDateFromDayOfWeek(dayOfWeek):
    week_days = ["monday", "tuesday", "wednesday",
                 "thursday", "friday", "saturday", "sunday"]
    today = datetime.datetime.today().weekday()
    requiredDay = week_days.index(dayOfWeek)
    if today>requiredDay:
          noOfDays=7-(today-requiredDay)
          print("noDays",noOfDays)
    else:  
          noOfDays = requiredDay-today
          print("noDays",noOfDays)
    requiredDate = datetime.datetime.today()+datetime.timedelta(days=noOfDays)
    return requiredDate

print(getDateFromDayOfWeek('sunday').strftime("%d/%m/%y"))

以日/月/年的格式給出 output

dateutil對這種操作有一個特殊的功能,它是我見過的最優雅的方式。

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

first_monday_date = (datetime(2011,7,2) + relativedelta(weekday=MO(0))).date()

如果你只想要日期時間

first_monday_date = datetime(2011,7,2) + relativedelta(weekday=MO(0))

這將給出給定日期后的第一個下周一:

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

通過列表理解?

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM