如何计算一个月的第一个星期一;Python 3.3+

7

我需要在每月的第一个星期一运行一次报告,并使用Python计算出这个日期。目前我已经编写了一段代码,将其放入我们的ETL程序模块中,并确定该日期是否实际上是该月的第一天。理想情况下,如果星期一是本月的第一个星期一,则仅在这一天运行报告(执行=1)。否则,不执行任何操作(执行=0)。我现在拥有的是:

# Calculate first Monday of the month

# import module(s)

from datetime import datetime, date, timedelta

today = date.today() # - timedelta(days = 1)
datee = datetime.strptime(str(today), "%Y-%m-%d")

print(f'Today: {today}')

# function finds first Monday of the month given the date passed in "today"

def find_first_monday(year, month, day):
    d = datetime(year, int(month), int(day))
    offset = 0-d.weekday() #weekday = 0 means monday
    if offset < 0:
        offset+=7
    return d+timedelta(offset)

# converts datetime object to date
first_monday_of_month = find_first_monday(datee.year, datee.month, datee.day).date()

# prints the next Monday given the date that is passed as "today" 

print(f'Today\'s date: {today}')
print(f'First Monday of the month date: {first_monday_of_month}')

# if first Monday is true, execute = 1, else execute = 0; 1 will execute the next module of code

if today == first_monday_of_month:
  execute = 1
  print(execute) 
else:
  execute = 0
  print(execute)

假设“今天”的日期在本月的第一个星期一之前,这段代码会起作用。当“今天”在本月的第一个星期一之后时,该代码将打印下一个即将到来的星期一。

我们的ETL调度程序允许我们每天、每周或每月运行。我想我必须每天运行它,即使这是一个月度报告,而拥有这段代码的模块将确定“今天”是否是本月的第一个星期一。如果不是第一个星期一,它将不会执行下一个代码模块(execute = 0)。但如果“今天”是本月的第一个星期一,则我不确定它是否能够正常运行,因为它会打印出任何传入“今天”的日期的下一个即将到来的星期一。

我似乎找不到我需要的答案,以确保它只计算本月的第一个星期一,并仅在那一天运行报告。提前谢谢。

4个回答

13
一种方法是忽略当前的day值,而是直接使用7;然后你可以简单地减去weekday的偏移量:
from datetime import datetime, timedelta

# note change to function signature
def find_first_monday(year, month):
    d = datetime(year, int(month), 7)
    offset = -d.weekday() # weekday == 0 means Monday
    return d + timedelta(offset)

4
使用numpy,计算每月的第一个星期一要比其他方式简单得多。
import datetime
import numpy as np

any_date_in_month = datetime.datetime(year, month, day)

year_month = any_date_in_month.strftime('%Y-%m')
first_monday = np.busday_offset(year_month, 0, roll='forward', weekmask='Mon')

所以只需将您需要的任何内容与first_monday进行比较,您就可以开始了。


0
一个稍微不同的方法 - date.weekday()函数会给出一周中某天的索引(星期一为0,星期日为6)。您可以使用此值直接计算一周中任何一天将落在哪个日期。对于星期一,可以这样做...
def first_monday(year, month):
    day = (8 - datetime.date(year, month, 1).weekday()) % 7
    return datetime.date(year, month, day)

当然,你可以制作一个通用版本,让你指定你想要的星期几,就像这样:
def first_dow(year, month, dow):
    day = ((8 + dow) - datetime.date(year, month, 1).weekday()) % 7
    return datetime.date(year, month, day)

它接受与date.weekday()函数返回相同的索引(星期一为0,星期日为6)。例如,要查找2022年7月的第一个星期三(2)...

>>> first_dow(2022, 7, 2)
datetime.date(2022, 7, 6)

对于星期天 -> 6 first_dow(2022, 8, 6) 它以错误结束:ValueError: day is out of range for month - cincin21

0
这是一个函数,它将在给定月份中找到第一个出现的日期。
def find_first_week_day(year: int, month: int, week_day: int) -> date:
    """
    Return the first weekday of the given month.

    :param year: Year
    :param month: Month
    :param week_day: Weekday to find [0-6]

    :return: Date of the first weekday of the given month
    """
    first_day = date(year, month, 1)
    if first_day.weekday() == week_day:
        return first_day
    if first_day.weekday() < week_day:
        return first_day + timedelta(week_day - first_day.weekday())
    return first_day + timedelta(7 - first_day.weekday() + week_day)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接