日期时间Python - 下一工作日

时间:2012-02-08 02:52:41

标签: python datetime

两个相关问题:(1)我使用的所有数据都附有工作日。在不同的地方,我需要知道下一个工作日是什么。我已经写了类似下面的代码来做出这个决定,但我确信有更好的方法。任何人? (2)理想情况下,我不仅要知道下一个工作日,还要知道下一个美国工作日 - 也就是下一个不是美国市场假日的工作日。对此的任何帮助也会很棒。

import datetime as dt

day = dt.datetime.strptime('2012-02-03','%Y-%m-%d').date()
print day#day=2012-03-02 (Friday)

if day.weekday()==4:
    day = day+dt.timedelta(days=3)
else:
    day = day+dt.timedelta(days=1)

print day#day=2012-02-06 (Monday)
day = day+dt.timedelta(days=1)
print day#day=2012-02-07 (Tuesday)

5 个答案:

答案 0 :(得分:16)

我会使用dateutil.rrule

import datetime
from dateutil import rrule


holidays = [
    datetime.date(2012, 5, 1,),
    datetime.date(2012, 6, 1,),
    # ...
]

# Create a rule to recur every weekday starting today
r = rrule.rrule(rrule.DAILY,
                byweekday=[rrule.MO, rrule.TU, rrule.WE, rrule.TH, rrule.FR],
                dtstart=datetime.date.today())

# Create a rruleset
rs = rrule.rruleset()

# Attach our rrule to it
rs.rrule(r)

# Add holidays as exclusion days
for exdate in holidays:
    rs.exdate(exdate)


print rs[0]

答案 1 :(得分:5)

这个问题很常见,并且有不同级别的解决方案:

最简单:使用类似于检查工作日的方法。一个常见的idom就像是

d = datetime.date(2012,2,7)
next = d + datetime.timedelta(days= 7-d.weekday() if d.weekday()>3 else 1)

一旦你想要假期,你可以滚动你自己的日期时间“TradingDateChecker”,它必须扫描“可预测”的假期,如1月1日,7月4日,12月25日星期五或星期一之后,如果它们是周末, 5月的最后一个星期一,9月的第一个星期一等。

我甚至不打扰在这里发布该代码,因为在交易假期,它仍然不够。

  • 周五纽约证券交易所关闭,期货和债券市场开放
  • 哥伦布日和退伍军人节,银行关闭,股票市场开放。

股票和期货市场有不同的假期。如果您想要纽约证券交易所假期(常见请求),请参阅下文。由于截止日期通常仅在未来几年宣布,因此您无法真正保留自己的日历。

