Pythonクックブック(3章)

dateutilモジュールの続き

rrule

繰り返し処理を簡単に出来る。

>>> from dateutil.rrule import *
>>> from datetime import *
>>> import calendar
>>> today=datetime.today()
>>> firstday=today.replace(day=1)
>>> lastday = today.replace(day=calendar.monthrange(today.year, today.month)[1])
>>> 
# 今月の火曜日、木曜日をリストアップ
>>> list(rrule(DAILY, byweekday=(TU, TH), dtstart=firstday, until=lastday))
[datetime.datetime(2011, 7, 5, 22, 17, 2), datetime.datetime(2011, 7, 7, 22, 17, 2), datetime.datetime(2011, 7, 12, 22, 17, 2), datetime.datetime(2011, 7, 14, 22, 17, 2), datetime.datetime(2011, 7, 19, 22, 17, 2), datetime.datetime(2011, 7, 21, 22, 17, 2), datetime.datetime(2011, 7, 26, 22, 17, 2), datetime.datetime(2011, 7, 28, 22, 17, 2)]
>>> 
# 今月の偶数週の水曜日をリストアップ
>>> list(rrule(WEEKLY, interval=2, byweekday=(WE), dtstart=firstday, until=lastday))
[datetime.datetime(2011, 7, 13, 22, 17, 2), datetime.datetime(2011, 7, 27, 22, 17, 2)]
>>> list(rrule(DAILY, interval=2, byweekday=(WE), dtstart=firstday, until=lastday))
[datetime.datetime(2011, 7, 13, 22, 17, 2), datetime.datetime(2011, 7, 27, 22, 17, 2)]
>>> 
# 今年の残りの月の第一水曜日をリストアップ
>>> list(rrule(MONTHLY, byweekday=WE(1), dtstart=firstday, until=datetime(2011, 12, 31)))
[datetime.datetime(2011, 7, 6, 22, 17, 2), datetime.datetime(2011, 8, 3, 22, 17, 2), datetime.datetime(2011, 9, 7, 22, 17, 2), datetime.datetime(2011, 10, 5, 22, 17, 2), datetime.datetime(2011, 11, 2, 22, 17, 2), datetime.datetime(2011, 12, 7, 22, 17, 2)]
>>> 

DAILYでもWEEKLYでも同じような結果になる。どっちを使うべきなんだろうか。。。

出勤日数の計算

[kobakoba0723@fedora13-intel64 ~]$ cat count_dayoff.py 
from dateutil import rrule
import datetime


def workdays(start, end, holidays=0, days_off=None):
    if days_off == None:
        days_off = (5, 6)
    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__':
    testdates = [(datetime.date(2011, 7, 1), datetime.date(2011, 8, 31), 3),
                 (datetime.date(2011, 9, 1), datetime.date(2011, 11, 30), 3)
                ]

    def test(testdates, days_off=None):
        for s, e, h in testdates:
            print '\ttotal workdays from %s to %s are %s with %s holidays' % (
                s, e, workdays(s, e, h, days_off), h)

    print 'Saturday & Sunday are day off.'
    test(testdates)
    print 'Sunday is day off.'
    test(testdates, days_off=[6])
[kobakoba0723@fedora13-intel64 ~]$ python count_dayoff.py 
Saturday & Sunday are day off.
	total workdays from 2011-07-01 to 2011-08-31 are 41 with 3 holidays
	total workdays from 2011-09-01 to 2011-11-30 are 62 with 3 holidays
Sunday is day off.
	total workdays from 2011-07-01 to 2011-08-31 are 50 with 3 holidays
	total workdays from 2011-09-01 to 2011-11-30 are 75 with 3 holidays
[kobakoba0723@fedora13-intel64 ~]$ 

参考サイト

python dateutil@Labix

Python クックブック 第2版

Python クックブック 第2版