【问题标题】:Get the business day before yesterday获取前天营业日
【发布时间】:2021-05-26 21:48:53
【问题描述】:

基本上我正在寻找某种方法来计算前天的业务,因为我必须运行 t-2 查询,而无需对 datetime 变量进行任何手动干预:

简而言之:

27.05.21 -> 25.05.21

今天的日期当然是每天都在变化的动态变量,您应该考虑周末,例如31.05.21 -> 27.05.21

我自己研究了“获取最后一个工作日的方法”来修改它......

today = datetime.today()
offset = max(1, (today. weekday() + 6) % 7 - 3)
timedelta = datetime. timedelta(offset)
most_recent = today - timedelta
print(most_recent)

...但是我失败得很惨,在这里不值一提。

任何帮助将不胜感激!

非常感谢!

Ciao 回复

【问题讨论】:

  • 请详细说明您的代码存在的问题。我没看到。 5 月 20 日至 27 日这一周的简单测试循环显示了每一天的正确结果。
  • 如果你需要考虑假期,这段代码会复杂很多。
  • 这段代码必须每天运行,由詹金斯通过 git 触发。 5 月 20 日至 27 日(等等……)只是一个例子。因此,解决方案必须从今天开始每天运行,并且应该通过前天的工作日,这意味着今天 = 27.05。 -> 输出:25.05。不应考虑假期。
  • 我想知道为什么人们不赞成这个问题:|这是一个有趣的问题。与这个问题无关,但对于假期,很难考虑假期,因为这取决于每个国家的政策。考虑到假期,我们应该有一个数据库。

标签: python datetime timedelta


【解决方案1】:

您可以使用pandas.tseries.offsets.BusinessDay(仅周六和周日除外)。

from datetime import datetime
import pandas as pd

dates = ['24.05.21', '25.05.21', '26.05.21']

def offset(date, offset, date_format='%d.%m.%y'):
    return (datetime.strptime(date, date_format) + pd.tseries.offsets.BusinessDay(offset)).strftime(date_format)

for date in dates:
    print('if today =', date, 'the expected result is', offset(date, -2))

输出:

if today = 24.05.21 the expected result is 20.05.21
if today = 25.05.21 the expected result is 21.05.21
if today = 26.05.21 the expected result is 24.05.21

这是一个没有 pandas 的版本:

from datetime import datetime, timedelta

dates = ['24.05.21', '25.05.21', '26.05.21']

def offset(date, offset, date_format='%d.%m.%y'):
    # adds offset
    output = datetime.strptime(date, date_format) + timedelta(days=offset)
    # adds more offset if output's weekday is Saturday or Sunday
    output += timedelta(days=(output.isoweekday() > 5) * offset)
    # returns output
    return output.strftime(date_format)

for date in dates:
    print('if today =', date, 'the expected result is', offset(date, -2))

【讨论】:

  • 您好,感谢您的回复!我在您的代码中看到的问题是日期列表,因为此代码每天每天都会自动飞行。由于日期列表中的日期是硬编码的,这对我不起作用。
  • 硬编码的日期是示例。但基本思想在于offset() 函数。您可以使用(datetime.datetime.now() + pd.tseries.offsets.BusinessDay(-2)).date() 获得您正在寻找的确切结果。
【解决方案2】:

我认为我们可以通过预定义目标日期需要换班的天数来简化代码。例如,如果目标日期是星期一或星期二,我们将轮换 4 天,否则,我们将周三轮班 2 天到周六,周日轮班 3 天。

代码:

import datetime

SHIFT_DAY_MAP = {
    0: 4,
    1: 4,
    2: 2,
    3: 2,
    4: 2,
    5: 2,  # Sat.
    6: 3  # Sun.
}


def get_two_business_day_before(date: datetime.datetime):
    weekday = date.weekday()
    shift_days = SHIFT_DAY_MAP[weekday]
    timedelta = datetime.timedelta(days=shift_days)
    return date - timedelta

测试:

for i in range(7):
    d = datetime.datetime(2021, 5, 10 + i)
    print(d.date(), "->", get_two_business_day_before(d).date())

结果:

2021-05-10 -> 2021-05-06
2021-05-11 -> 2021-05-07
2021-05-12 -> 2021-05-10
2021-05-13 -> 2021-05-11
2021-05-14 -> 2021-05-12
2021-05-15 -> 2021-05-13
2021-05-16 -> 2021-05-13

注意:我假设周末的理想轮班日是周六 2 天,周日 3 天,因为您的要求没有提及。

【讨论】:

    猜你喜欢
    • 2020-08-11
    • 2021-07-17
    • 2018-11-07
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多