croniter

raw JSON →
6.2.2 verified Tue May 12 auth: no python install: verified quickstart: verified

croniter is a Python library that provides iteration capabilities for `datetime` objects based on cron-like formats. It allows generating future or past occurrences matching a given cron expression. The current version is 6.2.2, released on March 15, 2026. While it experienced a period of abandonment, it is now actively maintained by the Pallets-Eco organization.

pip install croniter
error ModuleNotFoundError: No module named 'croniter'
cause The 'croniter' library is not installed in the Python environment where the code is being executed.
fix
Install the croniter package using pip: pip install croniter
error croniter.croniter.CroniterBadCronError: Exactly 5 or 6 columns has to be specified for iterator expression.
cause The provided cron expression string is malformed and does not contain the required 5 fields (minute, hour, day of month, month, day of week) or 6 fields (including seconds).
fix
Ensure your cron expression has either 5 or 6 space-separated fields. For example, '0 0 * * *' for daily at midnight, or '0 0 0 * * *' for daily at midnight with seconds.
error ValueError
cause This generic error can be raised by `croniter` for various reasons, such as providing an invalid character in a cron field, specifying a number outside the valid range for a field (e.g., month 13), or using an invalid cron step (e.g., '0-10/error').
fix
Carefully review the cron expression for any invalid characters, out-of-range numbers, or incorrect syntax. Use croniter.is_valid(cron_expression) for pre-validation or consult cron syntax documentation.
error croniter.croniter.CroniterBadDateError: failed to find next date
cause The `croniter` library could not find a matching next (or previous) date for the given cron expression within its default search window (typically 50 years). This often happens with very sparse or impossible cron expressions, like '0 0 29 2 *' when the `base` date is in a non-leap year and the next valid date is too far in the future.
fix
For very sparse cron expressions, consider increasing the max_years_between_matches parameter in the croniter constructor (e.g., croniter(cron_expression, base, max_years_between_matches=200)). Alternatively, ensure the cron expression is feasible given the base datetime.
error TypeError: Invalid ret_type, only 'float' or 'datetime'
cause When calling methods like `get_next()` or `get_prev()`, an invalid type was passed to the `ret_type` argument. `croniter` expects either `float` or `datetime.datetime`.
fix
Ensure that the ret_type argument, if provided, is either float or datetime.datetime. For example: iter.get_next(datetime.datetime) or iter.get_next(float).
breaking The `croniter` project was previously declared unmaintained and abandoned by its original author in late 2024 due to concerns about the EU Cyber Resilience Act. It has since been adopted and is now maintained by Pallets-Eco. Users should ensure they are using the `pallets-eco` version and monitor its status if the CRA impacts open source libraries.
fix Ensure installation from the official PyPI `croniter` package, which is now maintained by Pallets-Eco, and update to the latest version (6.x.x) if using an older, unmaintained fork.
gotcha By default, `croniter` uses 'OR' logic when both 'day of month' and 'day of week' fields are specified in a cron expression, matching standard Vixie-cron behavior. This means a schedule will trigger if *either* the day of month *or* the day of week matches. For 'AND' logic (trigger only if *both* match, like fcron), you must explicitly pass `day_or=False` to the `croniter` constructor.
fix If 'AND' logic is desired for day and day-of-week fields, initialize `croniter` with `croniter(cron_expression, base, day_or=False)`.
gotcha `croniter` is less strict than some cron implementations regarding ranges for months (e.g., 'APR-JAN') and days of the week (e.g., 'SAT-SUN', 'WED-SUN'). These reverse ranges are interpreted, which might lead to unexpected iterations if a strict cron parser is anticipated.
fix Carefully review cron expressions, especially those with reverse ranges. Validate the generated iterations against expected behavior, or use a more strictly validated cron string if precise adherence to a specific cron flavor is critical.
gotcha The `is_valid()` method, by default, only performs basic syntax and field range validation. It does not perform cross-field validation (e.g., it will report '31 2 * * *' as valid even though February has no 31st). To enable strict cross-field validation, you must pass `strict=True`.
fix Always use `croniter.is_valid(cron_expression, strict=True)` for comprehensive validation, especially with user-provided cron strings, to prevent parsing impossible dates.
gotcha The `croniter.match()` method has a default precision of 60 seconds for 5-field expressions and 1 second for 6-field expressions. This means a target `datetime` up to 60 (or 1) seconds *after* the scheduled time will still be considered a match. This can cause issues in scenarios requiring exact time matching.
fix When using `croniter.match()`, be aware of its default precision. For highly precise matching, consider comparing `datetime` objects directly or adjusting the comparison logic.
python os / libc status wheel install import disk
3.10 alpine (musl) - - 0.06s 19.0M
3.10 slim (glibc) - - 0.04s 20M
3.11 alpine (musl) - - 0.10s 21.2M
3.11 slim (glibc) - - 0.08s 22M
3.12 alpine (musl) - - 0.07s 13.0M
3.12 slim (glibc) - - 0.07s 13M
3.13 alpine (musl) - - 0.07s 12.6M
3.13 slim (glibc) - - 0.07s 13M
3.9 alpine (musl) - - 0.05s 18.5M
3.9 slim (glibc) - - 0.05s 19M

Demonstrates creating a croniter object and retrieving the next matching datetime. It also shows the `day_or` parameter for 'AND' logic between day-of-month and day-of-week fields.

from datetime import datetime
from croniter import croniter

# Example 1: Every 5 minutes
base = datetime(2010, 1, 25, 4, 46)
iter_5min = croniter('*/5 * * * *', base)
print(f"Next occurrence (every 5 min): {iter_5min.get_next(datetime)}")

# Example 2: Every Monday and Friday at 04:02
base = datetime.now()
iter_mf = croniter('2 4 * * mon,fri', base)
print(f"Next occurrence (Mon/Fri 04:02): {iter_mf.get_next(datetime)}")

# Example 3: First day of the month AND a Wednesday
# (using day_or=False for AND logic, like fcron)
base = datetime.now()
iter_and = croniter('2 4 1 * wed', base, day_or=False)
print(f"Next occurrence (1st day AND Wed 04:02): {iter_and.get_next(datetime)}")