adamu
Calculating the beginning of next month
I’m having a discussion with a colleague about how to calculate the beginning of the next month given a certain Date using the core library. We have come up with two solutions, but cannot agree on which one is better. Are there any technical reasons to prefer one over the other here? Or better options (without using external libraries)?
Version that relies on using the calendar to calculate the number of days to the next month:
def beginning_of_next_month(%Date{} = date) do
days_in_month = Date.days_in_month(date)
date
|> Date.beginning_of_month()
|> Date.add(days_in_month)
end
Version that increments the month and relies on pattern matching to handle rolling over the year:
def beginning_of_next_month(%Date{year: year, month: 12}),
do: Date.new!(year + 1, 1, 1)
def beginning_of_next_month(%Date{year: year, month: month}),
do: Date.new!(year, month + 1, 1)
- Date.days_in_month/1 + Date.add/2
- Pattern match + Date.new/3
0 voters
Marked As Solved
trisolaran
Personally, I’d go for:
date
|> Date.end_of_month()
|> Date.add(1)
Also Liked
eksperimental
Even simpler:
~D[2000-01-01] |> Date.end_of_month() |> Date.add(1)
c4710n
I prefer version 1 - it uses the public API of Date. It is stable. If it is depracated, compiler will warn you about that.
version 2 relies on the structure of Date struct. Generally, I think it is the moving part, and will change potentially in the future. (although the probability is very low)
eksperimental
Funny fact, we wrote the same solution.
adamu
Perfect. I completely missed Date.end_of_month 
qhwa
I like the increment version but I think it’s incorrect because the day should be always 1.
I’ll probably write:
def beginning_of_next_month(%Date{year: year, month: 12}),
do: %{date | year: year + 1, month: 1, day: 1}
def beginning_of_next_month(%Date{month: month}),
do: %{date | month: month + 1, day: 1}
Simple math seems clearer than public API combos to me.
Anyway, it feels good to have Date.beginning_of_next_month/1 out of the box.








