Skip to main content

croniter provides iteration for datetime object with cron like format

Project description

Introduction

croniter provides iteration for the datetime object with a cron like format.

                      _ _
  ___ _ __ ___  _ __ (_) |_ ___ _ __
 / __| '__/ _ \| '_ \| | __/ _ \ '__|
| (__| | | (_) | | | | | ||  __/ |
 \___|_|  \___/|_| |_|_|\__\___|_|

Website: https://github.com/kiorky/croniter

Travis badge

https://travis-ci.org/kiorky/croniter.svg?branch=master

Usage

A simple example:

>>> from croniter import croniter
>>> from datetime import datetime
>>> base = datetime(2010, 1, 25, 4, 46)
>>> 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
>>>
>>> iter = croniter('2 4 * * mon,fri', base)  # 04:02 on every Monday and Friday
>>> 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
>>> iter = croniter('0 0 * * sat#1,sun#2', base)
>>> print(iter.get_next(datetime))   # datetime.datetime(2010, 2, 6, 0, 0)

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(), 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. 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.

Supported added for get_prev method. (>= 0.2.0):

>>> base = datetime(2010, 8, 25)
>>> itr = croniter('0 0 1 * *', base)
>>> print(itr.get_prev(datetime))  # 2010-08-01 00:00:00
>>> print(itr.get_prev(datetime))  # 2010-07-01 00:00:00
>>> print(itr.get_prev(datetime))  # 2010-06-01 00:00:00

You can validate your crons using is_valid class method. (>= 0.3.18):

>>> croniter.is_valid('0 0 1 * *')  # True
>>> croniter.is_valid('0 wrong_value 1 * *')  # False

About DST

Be sure to init your croniter instance with a TZ aware datetime for this to work!

Example using pytz:

>>> import pytz
>>> tz = pytz.timezone("Europe/Paris")
>>> local_date = tz.localize(datetime(2017, 3, 26))
>>> val = croniter('0 0 * * *', local_date).get_next(datetime)

Example using python_dateutil:

>>> import dateutil.tz
>>> tz = dateutil.tz.gettz('Asia/Tokyo')
>>> local_date = datetime(2017, 3, 26, tzinfo=tz)
>>> val = croniter('0 0 * * *', local_date).get_next(datetime)

About second repeats

Croniter is able to do second repeatition crontabs form:

>>> croniter('* * * * * 1', local_date).get_next(datetime)
>>> base = datetime(2012, 4, 6, 13, 26, 10)
>>> itr = croniter('* * * * * 15,25', base)
>>> itr.get_next(datetime) # 4/6 13:26:15
>>> itr.get_next(datetime) # 4/6 13:26:25
>>> itr.get_next(datetime) # 4/6 13:27:15

You can also note that this expression will repeat every second from the start datetime.:

>>> croniter('* * * * * *', local_date).get_next(datetime)

Testing if a date matchs a crontab

Test for a match with (>=0.3.32):

>>> croniter.match("0 0 * * *", datetime(2019, 1, 14, 0, 0, 0, 0))
True
>>> croniter.match("0 0 * * *", datetime(2019, 1, 14, 0, 2, 0, 0))
False
>>>
>>> croniter.match("2 4 1 * wed", datetime(2019, 1, 1, 4, 2, 0, 0)) # 04:02 on every Wednesday OR on 1st day of month
True
>>> croniter.match("2 4 1 * wed", datetime(2019, 1, 1, 4, 2, 0, 0), day_or=False) # 04:02 on every 1st day of the month if it is a Wednesday
False

Iterating over a range using cron

Finding all matching times in at time range can be handled with the croniter_range() function. This is much like the builtin range(start,stop,step) function, but for dates using a cron expression as “step”. Added in (>=0.3.34)

List the first Saturday of every month in 2019:

>>> from croniter import croniter_range
>>> for dt in croniter_range(datetime(2019, 1, 1), datetime(2019, 12, 31), "0 0 * * sat#1"):
>>>     print(dt)

Develop this package

git clone https://github.com/kiorky/croniter.git
cd croniter
virtualenv --no-site-packages venv
. venv/bin/activate
pip install --upgrade -r requirements/test.txt
py.test src

Make a new release

We use zest.fullreleaser, a great release infrastructure.

Do and follow these instructions

. venv/bin/activate
pip install --upgrade -r requirements/release.txt
./release.sh

Contributors

Thanks to all who have contributed to this project! If you have contributed and your name is not listed below please let me know.

  • mrmachine

  • Hinnack

  • shazow

  • kiorky

  • jlsandell

  • mag009

  • djmitche

  • GreatCombinator

  • chris-baynes

  • ipartola

  • yuzawa-san

Changelog

0.3.34 (2020-06-19)

  • Feat croniter_range(start, stop, cron) [Kintyr]

  • Optimization for poorly written cron expression [Kintyr]

0.3.33 (2020-06-15)

  • Make dateutil tz support more official [lowell80]

  • Feat/support for day or [田口信元]

0.3.32 (2020-05-27)

  • document seconds repeats, fixes #122 [kiorky]

  • Implement match method, fixes #54 [kiorky]

  • Adding tests for #127 (test more DSTs and croniter behavior around) [kiorky]

  • Changed lag_hours comparison to absolute to manage dst boundary when getting previous [Sokkka]

0.3.31 (2020-01-02)

  • Fix get_next() when start_time less then 1s before next instant [AlexHill]

0.3.30 (2019-04-20)

  • credits

0.3.29 (2019-03-26)

  • credits

  • history stripping (security)

  • Handle -Sun notation, This fixes #119. [kiorky]

  • Handle invalid ranges correctly, This fixes #114. [kiorky]

0.3.25 (2018-08-07)

  • Pypi hygiene [hugovk]

0.3.24 (2018-06-20)

  • fix #107: microsecond threshold [kiorky]

0.3.23 (2018-05-23)

0.3.22 (2018-05-16)

  • Don’t count previous minute if now is dynamic If the code is triggered from 5-asterisk based cron get_prev based on datetime.now() is expected to return current cron iteration and not previous execution. [Igor Khrol <igor.khrol@toptal.com>]

0.3.20 (2017-11-06)

0.3.19 (2017-08-31)

  • fix #87: backward dst changes [kiorky]

0.3.18 (2017-08-31)

0.3.17 (2017-05-22)

0.3.16 (2017-03-15)

0.3.15 (2017-02-16)

  • fix bug around multiple conditions and range_val in _get_prev_nearest_diff. [abeja-yuki@github]

0.3.14 (2017-01-25)

  • issue #69: added day_or option to change behavior when day-of-month and day-of-week is given [Andreas Vogl <a.vogl@hackner-security.com>]

0.3.13 (2016-11-01)

0.3.12 (2016-03-10)

0.3.11 (2016-01-13)

  • Bug fix: The get_prev API crashed when last day of month token was used. Some essential logic was missing. [Iddo Aviram <iddo.aviram@similarweb.com>]

0.3.10 (2015-11-29)

  • The fuctionality of ‘l’ as day of month was broken, since the month variable was not properly updated [Iddo Aviram <iddo.aviram@similarweb.com>]

0.3.9 (2015-11-19)

  • Don’t use datetime functions python 2.6 doesn’t support [petervtzand]

0.3.8 (2015-06-23)

  • Truncate microseconds by setting to 0 [Corey Wright]

0.3.7 (2015-06-01)

  • converting sun in range sun-thu transforms to int 0 which is recognized as empty string; the solution was to convert sun to string “0”

0.3.6 (2015-05-29)

  • Fix default behavior when no start_time given Default value for start_time parameter is calculated at module init time rather than call time.

  • Fix timezone support and stop depending on the system time zone

0.3.5 (2014-08-01)

  • support for ‘l’ (last day of month)

0.3.4 (2014-01-30)

  • Python 3 compat

  • QA Relase

0.3.3 (2012-09-29)

  • proper packaging

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

croniter-0.3.34.tar.gz (25.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

croniter-0.3.34-py2.py3-none-any.whl (19.5 kB view details)

Uploaded Python 2Python 3

File details

Details for the file croniter-0.3.34.tar.gz.

File metadata

  • Download URL: croniter-0.3.34.tar.gz
  • Upload date:
  • Size: 25.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/44.0.0 requests-toolbelt/0.9.1 tqdm/4.46.1 CPython/3.8.2

File hashes

Hashes for croniter-0.3.34.tar.gz
Algorithm Hash digest
SHA256 7186b9b464f45cf3d3c83a18bc2344cc101d7b9fd35a05f2878437b14967e964
MD5 adfeeb0032ab7aeccba908fa2eb09c33
BLAKE2b-256 67599e30c03c61ea20724bbc2a5e5ec606e3d29f96435ad93a2400ebbeb29f7d

See more details on using hashes here.

File details

Details for the file croniter-0.3.34-py2.py3-none-any.whl.

File metadata

  • Download URL: croniter-0.3.34-py2.py3-none-any.whl
  • Upload date:
  • Size: 19.5 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/44.0.0 requests-toolbelt/0.9.1 tqdm/4.46.1 CPython/3.8.2

File hashes

Hashes for croniter-0.3.34-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 15597ef0639f8fbab09cbf8c277fa8c65c8b9dbe818c4b2212f95dbc09c6f287
MD5 c43bc40cd74bff1ca5227d2d4f24bbd2
BLAKE2b-256 9b839b70ce509a225da6b4b1e7779f31c12ee58e26df814d6a03227b1378bf04

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page