考虑以下几点:
您只需仔细检查开始日期和结束日期的各个方面。 IE 仔细计算这两天的工作时间。
对于中间的每隔一个日期,您只需要知道一件事或几件事 (1) 如果是工作日,并且如果是:(2) 是联邦假日
对于日期范围内的每个合格日期,您确切知道每天有多少“工作时间”:480 分钟。
Pandas 提供了一种根据美国联邦假期获取工作日的方法。这可以解决最困难的部分。其余的应该很容易实现。
可能有一种更优雅的方式,但可以从这里开始。大多数代码用于处理开始日期和结束日期。中间的所有分钟大约是 4 行。
from dateutil.relativedelta import relativedelta
import pandas as pd
from pandas.tseries.offsets import CDay
from pandas.tseries.holiday import USFederalHolidayCalendar
business_day = CDay(calendar=USFederalHolidayCalendar())
def is_weekday(dt):
return dt.weekday() < 5
def is_holiday(dt):
return not len(pd.date_range(dt, dt, freq=business_day))
def weekend_or_holiday(dt):
'''helper function'''
if not is_weekday(dt):
return True
if is_holiday(dt):
return True
return False
def start_day_minutes(dt, end_of_day=None):
'''returns number of business minutes left in the day given a start datetime'''
if not end_of_day:
end_of_day = dt.replace(hour=17, minute=0)
if dt > end_of_day or weekend_or_holiday(dt):
return 0
num_of_minutes = (end_of_day - dt).seconds / 60
return num_of_minutes
def end_day_minutes(dt):
'''like start_day_minutes, but for the ending day.'''
start_of_day = dt.replace(hour=9, minute=0)
if dt < start_of_day or weekend_or_holiday(dt):
return 0
num_of_minutes = (dt - start_of_day).seconds / 60
return num_of_minutes
def business_minutes(t1, t2):
'''returns num of busniess minutes between t1 and t2'''
start = t1.replace(hour=0, minute=0) + relativedelta(days=1)
end = t2.replace(hour=0, minute=0) + relativedelta(days=-1)
days_between = pd.date_range(start, end, freq=business_day)
minutes_between = (len(days_between) * 480)
if (t1.year, t1.day) == (t2.year, t2.day):
start_end_minutes = start_day_minutes(t1, t2)
else:
start_end_minutes = start_day_minutes(t1) + end_day_minutes(t2)
minutes = minutes_between + start_end_minutes
return minutes
例子:
start=datetime(2016,1,1)
end=datetime(2017,1,1)
print(business_minutes(start,end))
#120480