我正在尝试将n(整数)工作日添加到给定日期,添加日期必须避免假期和周末(它不包括在工作日内)
omz*_*omz 17
跳过周末很容易做到这样的事情:
import datetime
def date_by_adding_business_days(from_date, add_days):
business_days_to_add = add_days
current_date = from_date
while business_days_to_add > 0:
current_date += datetime.timedelta(days=1)
weekday = current_date.weekday()
if weekday >= 5: # sunday = 6
continue
business_days_to_add -= 1
return current_date
#demo:
print '10 business days from today:'
print date_by_adding_business_days(datetime.date.today(), 10)
Run Code Online (Sandbox Code Playgroud)
假期的问题在于它们因国家或地区,宗教等而有很大差异.您需要一个列表/一组假期用于您的用例,然后以类似的方式跳过它们.起点可能是Apple为iCal发布的日历源(采用ics格式),美国的日历源是http://files.apple.com/calendars/US32Holidays.ics
您可以使用icalendar模块来解析它.
Jon*_*nts 12
如果您不介意使用第三方库,则dateutil非常方便
from dateutil.rrule import *
print "In 4 business days, it's", rrule(DAILY, byweekday=(MO,TU,WE,TH,FR))[4]
Run Code Online (Sandbox Code Playgroud)
您还可以查看rruleset并使用.exdate()提供假期以跳过计算中的假期,并且可选择cache避免重新计算可能值得查看的选项.
没有真正的捷径可以做到这一点.试试这种方法:
skip(self, d)返回True应跳过的日期的方法.datetime或类似,因为一天的分数会杀了你.True字典中的任何日期或d.weekday() >= 5要添加N天,请使用以下方法:
def advance(d, days):
delta = datetime.timedelta(1)
for x in range(days):
d = d + delta
while holidayHelper.skip(d):
d = d + delta
return d
Run Code Online (Sandbox Code Playgroud)
感谢基于omz代码我做了一些小改动......它可能对其他用户有帮助:
import datetime
def date_by_adding_business_days(from_date, add_days,holidays):
business_days_to_add = add_days
current_date = from_date
while business_days_to_add > 0:
current_date += datetime.timedelta(days=1)
weekday = current_date.weekday()
if weekday >= 5: # sunday = 6
continue
if current_date in holidays:
continue
business_days_to_add -= 1
return current_date
#demo:
Holidays =[datetime.datetime(2012,10,3),datetime.datetime(2012,10,4)]
print date_by_adding_business_days(datetime.datetime(2012,10,2), 10,Holidays)
Run Code Online (Sandbox Code Playgroud)
我想要一个不是O(N)的解决方案,它看起来像一个有趣的代码高尔夫.如果有人感兴趣的话,这就是我所说的.适用于正数和负数.如果我错过任何事情,请告诉我.
def add_business_days(d, business_days_to_add):
num_whole_weeks = business_days_to_add / 5
extra_days = num_whole_weeks * 2
first_weekday = d.weekday()
remainder_days = business_days_to_add % 5
natural_day = first_weekday + remainder_days
if natural_day > 4:
if first_weekday == 5:
extra_days += 1
elif first_weekday != 6:
extra_days += 2
return d + timedelta(business_days_to_add + extra_days)
Run Code Online (Sandbox Code Playgroud)