Simple date recurrences
To use Recurrencex with your projects, add it as a dependency in your mix.exs file
def deps do
[
{:recurrencex, "~> 0.1.0"}
]
end
-
Repeat every n days
-
Repeat on [weekdays] every n weeks
-
Repeat on [i, j, k] days every n months
-
Repeat on the [i'th weekdays] every n months
iex> date = Timex.to_datetime({{2018, 4, 20}, {0, 0, 0}}, "America/Toronto")
...> # repeat every 7 days
...> next = Recurrencex.next(date, %Recurrencex{type: :daily, frequency: 7, repeat_on: []})
...> next == Timex.to_datetime({{2018, 4, 27}, {0, 0, 0}}, "America/Toronto")
true
iex> date = Timex.to_datetime({{2018, 4, 20}, {0, 0, 0}}, "America/Toronto")
...> # repeat on Mondays, Wednesdays, Fridays every week
...> next = Recurrencex.next(date, %Recurrencex{type: :weekly, frequency: 1, repeat_on: [1, 3, 5]})
...> # date was a Friday the 20th, the next recurrence would be Monday the 23rd
...> next == Timex.to_datetime({{2018, 4, 23}, {0, 0, 0}}, "America/Toronto")
true
iex> date = Timex.to_datetime({{2018, 4, 20}, {0, 0, 0}}, "America/Toronto")
...> # repeat on the 20th and 25th of every month
...> next = Recurrencex.next(date, %Recurrencex{type: :monthly_day, frequency: 1, repeat_on: [20, 25]})
...> next == Timex.to_datetime({{2018, 5, 20}, {0, 0, 0}}, "America/Toronto")
true
iex> date = Timex.to_datetime({{2018, 4, 20}, {0, 0, 0}}, "America/Toronto")
...> # repeat on the first thursday of every month
...> next = Recurrencex.next(date, %Recurrencex{type: :monthly_dow, frequency: 1, repeat_on: [{4,1}]})
...> next == Timex.to_datetime({{2018, 5, 3}, {0, 0, 0}}, "America/Toronto")
true
iex> r = %Recurrencex{type: :monthly_day, frequency: 12, repeat_on: [20]}
...> Timex.to_datetime({{2018, 4, 20}, {0, 0, 0}}, "America/Toronto")
...> |> Recurrencex.next(r)
...> |> Recurrencex.next(r)
...> next == Timex.to_datetime({{2020, 4, 20}, {0, 0, 0}}, "America/Toronto")
true
Documentation: https://hexdocs.pm/recurrencex.
Behaviour with different days in months (Timex handles this like so)
iex> date = Timex.to_datetime({{2018, 1, 30}, {0, 0, 0}}, "America/Toronto")
iex> Timex.shift(date, months: 1)
#DateTime<2018-03-02 00:00:00-05:00 EST America/Toronto>
iex> date = Timex.to_datetime({{2018, 5, 1}, {0, 0, 0}}, "America/Toronto")
iex> Timex.shift(date, months: 1)
#DateTime<2018-07-01 00:00:00-04:00 EDT America/Toronto>
Recurrencex will opt to align with the end of the month as defined by Timex.end_of_month in these cases instead of rolling over to the next month.
iex> date = Timex.to_datetime({{2018, 1, 31}, {0, 0, 0}}, "America/Toronto")
iex> r = %Recurrencex{type: :monthly_day, frequency: 1, repeat_on: [31]}
iex> Recurrencex.next(date, r)
#DateTime<2018-02-28 00:00:00-05:00 EST America/Toronto>
Repeat on the nth weekday will rollover to the next month if for example there is no 6th Friday in January.
iex> date = Timex.to_datetime({{2018, 1, 1}, {0, 0, 0}}, "America/Toronto")
iex> r = %Recurrencex{type: :monthly_dow, frequency: 1, repeat_on: [{5, 6}]}
iex> Recurrencex.next(date, r)
#DateTime<2018-02-09 00:00:00-05:00 EST America/Toronto>