Hello folks,
I release a couple of months ago ex_cycle
for managing recurrent date(times) in elixir. I know there is cocktail but we decided to create our own lib since Cocktail doesn’t handle well timezoned datetimes. I tried to fix it on Cocktail but the problem seems to be harder that just updating a function.
So here we are : ex_cycle | Hex
Disclaimer : cocktail have some features that we don’t (like working with RRule as string).
But after a couple of months using it we could stay the lib is almost prod ready (we miss some important feature to be prod ready IMO, like display a cycle as string like “Every day at 10AM”).
Here an basic example
iex> ExCycle.new()
...> |> ExCycle.add_rule(:monthly,
...> days_of_month: [-1, 1, 10, 28],
...> hours: [10, 20],
...> timezone: "America/Montreal"
...> )
...> |> ExCycle.occurrences(~N[2025-02-01 00:00:00])
...> |> Enum.take(14)
[#DateTime<2025-02-01 10:00:00-05:00 EST America/Montreal>,
#DateTime<2025-02-01 20:00:00-05:00 EST America/Montreal>,
#DateTime<2025-02-10 10:00:00-05:00 EST America/Montreal>,
#DateTime<2025-02-10 20:00:00-05:00 EST America/Montreal>,
#DateTime<2025-02-28 10:00:00-05:00 EST America/Montreal>,
#DateTime<2025-02-28 20:00:00-05:00 EST America/Montreal>,
#DateTime<2025-03-01 10:00:00-05:00 EST America/Montreal>,
#DateTime<2025-03-01 20:00:00-05:00 EST America/Montreal>,
#DateTime<2025-03-10 10:00:00-04:00 EDT America/Montreal>,
#DateTime<2025-03-10 20:00:00-04:00 EDT America/Montreal>,
#DateTime<2025-03-28 10:00:00-04:00 EDT America/Montreal>,
#DateTime<2025-03-28 20:00:00-04:00 EDT America/Montreal>,
#DateTime<2025-03-31 10:00:00-04:00 EDT America/Montreal>,
#DateTime<2025-03-31 20:00:00-04:00 EDT America/Montreal>]
Oh and yeah in case you wonder, we support daylight saving as you can see on the example
We try to be as much possible close to cocktail to allow people switching easily to ex_cycle.
Have a good day folks