# For a longer list of NYSE closed dates see: http://www.chronos-st.org/NYSE_Observed_Holidays-1885-Present.html
holidays = [datetime.date(2000, 1, 17),
 datetime.date(2000, 2, 21),
 datetime.date(2000, 4, 21),
 datetime.date(2000, 5, 29),
 datetime.date(2000, 7, 4),
 datetime.date(2000, 9, 4),
 datetime.date(2000, 11, 23),
 datetime.date(2000, 12, 25),
 datetime.date(2001, 1, 1),
 datetime.date(2001, 1, 15),
 datetime.date(2001, 2, 19),
 datetime.date(2001, 5, 28),
 datetime.date(2001, 7, 4),
 datetime.date(2001, 9, 3),
 datetime.date(2001, 9, 11),
 datetime.date(2001, 9, 12),
 datetime.date(2001, 9, 13),
 datetime.date(2001, 9, 14),
 datetime.date(2001, 11, 22),
 datetime.date(2001, 12, 25),
 datetime.date(2002, 1, 1),
 datetime.date(2002, 1, 21),
 datetime.date(2002, 2, 18),
 datetime.date(2002, 3, 29),
 datetime.date(2002, 5, 27),
 datetime.date(2002, 7, 4),
 datetime.date(2002, 9, 2),
 datetime.date(2002, 11, 28),
 datetime.date(2002, 12, 25),
 datetime.date(2003, 1, 1),
 datetime.date(2003, 1, 20),
 datetime.date(2003, 2, 17),
 datetime.date(2003, 4, 18),
 datetime.date(2003, 5, 26),
 datetime.date(2003, 7, 4),
 datetime.date(2003, 9, 1),
 datetime.date(2003, 11, 27),
 datetime.date(2003, 12, 25),
 datetime.date(2004, 1, 1),
 datetime.date(2004, 1, 19),
 datetime.date(2004, 2, 16),
 datetime.date(2004, 4, 9),
 datetime.date(2004, 5, 31),
 datetime.date(2004, 6, 11),
 datetime.date(2004, 7, 5),
 datetime.date(2004, 9, 6),
 datetime.date(2004, 11, 25),
 datetime.date(2004, 12, 24),
 datetime.date(2005, 1, 17),
 datetime.date(2005, 2, 21),
 datetime.date(2005, 3, 25),
 datetime.date(2005, 5, 30),
 datetime.date(2005, 7, 4),
 datetime.date(2005, 9, 5),
 datetime.date(2005, 11, 24),
 datetime.date(2005, 12, 26),
 datetime.date(2006, 1, 2),
 datetime.date(2006, 1, 16),
 datetime.date(2006, 2, 20),
 datetime.date(2006, 4, 14),
 datetime.date(2006, 5, 29),
 datetime.date(2006, 7, 4),
 datetime.date(2006, 9, 4),
 datetime.date(2006, 11, 23),
 datetime.date(2006, 12, 25),
 datetime.date(2007, 1, 1),
 datetime.date(2007, 1, 2),
 datetime.date(2007, 1, 15),
 datetime.date(2007, 2, 19),
 datetime.date(2007, 4, 6),
 datetime.date(2007, 5, 28),
 datetime.date(2007, 7, 4),
 datetime.date(2007, 9, 3),
 datetime.date(2007, 11, 22),
 datetime.date(2007, 12, 25),
 datetime.date(2008, 1, 1),
 datetime.date(2008, 1, 21),
 datetime.date(2008, 2, 18),
 datetime.date(2008, 3, 21),
 datetime.date(2008, 5, 26),
 datetime.date(2008, 7, 4),
 datetime.date(2008, 9, 1),
 datetime.date(2008, 11, 27),
 datetime.date(2008, 12, 25),
 datetime.date(2009, 1, 1),
 datetime.date(2009, 1, 19),
 datetime.date(2009, 2, 16),
 datetime.date(2009, 4, 10),
 datetime.date(2009, 5, 25),
 datetime.date(2009, 7, 3),
 datetime.date(2009, 9, 7),
 datetime.date(2009, 11, 26),
 datetime.date(2009, 12, 25),
 datetime.date(2010, 1, 1),
 datetime.date(2010, 1, 18),
 datetime.date(2010, 2, 15),
 datetime.date(2010, 4, 2),
 datetime.date(2010, 5, 31),
 datetime.date(2010, 7, 5),
 datetime.date(2010, 9, 6),
 datetime.date(2010, 11, 25),
 datetime.date(2010, 12, 24),
 datetime.date(2011, 1, 17),
 datetime.date(2011, 2, 21),
 datetime.date(2011, 4, 22),
 datetime.date(2011, 5, 30),
 datetime.date(2011, 7, 4),
 datetime.date(2011, 9, 5),
 datetime.date(2011, 11, 24),
 datetime.date(2011, 12, 26),
 datetime.date(2012, 1, 2),
 datetime.date(2012, 1, 16),
 datetime.date(2012, 2, 20),
 datetime.date(2012, 4, 6),
 datetime.date(2012, 5, 28),
 datetime.date(2012, 7, 4),
 datetime.date(2012, 9, 3),
 datetime.date(2012, 11, 22),
 datetime.date(2012, 12, 25),
 datetime.date(2013, 1, 1),
 datetime.date(2013, 1, 21),
 datetime.date(2013, 2, 18),
 datetime.date(2013, 3, 29),
 datetime.date(2013, 5, 27),
 datetime.date(2013, 7, 4),
 datetime.date(2013, 9, 2),
 datetime.date(2013, 11, 28),
 datetime.date(2013, 12, 25)]

答案 2 :(得分:5)

我使用了holidays包。

$ pip install holidays

以下是我为确定今天下一个工作日所做的功能。

import datetime
import holidays

ONE_DAY = datetime.timedelta(days=1)
HOLIDAYS_US = holidays.US()

def next_business_day():
    next_day = datetime.date.today() + ONE_DAY
    while next_day.weekday() in holidays.WEEKEND or next_day in HOLIDAYS_US:
        next_day += ONE_DAY
    return next_day
如果明天不是周末而不是假期,它将在明天返回。否则它将找到下一个 * 日,而不是其中任何一个。示例运行于2017年3月15日星期三:

>>> next_business_day()
datetime.date(2017, 3, 16)

*注意,如果President Camacho每天都宣布假期,这可能会无限循环。

答案 3 :(得分:1)

没有ifs的另一种方式是:

def next_wk_day():
    date_today = datetime.datetime.today()
    shift = 1 + ((date_today.weekday()//4)*(6-date_today.weekday()))
    return(date_today+shift)

如果您在周六或周日进行此操作,也可以使用。

答案 4 :(得分:0)

完成多个工作日

def next_business_day(start_day, business_days, HOLIDAYS):
    ONE_DAY = datetime.timedelta(days=1)
    temp_day = start_day
    for i in range(0, business_days):
        next_day = temp_day + ONE_DAY
        while next_day.weekday() in [5,6] or next_day in HOLIDAYS:
            next_day += ONE_DAY
        temp_day = next_day
    return temp_day