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

2025-03-19 08:57:00
admin
原创
55
摘要:问题描述:给定一个特定日期,比如 2011-07-02,如何找到该日期之后的下一个星期一(或任何工作日)的日期?解决方案 1:import datetime def next_weekday(d, weekday): days_ahead = weekday - d.weekday() if ...

问题描述:

给定一个特定日期,比如 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
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用