diff --git a/README.md b/README.md index 7d0fe33..419185a 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,6 @@ Parse Cron Format Strings, Write Cron Format Strings and Caluclate Execution Dat ## [Documentation](https://hexdocs.pm/crontab/) -## Known Issues -If a previous date is searched for a Complex Cron Expression, it sometimes maxes out. Contributions are welcome to fix that. - ## Usage ### Helper Functions diff --git a/lib/crontab/cron_scheduler.ex b/lib/crontab/cron_scheduler.ex index c72c5bb..814c453 100644 --- a/lib/crontab/cron_scheduler.ex +++ b/lib/crontab/cron_scheduler.ex @@ -63,9 +63,12 @@ defmodule Crontab.CronScheduler do {:error, "No compliant date was found for your interval."} end defp get_run_date(cron_interval = %Crontab.CronInterval{}, date, max_runs, direction) do - cron_interval - |> Crontab.CronInterval.to_condition_list - |> get_run_date(reset(date, :seconds), max_runs, direction) + condition_list = case direction do + :increment -> Crontab.CronInterval.to_condition_list(cron_interval) + :decrement -> Enum.reverse(Crontab.CronInterval.to_condition_list(cron_interval)) + end + + get_run_date(condition_list, reset(date, :seconds), max_runs, direction) end defp get_run_date(cron_interval = %Crontab.ExtendedCronInterval{}, date, max_runs, direction) do cron_interval diff --git a/test/crontab/functional_test.exs b/test/crontab/functional_test.exs index 97b98df..4f97fb7 100644 --- a/test/crontab/functional_test.exs +++ b/test/crontab/functional_test.exs @@ -43,39 +43,39 @@ defmodule Crontab.FunctionalTest do { "4-59/2 * * * *", "4-59/2 * * * * *", ~N[2011-06-20 12:06:00], ~N[2011-06-20 12:06:00], ~N[2011-06-20 12:06:00], true }, { "4-59/3 * * * *", "4-59/3 * * * * *", ~N[2011-06-20 12:06:00], ~N[2011-06-20 12:07:00], ~N[2011-06-20 12:04:00], false }, # Test Day of the Week and the Day of the Month (issue #1) - { "0 0 1 1 0", "0 0 1 1 0 *", ~N[2011-06-15 23:09:00], ~N[2012-01-01 00:00:00], :none, false }, # Should be found, maxes out - { "0 0 1 JAN 0", "0 0 1 1 0 *", ~N[2011-06-15 23:09:00], ~N[2012-01-01 00:00:00], :none, false }, # Should be found, maxes out - { "0 0 1 * 0", "0 0 1 * 0 *", ~N[2011-06-15 23:09:00], ~N[2012-01-01 00:00:00], :none, false }, # Should be found, maxes out - { "0 0 L * *", "0 0 L * * *", ~N[2011-07-15 00:00:00], ~N[2011-07-31 00:00:00], :none, false }, # Should be found, maxes out + { "0 0 1 1 0", "0 0 1 1 0 *", ~N[2011-06-15 23:09:00], ~N[2012-01-01 00:00:00], ~N[2006-01-01 00:00:00], false }, + { "0 0 1 JAN 0", "0 0 1 1 0 *", ~N[2011-06-15 23:09:00], ~N[2012-01-01 00:00:00], ~N[2006-01-01 00:00:00], false }, + { "0 0 1 * 0", "0 0 1 * 0 *", ~N[2011-06-15 23:09:00], ~N[2012-01-01 00:00:00], ~N[2011-05-01 00:00:00], false }, + { "0 0 L * *", "0 0 L * * *", ~N[2011-07-15 00:00:00], ~N[2011-07-31 00:00:00], ~N[2011-06-30 00:00:00], false }, # Test the W day of the week modifier for day of the month field - { "0 0 LW * *", "0 0 LW * * *", ~N[2016-12-24 00:00:00], ~N[2016-12-30 00:00:00], :none, false }, # Should be found, maxes out - { "0 0 2W * *", "0 0 2W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-01 00:00:00], ~N[2011-07-01 00:00:00], true }, - { "0 0 1W * *", "0 0 1W * * *", ~N[2011-05-01 00:00:00], ~N[2011-05-02 00:00:00], :none, false }, # Should be found, maxes out - { "0 0 1W * *", "0 0 1W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-01 00:00:00], ~N[2011-07-01 00:00:00], true }, - { "0 0 3W * *", "0 0 3W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-04 00:00:00], :none, false }, # Should be found, maxes out - { "0 0 16W * *", "0 0 16W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-15 00:00:00], :none, false }, # Should be found, maxes out - { "0 0 28W * *", "0 0 28W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-28 00:00:00], ~N[2011-06-28 00:00:00], false }, - { "0 0 30W * *", "0 0 30W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-29 00:00:00], ~N[2011-06-30 00:00:00], false }, - { "0 0 31W * *", "0 0 31W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-29 00:00:00], ~N[2011-06-30 00:00:00], false }, + { "0 0 LW * *", "0 0 LW * * *", ~N[2016-12-24 00:00:00], ~N[2016-12-30 00:00:00], ~N[2016-11-30 00:00:00], false }, + { "0 0 2W * *", "0 0 2W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-01 00:00:00], ~N[2011-07-01 00:00:00], true }, + { "0 0 1W * *", "0 0 1W * * *", ~N[2011-05-01 00:00:00], ~N[2011-05-02 00:00:00], ~N[2011-04-01 00:00:00], false }, + { "0 0 1W * *", "0 0 1W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-01 00:00:00], ~N[2011-07-01 00:00:00], true }, + { "0 0 3W * *", "0 0 3W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-04 00:00:00], ~N[2011-06-03 00:00:00], false }, + { "0 0 16W * *", "0 0 16W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-15 00:00:00], ~N[2011-06-16 00:00:00], false }, + { "0 0 28W * *", "0 0 28W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-28 00:00:00], ~N[2011-06-28 00:00:00], false }, + { "0 0 30W * *", "0 0 30W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-29 00:00:00], ~N[2011-06-30 00:00:00], false }, + { "0 0 31W * *", "0 0 31W * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-29 00:00:00], ~N[2011-06-30 00:00:00], false }, # Test the year field { "* * * * * 2012", "* * * * * 2012", ~N[2011-05-01 00:00:00], ~N[2012-01-01 00:00:00], :none, false }, # Test the last weekday of a month - { "* * * * 5L", "* * * * 5L *", ~N[2011-07-01 00:00:00], ~N[2011-07-29 00:00:00], ~N[2011-06-24 23:59:00], false }, - { "* * * * 6L", "* * * * 6L *", ~N[2011-07-01 00:00:00], ~N[2011-07-30 00:00:00], ~N[2011-06-25 23:59:00], false }, - { "* * * * 7L", "* * * * 7L *", ~N[2011-07-01 00:00:00], ~N[2011-07-31 00:00:00], ~N[2011-06-26 23:59:00], false }, - { "* * * * 1L", "* * * * 1L *", ~N[2011-07-24 00:00:00], ~N[2011-07-25 00:00:00], ~N[2011-06-27 23:59:00], false }, - { "* * * * TUEL", "* * * * 2L *", ~N[2011-07-24 00:00:00], ~N[2011-07-26 00:00:00], ~N[2011-06-28 23:59:00], false }, - { "* * * 1 5L", "* * * 1 5L *", ~N[2011-12-25 00:00:00], ~N[2012-01-27 00:00:00], ~N[2011-01-28 23:59:00], false }, + { "* * * * 5L", "* * * * 5L *", ~N[2011-07-01 00:00:00], ~N[2011-07-29 00:00:00], ~N[2011-06-24 23:59:00], false }, + { "* * * * 6L", "* * * * 6L *", ~N[2011-07-01 00:00:00], ~N[2011-07-30 00:00:00], ~N[2011-06-25 23:59:00], false }, + { "* * * * 7L", "* * * * 7L *", ~N[2011-07-01 00:00:00], ~N[2011-07-31 00:00:00], ~N[2011-06-26 23:59:00], false }, + { "* * * * 1L", "* * * * 1L *", ~N[2011-07-24 00:00:00], ~N[2011-07-25 00:00:00], ~N[2011-06-27 23:59:00], false }, + { "* * * * TUEL", "* * * * 2L *", ~N[2011-07-24 00:00:00], ~N[2011-07-26 00:00:00], ~N[2011-06-28 23:59:00], false }, + { "* * * 1 5L", "* * * 1 5L *", ~N[2011-12-25 00:00:00], ~N[2012-01-27 00:00:00], ~N[2011-01-28 23:59:00], false }, # Test the last day of a month - { "* * L", "* * L * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-31 00:00:00], ~N[2011-06-30 23:59:00], false }, + { "* * L", "* * L * * *", ~N[2011-07-01 00:00:00], ~N[2011-07-31 00:00:00], ~N[2011-06-30 23:59:00], false }, # Test the last day of a week - { "* * * * L", "* * * * 7 *", ~N[2011-07-01 00:00:00], ~N[2011-07-03 00:00:00], ~N[2011-06-26 23:59:00], false }, + { "* * * * L", "* * * * 7 *", ~N[2011-07-01 00:00:00], ~N[2011-07-03 00:00:00], ~N[2011-06-26 23:59:00], false }, # Test the last month of a year - { "* * * L", "* * * 12 * *", ~N[2011-07-01 00:00:00], ~N[2011-12-01 00:00:00], ~N[2010-12-31 23:59:00], false }, + { "* * * L", "* * * 12 * *", ~N[2011-07-01 00:00:00], ~N[2011-12-01 00:00:00], ~N[2010-12-31 23:59:00], false }, # # Test the hash symbol for the nth weekday of a given month - { "* * * * 5#2", "* * * * 5#2 *", ~N[2011-07-01 00:00:00], ~N[2011-07-08 00:00:00], ~N[2011-06-10 23:59:00], false }, - { "* * * * 5#1", "* * * * 5#1 *", ~N[2011-07-01 00:00:00], ~N[2011-07-01 00:00:00], ~N[2011-07-01 00:00:00], true }, - { "* * * * 3#4", "* * * * 3#4 *", ~N[2011-07-01 00:00:00], ~N[2011-07-27 00:00:00], ~N[2011-06-22 23:59:00], false }, + { "* * * * 5#2", "* * * * 5#2 *", ~N[2011-07-01 00:00:00], ~N[2011-07-08 00:00:00], ~N[2011-06-10 23:59:00], false }, + { "* * * * 5#1", "* * * * 5#1 *", ~N[2011-07-01 00:00:00], ~N[2011-07-01 00:00:00], ~N[2011-07-01 00:00:00], true }, + { "* * * * 3#4", "* * * * 3#4 *", ~N[2011-07-01 00:00:00], ~N[2011-07-27 00:00:00], ~N[2011-06-22 23:59:00], false }, ] for {cron_expression, written_cron_expression, start_date, next_search_date, previous_search_date, matches_now} <- tests_find_date do