ExCycle - Manage recurrent date(times) with timezone and daylight saving

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 :wink:

We try to be as much possible close to cocktail to allow people switching easily to ex_cycle.

Have a good day folks :wink:

3 Likes