查找给定日期之后的第一个星期一的日期
- 2025-03-19 08:57:00
- admin 原创
- 54
问题描述:
给定一个特定日期,比如 2011-07-02,如何找到该日期之后的下一个星期一(或任何工作日)的日期?
解决方案 1:
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)
解决方案 2:
这是针对上述略显沉重的答案的一个简洁而通用的替代方案。
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)
解决方案 3:
尝试
>>> 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:
另一种方法是使用 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
解决方案 5:
这是环内计算的示例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 年后你会发现这个答案极其有用 ;-)
解决方案 6:
另一个简单优雅的解决方案是使用 pandas 偏移量。
我发现它在玩日期游戏时非常有用且强大。
如果您想要第一个星期日,只需将频率修改为 freq='W-SUN'。
如果您想要接下来的几个星期日,请更改 offsets.Day(days)。
使用熊猫偏移量允许您忽略假期,只处理工作日等等。
您还可以使用该方法轻松地将此方法应用于整个 DataFrame apply
。
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)
解决方案 7:
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))
解决方案 8:
您可以开始向日期对象添加一天,并在星期一时停止。
>>> d = datetime.date(2011, 7, 2)
>>> while d.weekday() != 0: #0 for monday
... d += datetime.timedelta(days=1)
...
>>> d
datetime.date(2011, 7, 4)
解决方案 9:
import datetime
d = datetime.date(2011, 7, 2)
while d.weekday() != 0:
d += datetime.timedelta(1)
解决方案 10:
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)
解决方案 11:
这将给出给定日期之后的第一个下星期一:
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
解决方案 12:
通过列表理解?
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)
解决方案 13:
通常要查找今天星期几的任意日期:
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"))
以日/月/年格式输出
解决方案 14:
现在已经接近2024年底了,我想给出一个更新的答案,并在 Python 3.12+ 中进行了测试。
# For earlier Python versions like 3.7+
# from __future__ import annotations
from datetime import date, timedelta
from enum import IntEnum
class Day(IntEnum):
MONDAY = 0
TUESDAY = 1
WEDNESDAY = 2
THURSDAY = 3
FRIDAY = 4
SATURDAY = 5
SUNDAY = 6
@classmethod
def fromstr(cls, weekday: str):
return cls[weekday.upper()]
def next_day(from_date: date | None = None,
weekday: Day | int = Day.MONDAY,
always_next_weekday: bool = False) -> date:
if from_date is None:
from_date = date.today()
# Find the day of the week (0 = Monday, 6 = Sunday)
day_of_week = from_date.weekday()
# If weekdays match for `from_date` and `weekday`,
# return `from_date` if `next_if_same_day` is False
if weekday == day_of_week and not always_next_weekday:
return from_date
# Calculate days until next `weekday`
days_ahead = (weekday - day_of_week - 1) % 7 + 1
# Add the calculated days to the current date
return from_date + timedelta(days=days_ahead)
使用方法如下:
if __name__ == '__main__':
d = date(2011, 7, 2)
for day in Day.__members__:
res = next_day(d, Day[day], always_next_weekday=True)
print(day.ljust(10), res.strftime('%B %d %Y'))
观察输出是否正确:
MONDAY July 04 2011
TUESDAY July 05 2011
WEDNESDAY July 06 2011
THURSDAY July 07 2011
FRIDAY July 08 2011
SATURDAY July 09 2011
SUNDAY July 03 2011
相关推荐
热门文章
项目管理软件有哪些?
热门标签
曾咪二维码
扫码咨询,免费领取项目管理大礼包!
云禅道AD