✨ Elixir 1.17's new Date.shift/2 🕐
Notes
Elixir 1.17 introduced a new shift/2
function to work with dates and date times
that I think is pretty cool.
Up until now, when we want to change a date, we’d likely use Date.add/2
–
that would add days to the given date:
today = Date.utc_today()
Date.add(today, 1)
# => tomorrow
But what if we want to add weeks, months, or years?
Date.shift/2
has our back:
today = Date.utc_today()
Date.shift(today, day: 1)
# => tomorrow
Date.shift(today, week: 1)
# => next week
Date.shift(today, month: 1)
# => next month
Date.shift(today, year: 1)
# => next year
But here’s the important thing to remember:
It’s not an arithmetic operation
Why does that matter? Take this example:
end_of_jan = Date.new!(2024, 01, 31)
end_of_feb = Date.shift(end_of_jan, month: 1)
# => ~D[2024-02-29]
We shift the end of January by a month and we get the end of February. That’s awesome! It knows about calendars! It didn’t just add 30 days in some arithmetic operation.
But by the same token… what should it do when it shifts back a month?
end_of_feb = ~D[2024-02-29]
not_end_of_jan = Date.shift(end_of_feb, month: -1)
# => ~D[2024-01-29]
Well… that’s slightly more surprising, right? It didn’t shift back to the 31st. It shifted by to the 29th.
In other words, because we’re not doing arithmetic, the order of operations matters: shifting a month ahead and a month back won’t necessarily give you the starting date.
I think this is be a cool helper, but you have to keep that in mind.