Merge pull request #17 from vogan/master

issue #69: added day_or option
This commit is contained in:
kiorky 2017-01-25 11:11:28 +01:00 committed by GitHub
commit 06c130d9ee
3 changed files with 47 additions and 11 deletions

View File

@ -30,7 +30,7 @@ A simple example::
>>> from croniter import croniter
>>> from datetime import datetime
>>> base = datetime(2010, 1, 25, 4, 46)
>>> iter = croniter('*/5 * * * *', base) # every 5 minites
>>> iter = croniter('*/5 * * * *', base) # every 5 minutes
>>> print iter.get_next(datetime) # 2010-01-25 04:50:00
>>> print iter.get_next(datetime) # 2010-01-25 04:55:00
>>> print iter.get_next(datetime) # 2010-01-25 05:00:00
@ -39,23 +39,40 @@ A simple example::
>>> print iter.get_next(datetime) # 2010-01-26 04:02:00
>>> print iter.get_next(datetime) # 2010-01-30 04:02:00
>>> print iter.get_next(datetime) # 2010-02-02 04:02:00
>>>
>>> iter = croniter('2 4 1 * wed', base) # 04:02 on every Wednesday OR on 1st day of month
>>> print iter.get_next(datetime) # 2010-01-27 04:02:00
>>> print iter.get_next(datetime) # 2010-02-01 04:02:00
>>> print iter.get_next(datetime) # 2010-02-03 04:02:00
>>>
>>> iter = croniter('2 4 1 * wed', base, day_or=False) # 04:02 on every 1st day of the month if it is a Wednesday
>>> print iter.get_next(datetime) # 2010-09-01 04:02:00
>>> print iter.get_next(datetime) # 2010-12-01 04:02:00
>>> print iter.get_next(datetime) # 2011-06-01 04:02:00
All you need to know is how to use the constructor and the get_next
All you need to know is how to use the constructor and the ``get_next``
method, the signature of these methods are listed below::
>>> def __init__(self, cron_format, start_time=time.time())
>>> def __init__(self, cron_format, start_time=time.time(), day_or=True)
croniter iterates along with 'cron_format' from 'start_time'.
cron_format is 'min hour day month day_of_week', you can refer to
http://en.wikipedia.org/wiki/Cron for more details.::
croniter iterates along with ``cron_format`` from ``start_time``.
``cron_format`` is **min hour day month day_of_week**, you can refer to
http://en.wikipedia.org/wiki/Cron for more details. The ``day_or``
switch is used to control how croniter handles **day** and **day_of_week**
entries. Default option is the cron behaviour, which connects those
values using **OR**. If the switch is set to False, the values are connected
using **AND**. This behaves like fcron and enables you to e.g. define a job that
executes each 2nd friday of a month by setting the days of month and the
weekday.
::
>>> def get_next(self, ret_type=float)
get_next calculates the next value according to the cron expression and
returns an object of type 'ret_type'. ret_type should be a 'float' or a
'datetime' object.
returns an object of type ``ret_type``. ``ret_type`` should be a ``float`` or a
``datetime`` object.
Supported added for get_prev method. (>= 0.2.0)::
Supported added for ``get_prev`` method. (>= 0.2.0)::
>>> base = datetime(2010, 8, 25)
>>> itr = croniter('0 0 1 * *', base)

View File

@ -63,8 +63,10 @@ class croniter(object):
bad_length = 'Exactly 5 or 6 columns has to be specified for iterator' \
'expression.'
def __init__(self, expr_format, start_time=None, ret_type=float):
def __init__(self, expr_format, start_time=None, ret_type=float, day_or=True):
self._ret_type = ret_type
self._day_or = day_or
if start_time is None:
start_time = time()
@ -240,7 +242,8 @@ class croniter(object):
raise TypeError("Invalid ret_type, only 'float' or 'datetime' "
"is acceptable.")
if expanded[2][0] != '*' and expanded[4][0] != '*':
# exception to support day of month and day of week as defined in cron
if (expanded[2][0] != '*' and expanded[4][0] != '*') and self._day_or:
bak = expanded[4]
expanded[4] = ['*']
t1 = self._calc(self.cur, expanded, is_prev)

View File

@ -145,6 +145,22 @@ class CroniterTest(base.TestCase):
self.assertEqual(n3.day, 3)
self.assertEqual(n3.year, 2010)
def testWeekDayDayAnd(self):
base = datetime(2010, 1, 25)
itr = croniter('0 0 1 * mon', base, day_or=False)
n1 = itr.get_next(datetime)
self.assertEqual(n1.month, 2)
self.assertEqual(n1.day, 1)
self.assertEqual(n1.year, 2010)
n2 = itr.get_next(datetime)
self.assertEqual(n2.month, 3)
self.assertEqual(n2.day, 1)
self.assertEqual(n2.year, 2010)
n3 = itr.get_next(datetime)
self.assertEqual(n3.month, 11)
self.assertEqual(n3.day, 1)
self.assertEqual(n3.year, 2010)
def testMonth(self):
base = datetime(2010, 1, 25)
itr = croniter('0 0 1 * *', base)