Date ranges in Elixir?

Yes,

Using the Date module

range = Date.range(~D[2001-01-01], ~D[2002-01-01])

Enum.each(range, fn(x) -> IO.puts x end)

output

2001-01-01
2001-01-02
2001-01-03
2001-01-04
2001-01-05
2001-01-06
2001-01-07
2001-01-08
2001-01-09
2001-01-10

to the last day i.e 2002-01-01


@bitwalker's suggestion is excellent. If you want to do this in "native" Elixir code:

def generate_all_valid_dates_in_range(start_date, end_date) when start_date <= end_date do
  (:calendar.date_to_gregorian_days(start_date) .. :calendar.date_to_gregorian_days(end_date))
  |> Enum.to_list
  |> Enum.map (&(:calendar.gregorian_days_to_date(&1)))
end

More about this solution and how I devised it with a lot of help from the Elixir community at my blog. But Timex is a better solution in my estimation.


Using Calendar you can get a stream of dates after a certain date. Example:

alias Calendar.Date

d1 = Date.from_erl! {2015, 1, 1}
d2 = Date.from_erl! {2015, 1, 1}
Date.days_after_until(d1, d2)

If you also want to include the first date you have to pass true as the third argument. This will get you a list:

Date.days_after_until(d1, d2, true) |> Enum.to_list

[%Calendar.Date{day: 1, month: 1, year: 2015},
 %Calendar.Date{day: 2, month: 1, year: 2015},
 %Calendar.Date{day: 3, month: 1, year: 2015},
 %Calendar.Date{day: 4, month: 1, year: 2015},
 %Calendar.Date{day: 5, month: 1, year: 2015},
 %Calendar.Date{day: 6, month: 1, year: 2015},
 %Calendar.Date{day: 7, month: 1, year: 2015}

Tags:

Elixir