2007-08-10
Python Cookbook 3.5 计算两日期间的工作日数
需求:
你需要计算两个日期间的工作日数,而不是天数.
讨论:
因为对于周末的定义,每个国家,地区甚至公司都不同.所以没有内建的函数来完成这个需求,不过使用datetutil和datetime,可以很方便的实现这个需求.
from dateutil import rrule
import datetime
def workdays(start, end, holidays=0, days_off=None):
if days_off is None:
days_off = 5, 6 # default to: saturdays and sundays
workdays = [x for x in range(7) if x not in days_off]
days = rrule.rrule(rrule.DAILY, dtstart=start, until=end,
byweekday=workdays)
return days.count( ) - holidays
if _ _name_ _ == '_ _main_ _':
# test when run as main script
testdates = [ (datetime.date(2004, 9, 1), datetime.date(2004, 11, 14), 2),
(datetime.date(2003, 2, 28), datetime.date(2003, 3, 3), 1), ]
def test(testdates, days_off=None):
for s, e, h in testdates:
print 'total workdays from %s to %s is %s with %s holidays' % (
s, e, workdays(s, e, h, days_off), h)
test(testdates)
test(testdates, days_off=[6])
这个程序是我用Python写的第一个程序:我需要知道员工培训的具体日子,当给定两个日期的情况下.这个问题在Python2.2前是比较难办的,现在有了datetime和dateutil,变得非常简单了.
函数workdays首先给变量day_off设置了默认值(除非显式的给它赋值).它表示在一周中我们休息的日子.在我的公司中,每个人休息的日子是不同的,但一般情况都不会多于工作的日子,所以对我们来说,修改休息日比修改工作日更好一些.我把它作为函数的一个参数,这样在我需要另外的休息日的时候,可以简单的作为参数传递进来.接下来,函数创建了工作日的列表,里面不包含休息日.剩下要做的就是计算了.
在本节中做最多工作的是一个实例,days, 来自dateutil.rrule类.类rrule可以用来产生很多种不同的尺子.在本例中,我传递了常用的rrule.DAILY,还需要给出起始时间和终止时间,而且都是datetime.date类型.然后,我们只要调用days.count来计算其中的天数.
你可以自己定义周末:只要给day_off里面添加值就好了.在本节中,我们使用惯例的周六和周日作为周末,加入,你的公司是4工作日制,从周二到周五,你可以使用day_off=(5,6,0),只要以可以遍历的形式传递就好了,比如列表和元组.
一个简单的功能加强是自动判断给出的起始日和终止日是否是周末,如果是的话,自动修改day_off的值.更多的功能添加可以是加入病假日,或者查询休假日,而不是需要自己给出每一个休假日.
你需要计算两个日期间的工作日数,而不是天数.
讨论:
因为对于周末的定义,每个国家,地区甚至公司都不同.所以没有内建的函数来完成这个需求,不过使用datetutil和datetime,可以很方便的实现这个需求.
from dateutil import rrule
import datetime
def workdays(start, end, holidays=0, days_off=None):
if days_off is None:
days_off = 5, 6 # default to: saturdays and sundays
workdays = [x for x in range(7) if x not in days_off]
days = rrule.rrule(rrule.DAILY, dtstart=start, until=end,
byweekday=workdays)
return days.count( ) - holidays
if _ _name_ _ == '_ _main_ _':
# test when run as main script
testdates = [ (datetime.date(2004, 9, 1), datetime.date(2004, 11, 14), 2),
(datetime.date(2003, 2, 28), datetime.date(2003, 3, 3), 1), ]
def test(testdates, days_off=None):
for s, e, h in testdates:
print 'total workdays from %s to %s is %s with %s holidays' % (
s, e, workdays(s, e, h, days_off), h)
test(testdates)
test(testdates, days_off=[6])
这个程序是我用Python写的第一个程序:我需要知道员工培训的具体日子,当给定两个日期的情况下.这个问题在Python2.2前是比较难办的,现在有了datetime和dateutil,变得非常简单了.
函数workdays首先给变量day_off设置了默认值(除非显式的给它赋值).它表示在一周中我们休息的日子.在我的公司中,每个人休息的日子是不同的,但一般情况都不会多于工作的日子,所以对我们来说,修改休息日比修改工作日更好一些.我把它作为函数的一个参数,这样在我需要另外的休息日的时候,可以简单的作为参数传递进来.接下来,函数创建了工作日的列表,里面不包含休息日.剩下要做的就是计算了.
在本节中做最多工作的是一个实例,days, 来自dateutil.rrule类.类rrule可以用来产生很多种不同的尺子.在本例中,我传递了常用的rrule.DAILY,还需要给出起始时间和终止时间,而且都是datetime.date类型.然后,我们只要调用days.count来计算其中的天数.
你可以自己定义周末:只要给day_off里面添加值就好了.在本节中,我们使用惯例的周六和周日作为周末,加入,你的公司是4工作日制,从周二到周五,你可以使用day_off=(5,6,0),只要以可以遍历的形式传递就好了,比如列表和元组.
一个简单的功能加强是自动判断给出的起始日和终止日是否是周末,如果是的话,自动修改day_off的值.更多的功能添加可以是加入病假日,或者查询休假日,而不是需要自己给出每一个休假日.
标签: Python