Metadata-Version: 1.2
Name: croniter
Version: 0.3.35
Summary: croniter provides iteration for datetime object with cron like format
Home-page: http://github.com/kiorky/croniter
Author: Matsumoto Taichi, kiorky
Author-email: taichino@gmail.com, kiorky@cryptelium.net
License: MIT License
Description: Introduction
        ============
        
        .. contents::
        
        
        croniter provides iteration for the datetime object with a cron like format.
        
        ::
        
                                  _ _
              ___ _ __ ___  _ __ (_) |_ ___ _ __
             / __| '__/ _ \| '_ \| | __/ _ \ '__|
            | (__| | | (_) | | | | | ||  __/ |
             \___|_|  \___/|_| |_|_|\__\___|_|
        
        
        Website: https://github.com/kiorky/croniter
        
        Travis badge
        =============
        .. image:: https://travis-ci.org/kiorky/croniter.svg?branch=master
            :target: https://travis-ci.org/kiorky/croniter
        
        
        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
        
        Gaps between date matches
        =========================
        For performance reasons, croniter limits the amount of CPU cycles spent attempting to find the next match.
        By default croniter stops looking for dates more than 50 years away from the current time, and if the next cannot be reached within that span then ``CroniterBadDateError`` is raised.
        This works fine for most "normal" cron expressions, but can be limiting for very rare cron expressions.
        
        For example, say you're looking to match 4AM Friday January 1st.
        Since January 1 isn't often a Friday, it can be a few years between each occurrence.
        Starting in v0.3.35, croniter provides a ``max_years_between_matches`` parameter that allows more than 50 years default to be extended for scenarios like this::
        
            >>> it = croniter("0 4 1 1 fri", datetime(2000,1,1), day_or=False, max_years_between_matches=100).all_next(datetime)
            >>> for i in range(5):
            ...     print(next(it))
            ...
            2010-01-01 04:00:00
            2016-01-01 04:00:00
            2021-01-01 04:00:00
            2027-01-01 04:00:00
            2038-01-01 04:00:00
        
        Trying this without ``max_years_between_matches`` results in an exception, because there's a full decade between the 2000 start date and the first match in 2010::
        
            >>> it = croniter("0 4 1 1 fri", datetime(2000,1,1), day_or=False).all_next()
            >>> next(it)
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
              ...
            croniter.CroniterBadDateError: failed to find next date
        
        One advantage of explicitly specifying ``max_years_between_matches`` is that it simplifies the various iterable interfaces.
        Specifically ``all_next()``, ``all_prev()`` and ``iter()``) stop raising the ``CroniterBadDateError`` exception when a window is specified.
        The rationale is that since you've explicitly told croniter how far to look into the future (or past) to find the next/previous date, there's no need for a special exception.
        Instead, if no match is found then iteration is stopped.
        This makes the these iterable interfaces act as more like normal Python iterators without having to deal with any extra exceptions.
        This distinction allows v0.3.35 and later to keep the same default behavior as earlier versions.
        
        In summary:  For many cron expressions this will never matter.  Use ``max_years_between_matches`` to make iteration simplier.
        
        Iterating over a range using cron
        =================================
        Find matches within a range using the ``croniter_range()`` function.  This is much like the builtin ``range(start,stop,step)`` function, but for dates.  The `step` argument is a cron expression.
        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
            - lowell80
        
        
        Changelog
        ==============
        
        0.3.35 (2020-10-11)
        -------------------
        
        - Handle L in ranges. This fixes #142.
          [kiorky]
        - Add a new initializaton paramter ``max_years_between_matches`` to support finding the next/previous date beyond the default 1 year window, if so desired.  Updated README to include additional notes and example of this usage.  Fixes #145.
          [Kintyre]
        - The ``croniter_range()`` function was updated to automatically determines the appropriate ``max_years_between_matches`` value, this preventing handling of the ``CroniterBadDateError`` exception.
          [Kintyre]
        - Updated exception handling classes:  ``CroniterBadDateError`` now only
          applies during date finding operations (next/prev), and all parsing errors can now be caught using ``CroniterBadCronError``.  The ``CroniterNotAlphaError`` exception is now a subclass of ``CroniterBadCronError``.  A breif description of each exception class was added as an inline docstring.
          [Kintyre]
        - Updated iterable interfaces to replace the ``CroniterBadDateError`` with ``StopIteration`` if (and only if) the ``max_years_between_matches`` argument is provided.  The rationale here is that if the user has specified the max tollernace between matches, then there's no need to further inform them of no additional matches.  Just stop the iteration.  This also keeps backwards compatibility.
          [Kintyre]
        - Minor docs update
          [Kintyre]
        
        
        0.3.34 (2020-06-19)
        -------------------
        
        - Feat croniter_range(start, stop, cron)
          [Kintyre]
        - Optimization for poorly written cron expression
          [Kintyre]
        
        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 <https://github.com/taichino/croniter/issues/119>`_.
          [kiorky]
        - Handle invalid ranges correctly,  This fixes `#114 <https://github.com/taichino/croniter/issues/114>`_.
          [kiorky]
        
        0.3.25 (2018-08-07)
        -------------------
        - Pypi hygiene
          [hugovk]
        
        
        0.3.24 (2018-06-20)
        -------------------
        - fix `#107 <https://github.com/taichino/croniter/issues/107>`_: microsecond threshold
          [kiorky]
        
        
        0.3.23 (2018-05-23)
        -------------------
        
        - fix ``get_next`` while perserving the fix of ``get_prev`` in 7661c2aaa
          [Avikam Agur <avikam@pagaya-inv.com>]
        
        
        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)
        -------------------
        
        - More DST fixes
          [Kevin Rose <kbrose@github>]
        
        
        0.3.19 (2017-08-31)
        -------------------
        
        - fix #87: backward dst changes
          [kiorky]
        
        
        0.3.18 (2017-08-31)
        -------------------
        
        - Add is valid method, refactor errors
          [otherpirate, Mauro Murari <mauro_murari@hotmail.com>]
        
        
        0.3.17 (2017-05-22)
        -------------------
        - DOW occurence sharp style support.
          [kiorky, Kengo Seki <sekikn@apache.org>]
        
        
        0.3.16 (2017-03-15)
        -------------------
        
        - Better test suite [mrcrilly@github]
        - DST support [kiorky]
        
        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)
        -------------------
        
        - `Real fix for #34 <https://github.com/taichino/croniter/pull/73>`_
          [kiorky@github]
        - `Modernize test infra <https://github.com/taichino/croniter/pull/72>`_
          [kiorky@github]
        - `Release as a universal wheel <https://github.com/kiorky/croniter/pull/16>`_
          [adamchainz@github]
        - `Raise ValueError on negative numbers <https://github.com/taichino/croniter/pull/63>`_
          [josegonzalez@github]
        - `Compare types using "issubclass" instead of exact match <https://github.com/taichino/croniter/pull/70>`_
          [darkk@github]
        - `Implement step cron with a variable base <https://github.com/taichino/croniter/pull/60>`_
          [josegonzalez@github]
        
        0.3.12 (2016-03-10)
        -------------------
        - support setting ret_type in __init__ [Brent Tubbs <brent.tubbs@gmail.com>]
        
        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
        
        
Keywords: datetime,iterator,cron
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
