12.4. The dateutil Module
The third-party package dateutil (http://labix.org/python-dateutil) offers modules to manipulate dates in various ways, including time deltas, recurrence, time zones, and fuzzy parsing. (See the module's web site for complete documentation of its rich functionality.) dateutil's main modules are the following.
Returns the datetime.date object for Easter of the given year. For example:
from dateutil import easter print easter.easter(2006)
Returns the datetime.datetime object denoted by string s, with very permissive (a.k.a. "fuzzy") parsing rules. For example:
from dateutil import parser print parser.parse("Saturday, January 28, 2006, at 11:15pm")
emits 2006-01-28 23:15:00.
You can call relativedelta with two instances of datetime.datetime: the resulting relativedelta instance captures the relative difference between the two arguments. Alternatively, you can call relativedelta with a keyword argument representing absolute information (year, month, day, hour, minute, second, microsecond); relative information (years, months, weeks, days, hours, minutes, seconds, microseconds), which may have positive or negative values; or the special keyword weekday, which can be a number from 0 (Monday) to 6 (Sunday), or one of the module attributes MO, TU,..., SU, which can also be called with a numeric argument n to specify the nth weekday. In any case, the resulting relativedelta instance captures the information in the call. For example, after:
from dateutil import relativedelta r = relativedelta.relativedelta(weekday=relativedelta.MO(1))
r means "next Monday." You can add a relativedelta instance to a datetime.datetime instance to get a new datetime.datetime instance at the stated relative delta from the other:
# emits: 2006-01-30
# emits: 2006-01-30
# emits: 2006-02-06
Note that "next Monday," by relativedelta's interpretation, is the very same date, if that day is already a Monday (so, a more detailed name might be "the first date, on or following the given date, which falls on a Monday"). dateutil's site has very detailed explanations of the rules defining the behavior of relativedelta instances.
Module rrule implements RFC2445 (also known as the iCalendar RFC), available in all the glory of its 140+ pages at ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt. freq must be one of the constant attributes of module rrule: YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, or SECONDLY. After mandatory argument freq may optionally come some of many possible named arguments, such as interval=2, to specify that the recurrence is only on alternate occurrences of the specified frequency (for example, rrule.rrule(rrule.YEARLY) repeats every year, while rrule.rrule(rrule.YEARLY, interval=7) repeats only every seven years).
An instance r of type rrule.rrule supplies several methods.
Returns the earliest datetime.datetime instance that's an occurrence of recurrence rule r and happens after date d (when inc is true, an occurrence happening on date d itself is also acceptable).
Returns the latest datetime.datetime instance that's an occurrence of recurrence rule r and happens before date d (when inc is true, an occurrence happening on date d itself is also acceptable).
r.between(start, finish, inc=False)
Returns all datetime.datetime instances that are occurrences of recurrence rule r and happen between dates start and finish (when inc is true, occurrences happening on dates start and finish themselves are also acceptable).
Returns the number of occurrences of recurrence rule r.
For example, to express "once a week throughout January 2006," you could code:
for d in r.between(start, datetime.datetime(2006,2,1), True):
print d.date( ),
to emit 2006-01-01 2006-01-08 2006-01-15 2006-01-22 2006-01-29.