New to Elixir? Beware of Date and DateTime Comparisons!
People new to Elixir, especially those coming from Ruby, might be surprised at how Elixir dates and datetimes are compared. It’s easy to introduce a subtle yet dangerous bug.
You might want to use comparison operators like >
, <
, ==
to compare dates:
%Date{} > %Date{}
But using those comparison operators performs a structural comparison – comparing each of the elements of the struct: day first, then month, then year.
# Semantically false, but day 1 < 2
iex(1)> %Date{year: 2021, month: 12, day: 1} < %Date{year: 2021, month: 1, day: 2}
true
# Semantically false, but month 1 < 12
iex(2)> %Date{year: 2022, month: 1, day: 2} < %Date{year: 2021, month: 12, day: 2}
true
To compare dates correctly, we need to use Date.compare/2
or
DateTime.compare/2
.
Thankfully, Elixir has excellent documentation about it (as usual). See the
structural comparison notes in the Kernel
module.