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的值.更多的功能添加可以是加入病假日,或者查询休假日,而不是需要自己给出每一个休假日.

标签:


Comments: 发表评论



<< Home

This page is powered by Blogger. Isn't yours?