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 ![]()




















